1. 程式人生 > >java——向上轉型和向下轉型

java——向上轉型和向下轉型

Father f1 = new Son();   // 這就叫 upcasting (向上轉型)
// 現在 f1 引用指向一個Son物件

Son s1 = (Son)f1;   // 這就叫 downcasting (向下轉型)
// 現在f1 還是指向 Son物件
Father f2 = new Father();
Son s2 = (Son)f2;       // 出錯,子類引用不能指向父類物件

 f1 指向一個子類物件,Father f1 = new Son(); 子類 s1 引用可以指向子類物件。

而 f2 被傳給了一個 Father 物件,Father f2 = new Father(); 子類 s2 引用不能指向父類物件。

總結:

1、父類引用指向子類物件,而子類引用不能指向父類物件。

2、把子類物件直接賦給父類引用叫 upcasting 向上轉型,向上轉型不用強制轉換。

3、把指向子類物件的父類引用賦給子類引用叫向下轉型(downcasting),要強制轉換。

 

一.   向上轉型

1.  向上轉型中的方法呼叫

1:發生向上轉型後,子類獨有的方法是調用不了的

2:在發生向上轉型後,呼叫的方法和  new  的物件有關,呼叫的屬性和型別有關(static除外)

3:向上轉型,一個類既可以轉型為父類,也可以轉型為祖先類!

package com.zth;

class Animal {
  String name = "Animal";
  public void eat() {
    System.out.println("animal eating...");
  }
}

class Bird extends Animal  {
  String name = "brid";
  public void eat() {
    System.out.println("bird eating...");
  }
  public void fly() {
    System.out.println("bird flying...");
  }
}

public class Test{
  public static void main(String[] args) {
    Animal b = new Bird();
    System.out.println(b.name);
    b.eat();
    // b.fly();  報錯
  }
}

執行結果:

Animal
bird eating...

 

2、向上轉型的好處

以父類為引數,調有時用子類作為引數,就是利用了向上轉型。這樣使程式碼變得簡潔。

package com.zth;

class Human{
  public void sleep() {
    System.out.println("Human sleep...");
  }
}

class Male extends Human{
  @Override
  public void sleep() {
    System.out.println("Male sleep...");
  }
}

class Female extends Human{
  @Override
  public void sleep() {
    System.out.println("Female sleep...");
  }
  
}

public class Test{
  public static void dosleep(Human h) {
    h.sleep();
  }
  public static void main(String[] args) {
    dosleep(new Male());
    dosleep(new Female());
  }
}

執行結果:

Male sleep...
Female sleep...

 

二.  向下轉型

與向上轉型相反,即是把父類物件轉為子類物件。

package com.zth;

class Animal {
  String name = "Animal";
  public void eat() {
    System.out.println("animal eating...");
  }
}

class Bird extends Animal  {
  String name = "bird";
  public void eat() {
    System.out.println("bird eating...");
  }
  public void fly() {
    System.out.println("bird flying...");
  }
}

public class Test{
  public static void main(String[] args) {
    Animal b = new Bird();          // 向上轉型
    System.out.println(b.name);     // Animal
    b.eat();                        // bird eating...
    //b.fly();      error
    
    Bird b1 = (Bird)b;              // 向下轉型
    System.out.println(b1.name);    // bird
    b1.eat();                       // bird eating...
    b1.fly();                       // bird flying...
    
    Animal bb = new Animal();
    //Bird b2 = (Bird)bb; //不安全的向下轉型,編譯無錯但會執行會出錯
    
    if(bb instanceof Bird) {
      Bird b2 = (Bird)bb;
      System.out.println(b2.name);
      b2.eat();
    }
  }
}

三.  instanceof 關鍵字

instanceof 是 Java 的一個二元操作符,類似於 ==,>,< 等操作符。

instanceof 是 Java 的保留關鍵字。它的作用是測試它左邊的物件是否是它右邊的類的例項,返回 boolean 的資料型別。

package com.zth;

class Person{
  String name;
  int age;
public Person() {
    
  }
  public Person( String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  public boolean equals(Object obj) {
    if(obj  instanceof Person) {
      Person p1 = (Person) obj;
      return this.name.equals(p1.name)  && this.age == p1.age;
    }else {
      return false;
    }
  }
}

class Teacher extends Person{
  public Teacher(String name,int age) {
    this.name = name;
    this.age = age;
  }
}

public class Test1 {
  public static void main(String[] args) {
    
    Person p = new Person("zth",18);
    Teacher p1 = new Teacher("zth",18); 
    System.out.println(p.equals(p1));           // true
    System.out.println(p.equals("zth"));        // false
  }

}