The basic point of object orientation is that, because we think about objects in the real world, we design systems in terms of objects. By programming with an object-oriented language, it is very easy to implement those designs in a natural way. Objects give great power: an object-oriented system is characterized by encapsulation, inheritance, polymorphism and relationships.
Encapsulation is the art of exposing the aspects of a class that a user can see, but hiding the parts that should not be seen. C++ provides the public
and private
qualifiers to express this:
class TS
{
public:
S(T1 aArg1, T2 aArg2);
void Use(T3 aArg1, T4 aArg2);
~S();
private:
TInt iInt;
TText8 iText;
TReal iReal;
};
Often, functions are public, while data is private. This allows a choice of representations for a class. In practical OO programming, classes often have many private functions. For classes whose representation is a fairly basic property and whose functions would provide direct read/write access to member variables, it is quite acceptable to make data public.
Inheritance is used to express an is-a relationship: for instance, “a button is-a bordered control”. This allows taxonomies of objects to be built up. In C++, inheritance is represented by derivation.
class CEikButtonBase : public CEikBorderedControl
{
// etc
};
Encapsulation is enhanced by the protected
qualifier, which means effectively private
for non-derived classes, but public
for derived classes.
Inheritance is often over-used by designers of object-oriented systems. Inheritance should not be used unless it is natural: for instance, no-one would dispute that a button is a bordered control. But in Smalltalk, a process is an ordered collection. Of what?! In cases like this, it is better for a class to use another class, rather than derive from it.
Polymorphism builds on inheritance to allow an abstract base class to be defined, from which concrete derived classes may inherit. But, these concrete objects may be used without knowing anything about them, other than that they are derived from the abstract base class.
Foo(CCoeControl* aControl)
{
aControl->Draw();
}
In the code above, for instance, the function knows that a control has a Draw()
function, but it knows nothing about the type of control or how it is drawn.
In object oriented systems, the relationships between objects matter very much. Some examples from the Symbian platform include
the control environment (CCoeEnv
) has-a window server session (RWsSession
). The lifetime of the window server session is identical to that of the control environment.
the app UI (CEikAppUi
) uses-a document (CEikDocument
). The document has independent existence: the app UI may come into being for a while, and then be destroyed, but throughout the app UI’s lifetime, it uses the document.
In these relationships, cardinality is important. An app UI uses only one document, and a control environment has only one window server session. But a dialog (CEikDialog
) has any number of lines.