Inheritance: reusing the interface | CodeGuru

Inheritance: reusing the interface

Bruce Eckel’s Thinking in Java Contents | Prev | Next reusing the interface By itself, the concept of an object is a convenient tool. It allows you to package data and functionality together by concept, so you can represent an appropriate problem-space idea rather than being forced to use the idioms of the underlying machine. […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
4 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

reusing
the interface

By


itself, the concept of an object is a convenient tool. It allows you to package


data and functionality together by


concept

,


so you can represent an appropriate problem-space idea rather than being forced


to use the idioms of the underlying machine. These concepts are expressed in


the primary idea of the programming language as a data type (using the


class

keyword).

It


seems a pity, however, to go to all the trouble to create a data type and then


be forced to create a brand new one that might have similar functionality.


It’s nicer if we can take the existing data type, clone it and make


additions and modifications to the clone. This is effectively what you get with


inheritance

,


with the exception that if the original class (called the


base

or


super

or


parent

class) is changed, the modified “clone” (called the


derived

or


inherited

or


sub

or


child

class)


also reflects the appropriate changes. Inheritance is implemented in Java with


the


extends

keyword. You make a new class and you say that it


extends

an existing class.

When


you inherit you create a new type, and the new type contains not only all the


members of the existing type (although the


private

ones are hidden away and inaccessible), but more importantly it duplicates the


interface of the base class. That is, all the messages you can send to objects


of the base class you can also send to objects of the derived class. Since we


know the type of a class by the messages we can send to it, this means that the


derived class


is
the same type as the base class

.


This type equivalence via inheritance is one of the fundamental gateways in


understanding the meaning of object-oriented programming.

Since


both the base class and derived class have the same interface, there must be


some implementation to go along with that interface. That is, there must be a


method to execute when an object receives a particular message. If you simply


inherit a class and don’t do anything else, the methods from the


base-class interface come right along into the derived class. That means


objects of the derived class have not only the same type, they also have the


same behavior, which doesn’t seem particularly interesting.

You


have two ways to differentiate your new derived class from the original base


class it inherits from. The first is quite straightforward: you simply add


brand new functions to the derived class. These new functions are not part of


the base class interface. This means that the base class simply didn’t do


as much as you wanted it to, so you add more functions. This simple and


primitive use for inheritance is, at times, the perfect solution to your


problem. However, you should look closely for the possibility that your base


class might need these additional functions.


Overriding
base-class functionality

Although


the


extends

keyword implies that you are going to add new functions to the interface,


that’s not necessarily true. The second way to differentiate your new


class is to


change

the behavior of an existing base-class function. This is referred to as


overriding

that function.

To


override a function, you simply create a new definition for the function in the


derived class. You’re saying “I’m using the same interface


function here, but I want it to do something different for my new type.”


Is-a
vs. is-like-a relationships

There’s


a certain debate that can occur about inheritance: Should inheritance override


only

base-class functions? This means that the derived type is


exactly

the same type as the base class since it has exactly the same interface. As a


result, you can exactly substitute an object of the derived class for an object


of the base class. This can be thought of as


pure
substitution

.


In a sense, this is the ideal way to treat inheritance. We often refer to the


relationship between the base class and derived classes in this case as an


is-a

relationship, because you can say “a circle


is
a

shape.” A test for inheritance is whether you can state the is-a


relationship about the classes and have it make sense.

There


are times when you must add new interface elements to a derived type, thus


extending the interface and creating a new type. The new type can still be


substituted for the base type, but the substitution isn’t perfect in a


sense because your new functions are not accessible from the base type. This


can be described as an


is-like-a

relationship; the new type has the interface of the old type but it also


contains other functions, so you can’t really say it’s exactly the


same. For example, consider an air conditioner. Suppose your house is wired


with all the controls for cooling; that is, it has an interface that allows you


to control cooling. Imagine that the air conditioner breaks down and you


replace it with a heat pump, which can both heat and cool. The heat pump


is-like-an

air conditioner, but it can do more. Because your house is wired only to


control cooling, it is restricted to communication with the cooling part of the


new object. The interface of the new object has been extended, and the existing


system doesn’t know about anything except the original interface.

When


you see the substitution principle it’s easy to feel like that’s


the only way to do things, and in fact it is nice if your design works out that


way. But you’ll find that there are times when it’s equally clear


that you must add new functions to the interface of a derived class. With


inspection both cases should be reasonably obvious.


Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.