Presentation is loading. Please wait.

Presentation is loading. Please wait.

3.3 Abstract Classes, Assignment, and Casting in a Hierarchy

Similar presentations


Presentation on theme: "3.3 Abstract Classes, Assignment, and Casting in a Hierarchy"— Presentation transcript:

1 3.3 Abstract Classes, Assignment, and Casting in a Hierarchy
3.4 Multiple Inheritance 09 – Inheritance

2 Attendance Quiz #9 Inheritance

3 Retrieves full path of command line arguments
Tip #9: Directory Path Inheritance #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; int main(int argc, char* argv[]) { char full[_MAX_PATH]; _fullpath(full, ".\\", _MAX_PATH); cout << "Place input/output files in the following directory:"; cout<< endl << full << endl; } ifstream in(argv[1]); // try to open argv[1] if (in) cout << "Successfully found \"" << argv[1] << " \""; in.close(); else cout << "Unable to find file \"" << argv[1] << " \""; return 0; Retrieves full path of command line arguments Place input/output files here: C:\Users\proper\Dropbox\BYU\CS 235\Visual Studio Examples\PrintFullPath\ Successfully found "fullPath.cpp "

4 Lab 02 - SNAP

5 S.N.A.P Lab Lab 02 - SNAP Class design is type design - defining effective classes can be challenging. For the SNAP lab you are to design classes for a school database with has-a and is-a relationships that have natural syntax, intuitive semantics, and efficient memory allocation. The class objects are populated from parsed input strings. Use object inheritance, polymorphism, and function and operator overloading where needed. All member data and internal functions are private. All classes have a "toString" method with friends for the insertion ("<<") operator. Use UML diagrams to describe your implementation.

6 Student # Name Address Phone # Course Student # Grade Course Day Hour Input Error Course Room

7 vector<Snap> snaps;
vector<Csg> csgs; vector<Cdh> cdhs; vector<Cr> crs; string toString() const { stringstream out; out << "snap(" << this->studentId; out << "," << this->studentName; out << "," << this->studentAddress; out << "," << this->studentPhone << ")"; return out.str(); } friend std::ostream& operator<< (ostream& os, const Snap& snap) os << snap.toString(); return os;

8 UML Summary Lab 02 - SNAP

9 3.3 Abstract Classes, Assignment, and Casting in a Hierarchy
Referencing Actual Objects Summary of Features of Actual Classes and Abstract Classes Assignments in a Class Hierarchy Casting in a Class Hierarchy Case Study: Displaying Addresses for Different Countries 3.3, pgs

10 Abstract Classes Inheritance An abstract class differs from an actual class (sometimes called a concrete class) in two respects: An abstract class cannot be instantiated. An abstract class declares at least one abstract member function, which must be defined in its derived classes. An abstract function is a virtual function that is declared but for which no body (definition) is provided. We use an abstract class in a class hierarchy when A base class can define attributes and functions that are common to derived classes. Actual derived classes may have unique as well as shared implementations. Pure abstract functions must be defined by derived concrete classes.

11 Abstract Class Food.h Inheritance #ifndef FOOD_H_ #define FOOD_H_ class Food { private: double calories; public: virtual double percent_protein() const = 0; virtual double percent_fat() const = 0; virtual double percent_carbohydrates() const = 0; double get_calories() const { return calories; } void set_calories(double cal) { calories = cal; } }; #endif These three abstract virtual functions impose the requirement that all derived classes implement these functions. (We would expect a different function definition for each kind of food.) A pure virtual function is specified in the class definition by using "= 0;:" in place of the function body.

12 Referencing Concrete Objects
Inheritance Because class Food is abstract, we can’t create type Food objects, hence the following statement is invalid: Food mySnack(); // compile time error! We can use a type Food pointer variable to point to an actual object that belongs to a class derived from Food. If a Vegetable object is derived from Food, then Food is contained in Vegetable. Vegetable Food Thus a pointer to Food can be used to reference a Vegetable. The pointer variable mySnack (type pointer-to-Food) is legal: Food* mySnack = new Vegetable("carrot sticks");

