Object-Oriented Concepts

Objects

At runtime, an object-oriented program can be viewed as a collection of interacting objects.

Objects represent entities (things, events, procedures) and values (quantities, locations, times) in the problem space.

Objects can also represent entities in the solution space. (E.g., controllers, boundaries, managers, dispatchers, message brokers, and other framework components).

An object is a collection of fields (variables and constants) and methods (functions and procedures). The fields represent the state of an entity. The methods represent the entity's behavior.

Their fields and methods can only be accessed through the object, if then:

myAccount.balance
myAccount.deposit(500)

Objects interact by calling each other's methods.

An object is mutable if its state can change without changing its identity. (E.g., the balance of a bank account can change without changing its identity.)

Usually objects representing values are immutable. Their state is their identity. (For example, a point in the plane is identified with its x- and y-coordinates.)

Classes

A class is a collection of related field and method declarations. A class is a template for creating objects. Invoking a class constructors creates and initializes an object.

Account myAccount = new Account();

Interfaces

An interface is a collection of related abstract method declarations. An abstract method declaration specifies the name and type of a method, but not its implementation.

interface GUIComponent {
   void click();
   void draw();
}

A class implements an interface if it implements all of the interface's abstract methods. If a class implements some but not all of these methods, then the class is abstract and can't be instantiated.

class Button implements GUIComponent { ... }

Inheritance

A class A can extend another class B. In this case A inherits the fields and methods of B. A can override (redefine) any inherited methods.

class CheckBox extends Button { ... }

Interface A can extend interface B. This just means that A inherits the abstract methods of B.

UML

During program design we can represent classes, interfaces, and their relationships using a UML class diagram.

For example, the following diagram might be part of the design for an interpreter for some programming language:

A code generator might translate this diagram into the following Java declarations:

interface Phrase {
   Void execute();
}

class Expression implements Phrase { ... }
class Definition implements Phrase { ... }
class Command implements Phrase { ... }

class Symbol extends Expression { ... }
class Literal extends Expression { ... }
class FunCall extends Expression { ... }

class Program {
   List<Phrase> phrases;
}

Polymorphism (Data-Driven Control)

Interfaces and classes are types.

Assume A is a type. Object x has type A if x can masquerade as an instance of A. In other words, x can be used in all contexts where an instance of A is expected.

Assume A and B are types and x is an object. Here are a few important rules object-oriented type systems must satisfy:

A is a subtype of B if A equals, extends, or implements B (inheritance rule)

A is a subtype of itself (reflexive rule)

if A is a subtype of B and B is a subtype of C, then A is a subtype of C (transitivity rule)

if x is an instance of A, then x has type A (instantiation rule)

if x has type A and A is a subtype of B, then x has type B (the subsumption rule)

For example:

FunCall is a subtype of Expression (inheritance)
Expression is a subtype of Phrase (inheritance)
FunnCall is a subtype of Phrase (transitivity)
Phrase is a subtype of Phrase (reflexive)

Assume:

FunCall e = new FunCall(); // object e is an instance of the FunCall class

We may infer:

e has type FunCall (instantiation)

e also has type Expression and Phrase (subsumption)

This last fact means that e can masquerade as a phrase or expression. For example:

Phrase p = e; // e can be assigned to variables of type Phrase or Expression
Program prog = new Program(); // assume
prog.phrases.add(e); // e can be passed to methods that expect a phrase

The subsumption rule enables polymorphism, or data-driven control, which states that objects, not programmers, should determine the flow of execution in a program.

For example, we don't know what will happen when we call:

prog.phrases.get(next++).execute();

Ignorance is bliss. This code doesn't need to change when new subtypes of Phrase are added to the design.

Parametric Types (Generics)

A parametric type may contain type parameters. For example:

class Stack<Data> {
   Data[] items;
   void push(Data item) { ... }
   ...
}

Reflection

Reflection is the ability of objects to answer questions about their class, methods, and fields. For example:

e.getClass().getMethods()[i].getParameters();

Reflection enables architectures that allow users to add new components to their programs that were unknown at the time the program was written.