CISC 3150
Object-Oriented Programming
On the Path to Object-Orientation
Object-oriented Programming
- See wikipedia entry on Object-oriented programming
- Elements
- Modularity
- Separate compilation
- Reuseable code
- interface/implementation
- Promotes encapsulation
- Data encapsulation
- Data hiding
- Access control
- Robust data types
- Polymorphism
- Allows user programs to be written based on an interface. Such programs need not even be recompiled
when changes are made to the implementation backing up the interface.
Class Definitions
- field, member
- instance variable, data member
- method, member function
- get/set, accessor/mutator
- higher semantics
- class method, static method, static member function
- static members, class variables, static variables
- modifiers
- visibility / access control
- immutable: const, final
Data Initialization
- constructor
- member initialization list
- static block
- intiialization at point of declaration
- C++ const/static primitive type initialization
- Order of declarations within a class
- Usual rule of thumb: order of importance
- Definition/Interface vs Implementation
Variations on Classes
- Abstract classes
- Interfaces (a la Java)
Mutually Recursive Class Definitions
- No problem in Java
- C++ - Forward definitions (incomplete / partial class definitions)
- inner - Java
- Inner class is linked to specific instance of outer class
- static inner class (same as nested class in C++)
- nested class - C++
- access / name / visibility control
Classes as Objects
- Class, Field, Method, Modifier classes
- Reflection
Message passing / invocation : process of requesting an object (the receiver)
to perform an action (execute the method associated with the method name -- often called the selector),
often in the presence of arguments.
- Message passing notation:
- receiver.selector(arguments)
- receiver selector
- receiver keyword1: arg1 keyword2: arg2
shape rotateBy: 30
shape rotateBy: degrees around: point
Statically vs Dynamically Typed Languages
- static - types are associated with variables
- The type is typically bound to the variable via a
declaration
- Allows system to check at 'compile' time that a receiver will understand a message
- dynamic - types are associated with values
- Variables are nothing more than names
Referring to the Receiver within a Method
Object Creation
- Creation separated from referencing variable declaration (Java:
new Counter()
)
- Variable represents object (C++ :
Counter ctr
)
Creating Arrays of Objects
- Java: Creation of the array separate from the creation of the elements
- C++: requires default constructor (unless there's an explicit initialization)
class C {
public:
C(int i) ......
...
private:
...
};
void main() {
C carr1[] = {1, 2, 3, 4, 5}; // OK
C carr2[10]; // Compiler error -- no default constructor
}
Memory Management
- Java: no expicit pointers; objects are heap-based; garbage collection
- Reference variables can still be stack-based
- C++: stack(automatic) or heap (or global/external) objects
- heap-based involve explicit pointer manipulation
- The mixed memory model also entails the need for copy constructors,
destructors, and assignment operators
Constructors
- Method used to initialize a newly created object
- Eliminates the window of vulnerability &mdash i.e., the
gap between the creation of the object and the point at which its value has been
properly initialized.
- Not just for the user — e.g., Java's restrcitions on
super
in
subclass constructors
- Often same name as class and no return type (C++, Java)
- Member initialization in C++
- necessary for initialization of superclass as well as data members
with non-default constructors (composition)
class A {
public:
A(int i) : i(i) {}
private:
int i;
};
class B {
public:
B(int j) : j(j) {}
private:
int j;
};
class C : public A {
public:
A(int i, int j, int k) : C(i), b(j), k(k) {}
private:
B b;
int k;
};
- Java: superclass initialized with
super
; instance variables
(composition) initialized either at point of declaration or within body of constructor
- default constructor: constructor with no arguments
- Provides novice or casual user with a quick instance whith a (typically) useful
initial state
- Required for array creation in C++
- Supplied by default if not other constructor is specified (C++, Java)
- copy constructor (C++): constructor whose argument is a reference
to an instance of the same class.
- Used in call-by-value
- Miranda rule: Supplied by default if class designed does not
supply one
- Since the default is often inappropriate (see below),
class designer will
often supplet copy constructor
Shallow vs Deep Copy
Destructors / Finalizers
- Primary use is to provide some form of programmer control to logic when object's lifetime
is about to end.
- Destructor (C++):
- ~classname
- no args, no return value, never called explicitly
- Finalizer (Java):
- method named
finalize
- invoked automatically right before object is reclaimed by garbage collector
- no idea WHEN this might happen, so not as useful
- On other hand, main use for a destructor is memory reclamation, and the collector
does that for you, so it's not all that bad
Orthodox Canoncal Class Form (C++)
Essentially mandatory for any class with one or more data members that pointers; good idea in general:
What goes wrong if the Canoncal Class Model is not Followed in the Presence of Pointers
- No copy constructor: violation of call-by-value semantics
- object passed by value as parameter, but only a shallow copy is made
- changes made to pointer targets persist upon returning to caller
- No assignment operator: violation of assignment semantics
- right-hand-side assigned to left-hand-side, but only a shallow copy is made
- changes made to either's targets affects the other's
- No destructor: memory leak
- deep copy is made (since copy constructor and/or assignment operastor have been defined)
- left-hand variable is assigned to again, or function is exited; memory allocated by assignment
operator / copy constructor for pointer target is not reclaimed
Just a Brief Word ABout Smalltalk
- Constructors are considered special methods/functions in Java/C++
- They have no (explicit) receiver (the object didn't exist yet to the programmer)
- The compiler must know about them
- In Smalltalk, even classes are objects, descendants of a class named
Class
- Every class in the system has a corresponding metaclass that
contains information about the class itself (e.g. its method and instance var tables)
- For example, the class
Number
has the corresponding
metaclass MetaNumber
- The metaclass is a subclass of the
Class
class
- Information contained in the
Class
superclass are common
to all metaclasses; e.g., method and var tables
- Information in the metaclass subclass cosists of information specific to
the metaclass (and thus the class itself) &mdash in particular
a method (defined in the metaclass) that creates and initializes an
object of the class — or in other words a constructor for the class!
- This constructor is a perfectly normal method (though of the metaclass).
- This stuff IS confusing, so the Smalltalk class browser hides metaclasses in general,
and presents the corresponding (metaclass) information as class
information associated with the class (
Number
in our example).
class Class {
name
new
addVariable(...) {...}
addMethod(...) {...}
VariableTable instanceVariables;
MethodTable methods;
}
class MetaNumber extends Class {
addVariable("value") // Adds instance variable 'value' for Number
addMethod("add") // Adds method 'add' for Number
addMethod("sub") // Adds method 'sub' for Number
...
Number with(int val) {...} // MetaNumber method: initialize the instance variable, value, to val
).
// note the receiver is an instance of MetaNumber (i.e., Number), while the return object
// is an instance of Number
}
MetaNumber Number = MetaNumber new; // Number is a (in fact the ONLY) variable of class MetaNumber
Number n = Number new with(12); // creates and initializes a new Number object
If this is of interest to you-- more on Smalltalk's metaclasses can be found
here.
An Aside About Design Patterns in the Context of Smalltalk's Metaclasses
- Only one instance of the metaclass need be created (why?) Which pattern?
- Notice that in C++/Java, constructors need to be special methods because the object doesn't
exist yet.
- In some respects, constructors are like class/static methods-- they operate not
on a specific object (although they DO do that it's the creation that problematic), but
rather they are associated with the class as a whole (i.e., create a new instance of the
class).
- The creation doesn't occurr within the context of the object, but rather outside of it,
hence the special/static nature of the constructor. Unless you use Which pattern?