diff --git a/pages/CSE332S/CSE332S_L12.md b/pages/CSE332S/CSE332S_L12.md new file mode 100644 index 0000000..06873ac --- /dev/null +++ b/pages/CSE332S/CSE332S_L12.md @@ -0,0 +1,427 @@ +# CSE332S Lecture 12 + +## Object-Oriented Programming (OOP) in C++ + +Today: + +1. Type vs. Class +2. Subtypes and Substitution +3. Polymorphism + a. Parametric polymorphism (generic programming) + b. Subtyping polymorphism (OOP) +4. Inheritance and Polymorphism in C++ + a. construction/destruction order + b. Static vs. dynamic type + c. Dynamic binding via virtual functions + d. Declaring interfaces via pure virtual functions + +## Type vs. Class, substitution + +### Type (interface) vs. Class + +Each function/operator declared by an object has a signature: name, parameter list, and return value + +The set of all public signatures defined by an object makes up the interface to the object, or its type + +- An object’s type is known (what can we request of an object?) +- Its implementation is not - different objects may implement an interface very differently +- An object may have many types (think interfaces in Java) + +An object’s class defines its implementation: + +- Specifies its state (internal data and its representation) +- Implements the functions/operators it declares + +### Subtyping: Liskov Substitution Principle + +An interface may contain other interfaces! + +A type is a **subtype** if it contains the full interface of another type (its **supertype**) as a subset of its own interface. (subtype has more methods than supertype) + +**Substitutability**: if S is a subtype of T, then objects of type T may be replaced with objects of type S + +Substitutability leads to **polymorphism**: a single interface may have many different implementations + +## Polymorphism + +Parametric (interface) polymorphism (substitution applied to generic programming) + +- Design algorithms or classes using **parameterized types** rather than specific concrete data types. +- Any class that defines the full interface required of the parameterized type (is a **subtype** of the parameterized type) can be substituted in place of the type parameter **at compile-time**. +- Allows substitution of **unrelated types**. + +### Polymorphism in OOP + +Subtyping (inheritance) polymorphism: (substitution applied to OOP) + +- A derived class can inherit an interface from its parent (base) class + - Creates a subtype/supertype relationship. (subclass/superclass) + - All subclasses of a superclass inherit the superclass’s interface and its implementation of that interface. + - Function overriding - subclasses may override the superclass’s implementation of an interface + - Allows the implementation of an interface to be substituted at run-time via dynamic binding + +## Inheritance in C++ - syntax + +### Forms of Inheritance in C++ + +A derived class can inherit from a base class in one of 3 ways: + +- Public Inheritance ("is a", creates a subtype) + - Public part of base class remains public + - Protected part of base class remains protected +- Protected Inheritance ("contains a", **derived class is not a subtype**) + - Public part of base class becomes protected + - Protected part of base class remains protected +- Private Inheritance ("contains a", **derived class is not a subtype**) + - Public part of base class becomes private + - Protected part of base class becomes private + +So public inheritance is the only way to create a **subtype**. + +```cpp +class A { +public: + int i; +protected: + int j; +private: + int k; +}; +class B : public A { +// ... +}; +class C : protected A { +// ... +}; +class D : private A { +// ... +}; +``` + +Class B uses public inheritance from A + +- `i` remains public to all users of class B +- `j` remains protected. It can be used by methods in class B or its derived classes + +Class C uses protected inheritance from A + +- `i` becomes protected in C, so the only users of class C that can access `i` are the methods of class C +- `j` remains protected. It can be used by methods in class C or its derived classes + +Class D uses private inheritance from A + +- `i` and `j` become private in D, so only methods of class D can access them. + +## Construction and Destruction Order of derived class objects + +### Class and Member Construction Order + +```cpp +class A { +public: + A(int i) : m_i(i) { + cout << "A" << endl;} + ~A() {cout<<"~A"<x (); // prints "B::x": lookup the type of bp, which is B, and x() is non-virtual so it is statically bound + bp->y (); // prints "B::y": lookup the dynamic type of bp, which is B (at run-time), and call the overridden y() function + ap->x (); // prints "A::x": lookup the type of ap, which is A, and x() is non-virtual so it is statically bound + ap->y (); // prints "B::y": lookup the dynamic type of ap, which is B (at run-time), and call the overridden y() function of class B + return 0; +}; +``` + +Only matter with pointer or reference + +- Calls on object itself resolved statically +- E.g., `b.y();` + +Look first at pointer/reference type + +- If non-virtual there, resolve statically +- E.g., `ap->x();` +- If virtual there, resolve dynamically +- E.g., `ap->y();` + +Note that virtual keyword need not be repeated in derived classes + +- But it’s good style to do so + +Caller can force static resolution of a virtual function via scope operator + +- E.g., `ap->A::y();` prints “A::y” + +Potential Problem: Class Slicing + +When a derived type may be caught by a catch block, passed into a function, or returned out of a function that expects a base type: + +- Be sure to catch by reference +- Pass by reference +- Return by reference + +Otherwise, a copy is made: + +- Loses original object's "dynamic type" +- Only the base parts of the object are copied, resulting in the class slicing problem + +## Class (implementation) Inheritance VS. Interface + +Inheritance +Class is the implementation of a type. + +- Class inheritance involves inheriting interface and implementation + - Internal state and representation of an object + +Interface is the set of operations that can be called on an object. + +- Interface inheritance involves inheriting only a common interface + - What operations can be called on an object of the type? + - Subclasses are related by a common interface + - But may have very different implementations + +In C++, pure virtual functions make interface inheritance possible. + +```cpp +class A { // the abstract base class +public: + virtual void x() = 0; // pure virtual function, no default implementation + virtual void y() = 0; // pure virtual function, no default implementation +}; +class B : public A { // B is still an abstract class because it still has a pure virtual function y() that is not defined +public: + virtual void x(); +}; +class C : public B { // C is a concrete derived class because it has all the pure virtual functions defined +public: + virtual void y(); +}; +int main () { + A * ap = new C; // ap is a pointer to an abstract class type, but it can point to a concrete derived class object, cannot create an object of an abstract class, for example, new A() will be an error. + ap->x (); + ap->y (); + delete ap; + return 0; +}; +``` + +Pure Virtual Functions and Abstract Base Classes: + +A is an **abstract (base) class** + +- Similar to an interface in Java +- Declares pure virtual functions (=0) +- May also have non-virtual methods, as well as virtual methods that are not pure virtual + +Derived classes override pure virtual methods + +- B overrides `x()`, C overrides `y()` + +Can't instantiate an abstract class + +- class that declares pure virtual functions +- or inherits ones that are not overridden + +A and B are abstract, can create a C + +Can still have a pointer or reference to an abstract class type + +- Useful for polymorphism + +## Review of Inheritance and Subtyping Polymorphism in C++ + +Create related subclasses via public inheritance from a common superclass + +- All subclasses inherit the interface and its implementation from the superclass + +Override superclass implementation via function overriding + +- Relies on virtual functions to support dynamic binding of function/operator calls + +Use pure virtual functions to declare a common interface that related subclasses can implement + +- Client code uses the common interface, does not care how the interface is defined. Reduces complexity and dependencies between objects in a system. diff --git a/pages/CSE332S/CSE332S_L13.md b/pages/CSE332S/CSE332S_L13.md new file mode 100644 index 0000000..5b2aba3 --- /dev/null +++ b/pages/CSE332S/CSE332S_L13.md @@ -0,0 +1 @@ +# CSE332S Lecture 13 diff --git a/pages/CSE332S/_meta.js b/pages/CSE332S/_meta.js index d90f7f9..0f2c06a 100644 --- a/pages/CSE332S/_meta.js +++ b/pages/CSE332S/_meta.js @@ -14,4 +14,6 @@ export default { CSE332S_L9: "Object-Oriented Programming Lab (Lecture 9)", CSE332S_L10: "Object-Oriented Programming Lab (Lecture 10)", CSE332S_L11: "Object-Oriented Programming Lab (Lecture 11)", + CSE332S_L12: "Object-Oriented Programming Lab (Lecture 12)", + CSE332S_L13: "Object-Oriented Programming Lab (Lecture 13)", }