Objects consist of instance fields for the class of the object,
plus instance fields for its superclasses.
Every object is created by a class constructor. Interfaces don't have constructors.
Reference variables
All non-primitive variables contain only references to objects on the heap.
They never contain the object. C++ object variables may be either, but
Java supports only object references.
Assignment
Reference variable assignment is fast because only the
reference is copied (currently 4 bytes).
Making a copy of an object requires using clone().
Assigning up the inheritance hierarchy is always possible without a cast. (is-a is obvious)
Assigning down the inheritance hierarchy is only possible with a cast.
Downcasting makes a run-time check to be sure it's legal. (is-a is possible)
Assignment to an interface type variable from a reference type
implements that interface is possible without a cast. (is-a is obvious).
Assignment to an interface type variable from a reference type
that does not implement that interface requires an explicit cast which causes a run-time check
to make sure that the object's class really does implement this interface. (is-a is possible)
null can be assigned to any reference type.
Inheritance and interfaces
Every class has one superclass, except Object, which is the
root class for all other classes.
A class may implement many interfaces, but extend only one class.
Overriding and polymorphism
Methods (non-final) may be redefined in a subclass.
The @Override annotation provides compiler checking.
Polymorphism: When a method is called, the overridden method corresponding to the
actual object type is called, regardless of reference variable type.