13 Assignments in a Class Hierarchy
Inheritance C++ is what is known as a strongly typed language. Operands have a type, and operations can be performed only on operands of the same or compatible types. This includes the assignment operation: l-value = r-value For the built-in types the r-value must be of the same type as the l- value, or there must be a conversion defined to convert the r-value into a value that is the same type as the l-value. For class types, the assignment operator may be overridden and overloaded. Pointer types are an exception: A pointer variable (l-value) that is of type pointer-to-base class may point to a derived object (r-value). However, the opposite is not legal: Computer* computer = new LapTop( ... ); // Legal LapTop* laptop = new Computer( ... ); // Illegal

14 Refactoring the Employee and Student Classes
3.4 Multiple Inheritance Refactoring the Employee and Student Classes 3.4, pgs

15 Multiple Inheritance Inheritance Multiple inheritance refers the ability of a class to extend more than one class. In multiple inheritance, all the data fields for the derived class are inherited from its base classes. For example, a university has many students who are full- time students and many employees who are full-time employees, but also some student employees.

16 Definition of Student_Worker
Inheritance There is no argument given for data fields hours or gpa, so they are initialized to default values #ifndef STUDENT_WORKER_H_ #define STUDENT_WORKER_H_ #include <string> #include "Employee.h" #include "Student.h" class StudentWorker : public Employee, public Student { public: Student_Worker(const std::string& name, Address* address, double rate, const std::string& major) : Employee(name, address, rate), Student(name, address, major) {} std::string to_string() const; }; #endif The heading shows that class StudentWorker extends class Employee and class Student The constructor contains two initialization expressions separated by a comma The first initializes the Employee part The second initializes the Student part

17 Refactoring Classes Inheritance A better solution than multiple inheritance is to recognize that both Employees and Students have common data fields. Common data fields and their associated member functions could be collected into a separate class, which would become a common base class Person. This process is known as refactoring and is often used in object-oriented design. However, it leads to similar problems, because there are two Person components in the StudentWorker class: one inherited from Employee and the other inherited from Student A workable solution to this problem is beyond the scope of the chapter you can find this solution in Appendix A.4.

18 The friend Declaration
Inheritance The friend declaration allows a function external to a class to access the private members of that class. The friend declaration gives the functions and classes it specifies access to the private and protected members of the class in which the friend declaration appears. This effectively makes the named function or class a member of the declaring class. The class itself must declare who its friends are. Friendship is not inherited and is not transitive - if a base class is a friend of a particular class, its derived classes are not automatically friends too.

19 The friend Declaration
Inheritance class A { private: int x; friend foo; }; class B void foo() A a; a.x = 10; // Valid } class C void bar() a.x = 10; // Invalid! class A { private: int x; friend class B; }; class B int y; void foo() A a; a.x = 10; // Valid (B friend of A) } friend class C; class C void bar() B b; b.y = 10; // Valid (C friend of B) a.x = 10; // Invalid, C ~friend of A)

20 Follow up… Inheritance class MyClass { private: string name; public: MyClass(const string name) { this->name = name; } ~MyClass() = default; friend std::ostream& operator<< (ostream& lhs, const MyClass& rhs) lhs << "MyClass(" << name << ")"; return lhs; } }; class MyClass { private: string name; public: MyClass(const string name) { this->name = name; } ~MyClass() = default; string toString() const ostringstream out; out << "MyClass(" << name << ")"; return out.str(); } }; std::ostream& operator<< (ostream& lhs, const MyClass& rhs) lhs << rhs.toString(); return lhs; A friend function of a class has the same access privileges to private and protected data as the class member functions. A friend declaration is not needed if using the public toString member function.

21


Download ppt "3.3 Abstract Classes, Assignment, and Casting in a Hierarchy"

Similar presentations


Ads by Google