JAVA中的向上转型与向下转型

一:

一.定义:

通俗理解向上转型:

就是子类转型成父类。

  classA
  {
  }
  classBextendsA
  {
  }
  A b=new B();

  这个就是向上转型。

  向上转型可以像下面这条语句这么简单:

  Shape s =new Circle();

  这里,创建一个Circle对象,并把得到的引用立即赋值给S矇,这样做看似错误(将一种类型赋值给别一种类型);但实际上没有问题,因为通过继承,Circle就是一种Shape。因此,编译器认可这条语句,也就不会产生错误信息。

二.注意事项:

(1)向上转型的对象的引用调用的方法是子类的。

(2)但如果调用的方法父类中没有的话则会报错。(意思是只能调用子类中重载父类的方法)

(3)父类的引用可以指向子类的对象,但是子类的引用不能指向父类的对象。

java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象

什么叫父类引用指向子类对象,且听我慢慢道来.

从2个名词开始说起:向上转型(upcasting) 、向下转型(downcasting).

举个例子:有2个类,Father是父类,Son类继承自Father。

Father f1 = new Son(); // 这就叫 upcasting (向上转型)

// 现在f1引用指向一个Son对象

Son s1 = (Son)f1; // 这就叫 downcasting (向下转型)

// 现在f1还是指向Son对象

第2个例子:

Father f2 = new Father();

Son s2 = (Son)f2; // 出错,子类引用不能指向父类对象

你或许会问,第1个例子中:Son s1 = (Son)f1;问什么是正确的呢。

很简单因为f1指向一个子类对象,Father f1 = new Son(); 子类s1引用当然可以指向子类对象了。

而f2 被传给了一个Father对象,Father f2 = new Father();子类s1引用不能指向父类对象。

总结:

1。父类引用指向子类对象,而子类引用不能指向父类对象。

2。把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转换。

如:Father f1 = new Son();

3。把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换。

如:f1 就是一个指向子类对象的父类引用。把f1赋给子类引用s1即 Son s1 = (Son)f1;

其中f1前面的(Son)必须加上,进行强制转换。

现在再进一步变化,在父类和子类中同时定义和赋值同名的成员变量name,并试图输出该变量的值。

复制代码
 1 public class Father {  
 2   
 3   protected String name="父亲属性";  
 4     
 5   public void method() {  
 6     System.out.println("父类方法,对象类型:" + this.getClass());  
 7   }  
 8 }  
 9     
10 public class Son extends Father {  
11   protected String name="儿子属性";  
12     
13   public void method() {  
14     System.out.println("子类方法,对象类型:" + this.getClass());  
15   }  
16     
17   public static void main(String[] args) {  
18     Father sample = new Son();//向上转型   
19     System.out.println("调用的成员:"+sample.name);  
20   }  
21 }  
22 
23 public class Father {
24 
25   protected String name="父亲属性";
26   
27   public void method() {
28     System.out.println("父类方法,对象类型:" + this.getClass());
29   }
30 }
31   
32 public class Son extends Father {
33   protected String name="儿子属性";
34   
35   public void method() {
36     System.out.println("子类方法,对象类型:" + this.getClass());
37   }
38   
39   public static void main(String[] args) {
40     Father sample = new Son();//向上转型
41     System.out.println("调用的成员:"+sample.name);
42   }
43 }
44 
45 
46 
47 
48  
复制代码

结果3:

  调用的成员:父亲属性

这个结果表明,子类的对象(由父类的引用handle)调用到的是父类的成员变

现在试图调用子类的成员变量name,该怎么做?最简单的办法是将该成员变量封装成方法getter形式。

[c-sharp] view plain copy print ?
复制代码
 1 public class Father {  
 2   protected String name = "父亲属性";  
 3   public String getName() {  
 4     return name;  
 5   }  
 6   public void method() {  
 7     System.out.println("父类方法,对象类型:" + this.getClass());  
 8   }  
 9 }  
10     
11 public class Son extends Father {  
12   protected String name="儿子属性";  
13     
14   public String getName() {  
15     return name;  
16   }  
17     
18   public void method() {  
19     System.out.println("子类方法,对象类型:" + this.getClass());  
20   }  

21     
22   public static void main(String[] args) {  
23     Father sample = new Son();//向上转型   
24     System.out.println("调用的成员:"+sample.getName());  
25   }  
26 }  
27 
28 public class Father {
29   protected String name = "父亲属性";
30   public String getName() {
31     return name;
32   }
33   public void method() {
34     System.out.println("父类方法,对象类型:" + this.getClass());
35   }
36 }
37   
38 public class Son extends Father {
39   protected String name="儿子属性";
40   
41   public String getName() {
42     return name;
43   }
44   
45   public void method() {
46     System.out.println("子类方法,对象类型:" + this.getClass());
47   }
48   
49   public static void main(String[] args) {
50     Father sample = new Son();//向上转型
51     System.out.println("调用的成员:"+sample.getName());
52   }
53 }
54 
55 
56 
57  
复制代码

结果4:

  调用的成员:儿子属性

三.向上转型的作用:

在父类有多个子类时,利用向上转型减少重复代码量。



二:搜啦个容易理解的例子


class   Chinese   

   class    Guangdongren    extends    Chinese {   
          
public   static   void   print(){   
                  System.out.println(
"this   is   广东人   ");   
          }
   
            
  }
   
  
class    HunanRen    extends    Chinese {   
          
public   static   void   print(){   
                  System.out.println(
"this   is   湖南人   ");   
          }
   
  }
   
  
class    GuangzhouRen    extends    Guangdongren {   
          
public   static   void   print(){   
                  System.out.println(
"this   is   广州人     ");   
          }
   
  }
   
    
  
public     class    Test    {   
            
            
public   static   void   main(String   args[]){   
                      
                    Chinese   c
=new   Chinese();//这样编译可以通过,但运行会抛出异常   
                      HunanRen   h=(HunanRen)c;//     这是因为向下转型错误,中国人不一定是湖南人,这里   
                                                                    
//是不是可以这样理解要将c强制转换成一个HunanRen     
                      
                    HunanRen   h
=new   HunanRen();//这样就没有问题,这是向上转型,   
                    Chinese   c=(Chinese)h;         //湖南人一定是中国人这是是否可以理解为将h转换成Cinese   
                Chinaese   h=new   HunanRen();//向上转型   
                    h.print();   
            }
   
      }
   
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值