Upcasting | CodeGuru

Upcasting

Bruce Eckel’s Thinking in Java Contents | Prev | Next In Chapter 6 you saw how an object can be used as its own type or as an object of its base type. Taking an object handle and treating it as the handle of the base type is called upcasting because of the way inheritance […]

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

In


Chapter 6 you saw how an object can be used as its own type or as an object of


its base type. Taking an object handle and treating it as the handle of the


base type is called


upcasting

because of the way inheritance trees are drawn with the base class at the top.

You


also saw a problem arise, which is embodied in the following: (See page


97

if you have trouble executing this program.)

//: Music.java 
// Inheritance & upcasting
package c07;
 
class Note {
  private int value;
  private Note(int val) { value = val; }
  public static final Note
    middleC = new Note(0),
    cSharp = new Note(1),
    cFlat = new Note(2);
} // Etc.
 
class Instrument {
  public void play(Note n) {
    System.out.println("Instrument.play()");
  }
}
 
// Wind objects are instruments
// because they have the same interface:
class Wind extends Instrument {
  // Redefine interface method:
  public void play(Note n) {
    System.out.println("Wind.play()");
  }
}
 
public class Music {
  public static void tune(Instrument i) {
    // ...
    i.play(Note.middleC);
  }
  public static void main(String[] args) {
    Wind flute = new Wind();
    tune(flute); // Upcasting
  }
} ///:~ 

The


method


Music.tune( )

accepts an


Instrument

handle,


but also anything derived from


Instrument

.


In


main( )

,


you can see this happening as a


Wind

handle is passed to


tune( )

,


with no cast necessary. This is acceptable; the interface in


Instrument

must exist in


Wind

,


because


Wind

is inherited from


Instrument

.


Upcasting from


Wind

to


Instrument

may “narrow” that interface, but it cannot make it anything less


than the full interface to


Instrument

.

Why
upcast?

This


program might seem strange to you. Why should anyone intentionally


forget

the type of an object? This is what happens when you upcast, and it seems like


it could be much more straightforward if


tune( )

simply takes a


Wind

handle as its argument. This brings up an essential point: If you did that,


you’d need to write a new


tune( )

for every type of


Instrument

in your system. Suppose we follow this reasoning and add


Stringed

and


Brass

instruments:

//: Music2.java 
// Overloading instead of upcasting
 
class Note2 {
  private int value;
  private Note2(int val) { value = val; }
  public static final Note2
    middleC = new Note2(0),
    cSharp = new Note2(1),
    cFlat = new Note2(2);
} // Etc.
 
class Instrument2 {
  public void play(Note2 n) {
    System.out.println("Instrument2.play()");
  }
}
 
class Wind2 extends Instrument2 {
  public void play(Note2 n) {
    System.out.println("Wind2.play()");
  }
}
 
class Stringed2 extends Instrument2 {
  public void play(Note2 n) {
    System.out.println("Stringed2.play()");
  }
}
 
class Brass2 extends Instrument2 {
  public void play(Note2 n) {
    System.out.println("Brass2.play()");
  }
}
 
public class Music2 {
  public static void tune(Wind2 i) {
    i.play(Note2.middleC);
  }
  public static void tune(Stringed2 i) {
    i.play(Note2.middleC);
  }
  public static void tune(Brass2 i) {
    i.play(Note2.middleC);
  }
  public static void main(String[] args) {
    Wind2 flute = new Wind2();
    Stringed2 violin = new Stringed2();
    Brass2 frenchHorn = new Brass2();
    tune(flute); // No upcasting
    tune(violin);
    tune(frenchHorn);
  }
} ///:~ 

This


works, but there’s a major drawback: You must write type-specific methods


for each new


Instrument2

class you add. This means more programming in the first place, but it also


means that if you want to add a new method like


tune( )

or a new type of


Instrument

,


you’ve got a lot of work to do. Add the fact that the compiler


won’t give you any error messages if you forget to overload one of your


methods and the whole process of working with types becomes unmanageable.

Wouldn’t


it be much nicer if you could just write a single method that takes the

base
class as its argument, and not any of the specific derived classes? That is,
wouldn’t it be nice if you could forget that there are
derived
classes, and write your code to talk only to the base class?

That’s


exactly what polymorphism allows you to do. However, most programmers (who come


from a procedural programming background) have a bit of trouble with the way


polymorphism works.


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.