1. 程式人生 > >Java向上轉型與向下轉型(子類的物件賦給父類的)

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 plaincopyprint? 複製程式碼
 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:

  呼叫的成員:兒子屬性

三.向上轉型的作用:

    在父類有多個子類時,利用向上轉型減少重複程式碼量。