C311 script11.txt -- 11/11/96 --- OBJECT-ORIENTED PROGRAMMING --- SOME TERMINOLOGY CLASS: a prototype for making an INSTANCE (using the 'new' operation of C++ or Java) +++ METHOD: a procedure belonging to a class a.k.a. MEMBER FUNCTION in C++ +++ CLASS VARIABLE: binding belongs to the class Java, C++: static variables +++ INSTANCE VARIABLE: new binding created for each instance of the class Java: non-static variables belonging to a class +++ ELEMENTS of a class: its methods and variables (class and instance) a.k.a. class MEMBERS in C++ --- TYPE: a collection of objects related by some property informally a set, e.g. integers, strings in the context of OOP, a class or interface +++ INTERFACE (or SIGNATURE): the type of an ADT or class contains the names and types of all procedures (methods) of the ADT (class) Java: also may include final variables (constants) +++ POLYMORPHISM: having more than one type +++ SUBTYPING: A is a SUBTYPE of B (and B is a SUPERTYPE of A) if anywhere an instance of B is expected an instance of A may be used instead. E.g. integer is a subtype of real in usual mathematical usage --- STRONG TYPING: cannot crash due to objects being of the wrong type E.g. in Scheme, Smalltalk, Java, and Ada, but not C or C++ Requires automatic storage management (garbage collection) in an OO language. +++ STATIC TYPING: uses compile time analysis to catch type errors In OOP, it is a type error if an object is passed a message it does not understand. Here 'type error' excludes projections from the wrong variant of a declared union type or narrowing to the wrong subclass. E.g. Java, Ada, C, and C++, but not Scheme or Smalltalk DYNAMIC (or LATENT) typing: opposite of static typing some or all type checks are done at run time --- ELEMENTS OF OOP -- Data abstraction -- Objects (actors) -- Code reuse by inheritance or deligation -- Polymorphism, especially subtyping Each of these is an independent concept. They may appear in isolation or in any combination. The full power of OOP comes from using them in combination. Without objects, you're not really doing OOP. --- DATA ABSTRACTION (ADT) a.k.a. ENCAPSULATION or INFORMATION HIDING grouping of procedures that work on data of common type(s) e.g. a module or class modeled with abstract (existential) types An ABSTRACT TYPE is just a name, which hides the CONCRETE TYPE, which is the actual type available only within the data abstraction. MODULE: an ADT with only one instance (set of variables) Java: class with only static and private variables --- Java ADT: instance of a class not used with polymorphism E.g. when no inheritance or interfaces: a 'final' class that does not 'implement' or 'inherit' instance variables must be private class name is the abstract type concrete type is essentially a vector of instance variables +++ C++ ADT: classes with static (C++, not Java, terminology) methods, which are the default! --- ACTORS (OBJECTS) combine data and procedure (state and behavior) in a single run-time object +++ A lambda expression is effectively a class with one method (procedure call) whose instance variables are its free variables. +++ OOP: dynamic method binding in general, requires that the object contain a method table not necessary in a statically-typed language in the absense of method overriding C++: virtual, not static, methods; not the default Java: always does not apply to static methods, if all methods are final, overriding is not possible +++ method invocation by message passing: e.g. C++, Java, Smalltalk, Scheme OOP simulation generic procedures: e.g. CLOS multimethods: method selection besed on more than the first argument of a generic procedure --- Scheme OOP using message passing > (define s1 (make-stack)) > (define s2 (make-stack)) > ((s1 'push!) 13) > ((s2 'push!) 14) > ((s2 'push!) 15) > ((s1 'local-pushed)) 1 > ((s2 'local-pushed)) 2 > ((s1 'pushed)) 3 > ((s2 'pushed)) 3 (define make-stack (let ((pushed 0)) (lambda () (let ((stk '()) (local-pushed 0)) (lambda (message) (case message ((empty?) (lambda () (null? stk))) ((push!) (lambda (x) (set! pushed (+ pushed 1)) (set! local-pushed (+ local-pushed 1)) (set! stk (cons x stk)))) ((pop!) (lambda () (if (null? stk) (error "Stack: Underflow") (begin (set! pushed (- pushed 1)) (set! local-pushed (- local-pushed 1)) (set! stk (cdr stk)))))) ((top) (lambda () (if (null? stk) (error "Stack: Underflow") (car stk)))) ((local-pushed) (lambda () local-pushed)) ((pushed) (lambda () pushed)) (else (error "Stack: Invalid message" message)))))))) Class variables: e.g. pushed Instance variables: stk, local-pushed. --- END ---