|
|
|
Advertisement
|
Dynamic binding, polymorphism, and change
When you establish an inheritance relationship between two classes, you
get to take advantage of dynamic binding and polymorphism.
Dynamic binding means the JVM will decide at runtime which method
implementation to invoke based on the class of the object. Polymorphism
means you can use a variable of a superclass type to hold a reference
to an object whose class is the superclass or any of its subclasses.
One of the prime benefits of dynamic binding and polymorphism is that
they can help make code easier to change. If you have a fragment of
code that uses a variable of a superclass type, such as
Fruit, you could later create a brand new subclass, such
as Banana, and the old code fragment will work without
change with instances of the new subclass. If Banana
overrides any of Fruit's methods that are invoked by the
code fragment, dynamic binding will ensure that Banana's
implementation of those methods gets executed. This will be true even
though class Banana didn't exist when the code fragment
was written and compiled.
Thus, inheritance helps make code easier to change if the needed change involves adding a new subclass. This, however, is not the only kind of change you may need to make.
Changing the superclass interface
In an inheritance relationship, superclasses are often said to be
"fragile," because one little change to a superclass can ripple out and
require changes in many other places in the application's code. To be
more specific, what is actually fragile about a superclass is its
interface. If the superclass is well-designed, with a clean separation
of interface and implementation in the object-oriented style, any
changes to the superclass's implementation shouldn't ripple at all.
Changes to the superclass's interface, however, can ripple out and
break any code that uses the superclass or any of its subclasses.
What's more, a change in the superclass interface can break the code
that defines any of its subclasses.
For example, if you change the return type of a public method in class
Fruit (a part of Fruit's interface), you can
break the code that invokes that method on any reference of type
Fruit or any subclass of Fruit. In addition,
you break the code that defines any subclass of Fruit that
overrides the method. Such subclasses won't compile until you go and
change the return value of the overridden method to match the changed
method in superclass Fruit.
Inheritance is also sometimes said to provide "weak encapsulation,"
because if you have code that directly uses a subclass, such as
Apple, that code can be broken by changes to a superclass,
such as Fruit. One of the ways to look at inheritance is
that it allows subclass code to reuse superclass code. For
example, if Apple doesn't override a method defined in its
superclass Fruit, Apple is in a sense reusing
Fruit's implementation of the method. But
Apple only "weakly encapsulates" the Fruit
code it is reusing, because changes to Fruit's interface
can break code that directly uses Apple.
|
Sponsored Links
|