"I paint objects as I think them, not as I see them."
Pablo Picasso
This is the second part in a brief review of a selection of topics from Computer Science.
- Intro and Big O
- Object Oriented Programming
- Data Structures: arrays, lists, trees, hash tables
- Algorithms (searches, sorts, maths!)
- Graphs, Networks, and Operating Systems
The content within this post focuses on one of the most popular software design pattern groups, OOP. In fact our encyclopedic ally wikipedia refers to OOP as a paradigm.
Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance. Many modern programming languages now support OOP.
For several popular languages OOP is grafted on, a set of features nearly at odds with the core intent of their host language. In contrast there are a handful of languages crafted where encapsulation is essential to their design (syntax and semantics). SmallTalk, Python and Ruby are prominent examples where everything is an object.
Let's dive right into to some of the terminology rattled off by Steve Yegge in Five Essential Phone Screen Questions. Anyone who can call out this list of constructs off the top of their head is an OOP Grammaton Cleric.
- class, object (and the difference between the two)
- instantiation
- method (as opposed to, say, a C function)
- virtual method, pure virtual method
- class/static method
- static/class initializer
- constructor
- destructor/finalizer
- superclass or base class
- subclass or derived class
- inheritance
- encapsulation
- multiple inheritance (and give an example)
- delegation/forwarding
- composition/aggregation
- abstract class
- interface/protocol (and different from abstract class)
- method overriding
- method overloading (and difference from overriding)
- polymorphism (without resorting to examples)
- is-a versus has-a relationships (with examples)
- method signatures (what's included in one)
- method visibility (e.g. public/private/other)
A series of OOP definitions, made as human friendly as possible (many are open to interpretation)
A class is a definition for an object, and serves as blueprints. An object is an instance of a class.
Methods are functions defined in classes and operate on object data or members, or are purely required interfaces (pure virtual methods). A method signature is the syntax which declares the methods interface (name, arguments, returned objects, visibility).
A class containing pure virtual functions is referred to as an abstract class and may contain other method definitions and state information, an interface serves a similar role but has no state or implementation*.
A derived or subclass inherits an interface and structure from a base, super or parent class^. Virtual methods enable subclasses to replace or augment method implementation of the parent class. Method overriding describes subclasses replacing super class members with identical signatures. Method overloading describes multiple methods which share the same name but have varied signatures.
A static method is defined once for all object instances, while class methods are defined for each instance. Likewise, static initializers are performed once per class, while class initializers are called for each instance.
A constructor call is made whenever an object is created, while a destructor method is called whenever an object is destroyed to release required resources (this is what destructors look like). Methods are encapsulated with data through bundling or restricted access.
Polymorphism allows various data types to be handled with a uniform interface. "Parametric polymorphism allows a function or a data type to be written generically, so that it can handle values identically without depending on their type" (parametric polymorphism)
Simple example of polymorphism:
Multiple inheritance occurs when a subclass inherits traits from multiple super classes. An example of multiple inheritance is the infamous killer-clown class which inherits attributes and methods from aliens and space-monsters.
Delegation is defined as routing method calls from one object to another. Deferring a task to another object, defines the receiving object as the delegate. Delegation may occur at run time unlike most inheritance which is defined with the class type (reference). An example of delegation occurs in Cocoa when GUI elements actions send notifications to the app controller class.
Method visibility is important for defining encapsulation by restriction. A member or method may be public, protected or private. Private visibility allows only class member access to the method or member. Protected visibility enables class and child class access. Public visibility allows ubiquitous access to the entire cosmos of calling programs.
Relationships between classes can be categorized as is-a versus has-a. Is-a defines an inherited or strict type, as in I am (mostly) human. Has-a defines a container or ownership relation, ie I have a piece of bacon. Object aggregation or composition occurs when container classes have several member classes (has-a). Complex structures can be built up from simple members. When a Composition is destroyed, so are all of it's member objects (the database containing these posts). Aggregation describes an order of several objects, but the parts remain after the destruction of the whole (glass jar of marbles).
When the mind's eye rests on objects illuminated by truth and reality, it understands and comprehends them, and functions intelligently; but when it turns to the twilight world of change and decay, it can only form opinions, its vision is confused and its beliefs shifting, and it seems to lack intelligence.
Plato, Republic
Notes:
*= Differences between abstract classes and interfaces references: 1,2,3
^= Beware the Yo-Yo problem. Long lived layered libraries that continue to change are particularly vulnerable to an issue of complex inheritance. As I've gotten older (and hopefully a bit wiser), I much prefer a concise dynamic interface to widely distributed class interfaces.