Concepts of Object-Oriented Programming Richard Berger [email protected] Johannes Kepler University Linz What This Talk Is About
Total Page:16
File Type:pdf, Size:1020Kb
Concepts of Object-Oriented Programming Richard Berger [email protected] Johannes Kepler University Linz What this talk is about • Introduction to Objects & Classes • Building objects • Composition • Encapsulation • Inheritance • Polymorphism • Best practices • Recommendations • Design Patterns • Conclusion • Pro & Cons of OOP What is Object-Oriented Programming? • OOP started in 1960s (Simula, SmallTalk) • Using objects as basic unit of computation message Object • Allows to extend type system • Usage: just like basic types (int, double, float, char, …) Object message • But with own structure and behavior • Static Languages (C++) message Object Types are known at compile time • Dynamic Languages (Python) Types can be manipulated at runtime I. Objects & Classes Defining new objects, object lifetime Where are these “objects”? • Objects exist in memory at runtime • Just like objects of primitive types (integers, floating-point numbers) • We can interpret 4 bytes of data as integer number • We can interpret 8 bytes of data as floating point number • In C we have structs to create composite types containing multiple primitive types • In C++ and other OOP languages this is further extended by associating behavior to a chunk of data through specifying methods to manipulate that data. Object • State • all properties of an object • Behavior • How an object reacts to interactions, such as calling a certain method • In OOP speak: Response of an object when sending it messages • Identity • Multiple objects can have the same state and behavior, but each one is a unique entity Structure and Behavior of similar objects is defined by their class. An object is also called an instance of a class. Classes Class • defines memory structure of objects • how we can interact with objects class Vector2D • how it reacts to interactions { public: Member Variable double x; • A variable in the scope of a class double y; • All instances allocate memory for their variables double length() Member Method { • A method which can be called for an object of the class. • Can access and modify the object state by manipulating return sqrt(x*x + y*y) member variables. } }; Interface • All methods which can be called on an object from outside. Lifetime of an Object Allocation • Allocation • Allocate enough memory to store object data/state Initialization • Initialization • Set an initial object state • Usage Usage • Interact with objects through methods • Access and modify object data • Cleanup Cleanup • Make sure that everything is in order before deletion • Deletion • Memory is freed, object ceases to exist Deletion Allocation Allocation Initialization Static / Stack Allocation Usage Stack void foo(int param1, int param2) param1 { double a = 30.0; param2 Cleanup double b = 50.0; a b Vector2D v; Deletion … v } x y + Fast + Automatic cleanup - Not persistent - “Limited” storage Allocation Allocation Initialization Dynamic / Heap Allocation Usage Stack Heap void foo(int param1, int param2) param1 { double a = 30.0; param2 Cleanup double b = 50.0; a Vector2D * v = new Vector2D; b Pointer Deletion v … x } y + Persistent + “Infinite” storage - Slow - Manual cleanup Allocation Initialization Initialization class Vector2D { Usage public: Vector2D(){ Constructors x = 0.0; • special methods which Cleanup y = 0.0; initialize an instance of a class } • multiple variants with Deletion Vector2D(double x1, double y1){ different parameters possible x = x1; • initialize member variables y = y1; } }; Vector2D v1(); Vector2D v2(10.0, 20.0); Vector2D * v3 = new Vector2D(); Vector2D * v3 = new Vector2D(10.0, 20.0); Allocation Usage Initialization Stack Objects Heap Objects Usage Vector2D v; Vector2D * pv = new Vector2D(); Cleanup // access members // access members v.x = 10.0; pv->x = 10.0; Deletion v.y = 20.0; pv->y = 20.0; // call member functions // call member functions double len = v.length(); double len = pv->length(); Allocation Cleanup Initialization class MyVector { Destructor Usage double * data; • Cleanup before destruction public: • Free any acquired resources MyVector( dim){ int (file handles, heap memory) Cleanup data = new double[dim]; } Deletion ~MyVector() { delete [] data; } }; Allocation Deletion Initialization Static / Stack Objects Usage Stack void foo(int param1, int param2) param1 { double a = 30.0; param2 Cleanup double b = 50.0; a b Vector2D v; Deletion v.x = 10.0; v v.y = 20.0; x … End of Scope y } objects on stack are automatically deleted at end of scope Allocation Deletion Initialization Dynamic / Heap Objects Usage Stack Heap void foo(int param1, int param2) param1 { double a = 30.0; param2 Cleanup double b = 50.0; a Vector2D * v = new Vector2D; b Pointer Deletion v->x = 10.0; v v->y = 20.0; x y … delete v; objects on heap must be deleted explicitly } Static class members Static Member Variable • Only a single instance of this variables exists class Point2D • Much like a global variable { • Can be accessed by all instances static int numPoints = 0; • Access by class name using ::, not instance public: int identifier; // Definition in a single .cpp file double x; int Point2D::numPoints = 0; double y; // access without having an instance cout << Point2D::numPoints << endl; Point2D(double x1, double y1) { identifier = numPoints++; x = x1; Static Method y = y1; • A method which is not applied on a class instance, but on } the class itself • Much like a global function static void reset_count() { • Can only access and modify static member variables numPoints = 0; } // call static method, no instance required }; Point2D::reset_count(); II. Building objects Composition, Encapsulation, Inheritance, Polymorphism Low-Level Model of an Airplane Abstractions Engine 1 model domain concepts as classes Flaps Engine 2 Aileron High-Level Model of an Airplane Elevator Heading, Speed, Height Engine 3 Latitude Engine 4 Rudder Longitude Gear Composition • natural way of creating new class Boeing747 objects is by building them out { of existing objects. Engine engine1; • Complex systems are composed Engine engine2; out of simpler sub-systems Engine engine3; Engine engine4; Gear frontGear; Gear backGear; Engine Engine Engine Engine Gear Gear … … }; Boing747 Encapsulation gearUp speed Boeing747 gearDown altitude class Boeing747{ private: hidden Gear gear; • View objects as black box : public • Don’t operate directly on internal data void gearUp() { of an object // update physics • Implementation details are hidden behind … interface gear.up(); • make member variables private } visible • Use methods of the interface to perform void gearDown() { certain actions // update physics … • Some languages, e.g. C++ and Java, help gear.down(); enforce this through specifiers: public, } private, protected }; Problems without Encapsulation void Boeing747::gearDown() { class Boeing747{ if(gear.isUp()) { public: totalAirFriction += 20.0; double totalAirFriction; gear.down(); Gear gear; } void gearUp(); } void gearDown(); void Boeing747::gearUp() { double speed(); if(gear.isDown()) { }; totalAirFriction -= 20.0; gear.down(); Boeing747 * a = new Boing747(); } } a->gearDown(); ≠ a->gear.down(); void Boeing747::speed() { // function of thrust & friction Encapsulation ensures that side effects and domain knowledge are kept inside the class which is responsible for them. return … } Type hierarchies and Inheritance Base Class • Smalltalk first added the concept of inheritance • Objects of a class can inherit state and behavior of a base class and make adjustments. • Usages: Derived Class • Extend classes with new functionality • Make minor modifications • Extract common functionality. Type hierarchies and Inheritance Airplane Boeing747 Cessna206h Type hierarchies and Inheritance class Boeing747 { class Cessna206h { float longitude, latitude; float longitude, latitude; float heading, speed; float heading, speed; float altitude; float altitude; ... ... public: public: void fullThrottle() { void fullThrottle() { engine1.maxThrottle(); engine1.maxThrottle(); engine2.maxThrottle(); speed = …; engine3.maxThrottle(); } engine4.maxThrottle(); } speed = …; } } class Airplane { public: Inheritance float longitude, latitude; Common structure float heading, speed; float altitude; }; class Boeing747 : Airplane { class Cessna206h : Airplane { ... ... public: public: void fullThrottle() { void fullThrottle() { Derived classes engine1.maxThrottle(); engine1.maxThrottle(); inherit structure engine2.maxThrottle(); speed = …; of Airplane engine3.maxThrottle(); } engine4.maxThrottle(); } speed = …; } } class Airplane { public: Inheritance float longitude, latitude; float heading, speed; float altitude; virtual void fullThrottle(); Common interface }; class Boeing747 : Airplane { class Cessna206h : Airplane { ... ... public: public: void fullThrottle() { void fullThrottle() { Derived classes engine1.maxThrottle(); engine1.maxThrottle(); implement or engine2.maxThrottle(); speed = …; extend interface engine3.maxThrottle(); } of Airplane engine4.maxThrottle(); } speed = …; } } Polymorphism Boeing747 * a = new Boeing747(); • Objects of derived classes can Airplane * b = new Boeing747(); be used as base class objects. Airplane * c = new Cessna206h(); • Polymorphism allows us to // as expected: will call Boeing747::fullThrottle modify the behavior of base a->fullThrottle(); classes and replacing the implementation of methods. // NEW! will call Boeing747::fullThrottle b->fullThrottle(); • Polymorphic methods must be declared virtual (in C++) // NEW! will call Cessna206h::fullThrottle c->fullThrottle(); Polymorphism