Object-oriented languages World conceptualization in terms of objects, classes, hierarchies Advantages - allow modularity ad implementation of abstraction therefore: - easy to understand - easy to extend by inheritance - easy to reuse Unit of modularity – an ADT implementation Languages defined to support OO: Smalltalk, Eiffel, Java Languages with added features to support OO: C++, Ada95, CLOS, ObjectPascal 1. Concepts of OOP Objects = entities that encapsulates data and related operations push(s,el) s.push(el) OOL are characterized by: - abstract data type definitions - inheritance - inclusion polymorphism - dynamic binding of function calls to function bodies 1.1 Classes of objects Objects, classes, instances An object contains a number of instance variables and supports a number of methods. A message is sent to an object to request the invocation of one of its methods. Smalltalk example: s push 5 C++ example Class definition class stack { public: void push(int) {elements[top++] = i; }; int pop( ) {return elements[--top]; }; private: int elements[100]; int top=0; }; Creation of objects stack s1, s2; stack* sp = new stack; Use of member functions s1.pop( ); sp -> pop(); Can we say s1.top? 1 1.2 Inheritance Inheritance = a linguistic mechanism that allows us to define a new class that inherits the properties of a parent class. adds new properties The derived (or child) class redefine (override) inherited properties C++ example class counting_stack: public stack { public: int size( ); //return the number of elements on the stack }; Problem to be considered: how can we access member variables and member functions? 1.3 Polymorphism OOL provides polymorphic variables that may refer to objects of different classes In a polymorphic PL, an object can belong to more than one type. For example, routines can accept actual parameters of more than one type. PLs that adopt a strong typing system limit polymorphism: usually a variable of class T is allowed to refer to objects of type T or any classes derived from T. Remember from Lecture no. 3: parametric universal inclusion polymorphism overloading ad-hoc coercion - Smalltalk, Eiffel, Java: all objects are referred to through references and references may be polymorphic. - In C++ only pointers, reference variables, and by-reference parameters may be polymorphic. 2 C++ example stack* sp= new stack; counting_stack * csp = new counting_stack; …. sp = csp; //okay … inclusion polymorphism csp = sp; //statically not sure if okay – disallowed csp = sp; would be allowed in a language with weak-typing system stack s; counting_stack cs; …….. s = cs; // okay, object is coerced to stack cs=s; // not allowed coercion polymorphism 1.3 Dynamic binding of function calls to function bodies adds new properties The derived (or child) class redefine (override) inherited properties Q: which is a proper binding of a member function if the PL allows redefinition and polymorphism? stack* sp = new stack; counting_stack * csp = new counting_stack; … sp -> push(…); // stack::push csp -> push(…); //counting_stack::push …. sp = csp; // assignment is okay sp -> push(…); //which push? statically – stack::push(…) dynamically – counting_stack::push(…) Inheritance + polymorphism a new programming style and technique (difficult to achieve in PL that do not support these features) 3 2. Inheritance and the type system P: interaction between inheritance and type consistency rules of the language 2.1 Subclasses versus subtypes is-a relation is it a sub-type type relation? A subclass defines a sub-type if it adds member variables and functions or redefines existing functions in a compatible way A subclass does not define a sub-type if it hides some parent member variables and functions or modifies them in an incompatible way Compatible way? - behavioral equivalence - base::f(x) may be replaced by derived::f(x) without risking any type errors (e.g. having identical signatures) 2.2 Strong typing and polymorphism Strong type system = guarantees type safety(type errors can be caught at compile time) Sustainability = can an object of a derived class be substituted for an object of the base class in every context? class base {…}; class derived : public base {…}; …. base* b; derived* d; Type extension: if the derived class only extends the type of base, then sustainability is guaranteed. Overriding of member functions C++: to override a member function in a derived class, specify it as a virtual function class polygon { public: polygon (…) {…} //constructor virtual float perimeter( ) {…}; }; class square: public polygon { public: square (…) {…} //constructor …. float perimeter( ) {…}; //overrides the definition of perimeter in polygon }; 4 Sustainability in C++: requires that the signature of the overriding function must be exactly the same as the signature of the overridden function. General rule for sustainability in case of overriding members functions o contravariance rule: the input parameters of the overriding function must be supertypes of the corresponding parameters of the overridden function o covariance rule: the result parameter of the overriding function must be a subtype of the result parameter of the overridden function C++, Java, ObjectPascal: none of the above, require same signature Emerald: both rules Eiffel: covariance rules on both input and output parameters Example in a language that is not C++ (but has a quite close syntax) class base { public: t1 virtual fnc(s1 par) {…} … }; class derived: public base { public: t2 fnc(s2 par) {…} }; base* b; derived* d; s1 v1 if (…) b = d; …. v0 = b-> fnc(v1); s2 v2; t0 v0; 2.3 Inheritance hierarchies Single and multiple inheritance - Single: Simula67, Ada, Java, Smalltalk - Multiple: C++, Eiffel Problems with multiple inheritance: o name clashes among parents of a subclass o diamond inheritance Eiffel: rename, undefined 5 Implementation inheritance and interface inheritance Interface inheritance = restricts derived classes to access a parent class only through its public interface Implementation inheritance = allows a derived class to access also the private part (i.e., implementation) of a parent class C++ - default = interface inheritance - protected members – implementation inheritance 3. Object-oriented features in programming languages 3.1 Smalltalk Dynamic type system = the type of a variable is determined by the type of the object it refers to at run time Classes may have: - instance variables – not visible outside - instance methods – are invoked by sending a message to the object - class variables – a single instance per class, for all objects of the class - class methods – a single instance per class, for all objects of the class Message: myPoint xMove delta For multiple parameters in messages – named parameters association o o o o Single inheritance, the most general class: system class Object All variables and objects are dynamic Dynamic polymorphism References are untyped, can refer any class instance 3.2 Eiffel (read also Section 3.3.2 Abstract data types in Eiffel, PLD) Classes, subclasses, inheritance, dynamic binding Object creation is explicit, separate step from object declaration b: Book; !!b; - declaration of a reference to BOOK objects - allocating and initializing an object that b points to. Dynamic allocation, static allocation via expanded. Inheritance: a subclass either extends its parent class or specializes it. Multiple inheritance: name conflicts may be resolved with undefine and rename 6 Covariance rules for polymorphism in function redefinition. The pure virtual specifier to implement virtual classes is deferred. class POINT export x_move, y_move, reset creation make_point feature x, y: INTEGER; x_move (a:INTEGER) is -- moves the point horizontally do x := x + a end; -- x_move …….. make_point(a, b: INTEGER) is -- sets the initial coordinates of the point do x := a; y := b; end – make_point end: -- POINT p1, p2: POINT; !!p1.make_point(4, 7); !!p2.make_point(55, 0); p1.move_x(3); 7