Talk About“Upcasting”

 
Talk About“Upcasting”
                                                
The most important aspect of inheritance is not that it provides methods for the new class. It’s the relationship expressed between the new class and the base class. This relationship can be summarized by saying, “The new class is a type of the existing class.”
This description is not just a fanciful way of explaining inheritance—it’s supported directly by the language. As an example, consider a base class called Human that represents musical Humans, and a derived class called Boy. Because inheritance means that all of the methods in the base class are also available in the derived class, any message you can send to the base class can also be sent to the derived class. If the Human class has a sleep( ) method, so will Boy Humans. This means we can accurately say that a Boy object is also a type of Human. The following example shows how the compiler supports this notion:
//file:Human.java
 Inheritance & upcasting.
import java.util.*;
 
class Human {
 public void sleep() {}
 static void breathe(Human h) {
    // ...
    h.sleep();
 }
}
 
// Boy objects are Humans
// because they have the same interface:
public class man extends Human {
 public static void main(String[] args) {
    man boy = new man();
    Human.breathe(boy); // Upcasting
 }
} ///:~
 
What’s interesting in this example is the breathe( ) method, which accepts an Human reference. However, in Boy. main( ) the breathe( ) method is called by giving it a Boy reference. Given that Java is particular about type checking, it seems strange that a method that accepts one type will readily accept another type, until you realize that a Boy object is also an Human object, and there’s no method that breathe( ) could call for an Human that isn’t also in Boy. Inside breathe( ), the code works for Human and anything derived from Human, and the act of converting a Boy reference
Why “upcasting”?
The reason for the term is historical, and based on the way class inheritance diagrams have traditionally been drawn: with the root at the top of the page, growing downward. (Of course, you can draw your diagrams any way you find helpful.) The inheritance diagram for Boy.java is then:

human
man

        
Casting from a derived type to a base type moves up on the inheritance diagram, so it’s commonly referred to as upcasting. Upcasting is always safe because you’re going from a more specific type to a more general type. That is, the derived class is a superset of the base class. It might contain more methods than the base class, but it must contain at least the methods in the base class. The only thing that can occur to the class interface during the upcast is that it can lose methods, not gain them. This is why the compiler allows upcasting without any explicit casts or other special notation.
In last Contens you saw how an object can be used as its own type or as an object of its base type. Taking an object reference and treating it as a reference to its 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 example about class Human. Since several examples has there skinColor, we should create the color class separately, in a package:
//: Human:color.java
// EveryOne has there skinColor
package myApp.human;
 
public class color {
 private String colorName;
 private color(String colorName) {
    this.colorName = colorName;
 }
 public String toString() { return noteName; }
 public static final color
    BLACK = new color("black man"),
    WHITE = new color("white man"),
    YELLO   = new Note("yello man");
    // Etc.
} ///:~
 
This is an “enumeration” class, which has a fixed number of constant objects to choose from. You can’t make additional objects because the constructor is private.
In the following example, man is a type of Human, therefore man is inherited from Human:
//: organism.java
// Inheritance & upcasting.
Package myApp.Human;
 
 
public class organism {
 public static void breathe(Human h) {
    // ...
    h.skin(color.BLACK);
 }
 public static void main(String[] args) {
    man m = new man();
    breathe(m); // Upcasting
   
    });
 }
} ///:~
 
//: man.java
package myApp.human;
 
public class man extends Human {
 // Redefine interface method:
  public void skin(color c) {
    System.out.println("man.skin() " + c);
 }
} ///:~
 
//: organism.java
// Inheritance & upcasting.
package myApp.human;
 
public class organism {
 
  public static void breathe(human h) {
    // ...
    h.skin(color.WHITE);
 }
 public static void main(String[] args) {
    man m = new man();
    breathe(m); // Upcasting
 
  }
} ///:~
 
The method organism .breathe( ) accepts an Human reference, but also anything derived from Human. In main( ), you can see this happening as a Man reference is passed to breath( ), with no cast necessary. This is acceptable—the interface in Human must exist in Man, because Man is inherited from Human. Upcasting from Man to Human may “narrow” that interface, but it cannot make it anything less than the full interface to Human.
 
when shall we use INHERITANCE?
In object-oriented programming, the most likely way that you’ll create and use code is by simply packaging data and methods together into a class, and using objects of that class. You’ll also use existing classes to build new classes with composition. Less frequently, you’ll use inheritance. So although inheritance gets a lot of emphasis while learning OOP, it doesn’t mean that you should use it everywhere you possibly can. On the contrary, you should use it sparingly, only when it’s clear that inheritance is useful. One of the clearest ways to determine whether you should use composition or inheritance is to ask whether you’ll ever need to upcast from your new class to the base class. If you must upcast, then inheritance is necessary, but if you don’t need to upcast, then you should look closely at whether you need inheritance,  if you remember to ask “Do I need to upcast?” you’ll have a good tool for deciding between composition and inheritance.
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值