簡體   English   中英

多態性 - 方法覆蓋和重載不清楚

[英]Polymorphism - Method overriding and overloading not clear

我正在學習多態性,但無法理解它是如何工作的

當我嘗試創建 object Car car = new Audi(); ,覆蓋打印“這是奧迪”。 但是使用相同的 object 我無法先調用Audi class 的first(int x, int y) ... 我只能先調用Car class first()

覆蓋打印奧迪方法,重載打印汽車方法..使用相同的 object 調用時..

Class 汽車

class Car {
   public void carName() {
      System.out.println("Parent of car");
   }

   public int first() {
      System.out.println("Base - Parent");
      return 2;
   }
}

Class 寶馬

class BMW extends Car {
   public void carName() {
      System.out.println("This is BMW");
   }
   public int first(int x) {
      System.out.println("BMW override");
      return x;
   }
}

Class 奧迪

class Audi extends BMW {
   public void carName() {
      System.out.println("This is Audi");
   }
   public int first(int x, int y) {
      System.out.println("AUdi Override");
      return x;
   }
}

Class PloyMor

public class PolyMor extends Audi {
   public static void main(String args[]) {
      Car car = new Audi();
      car.carName();
      car.first();
   }
}

重要提示:我假設 class BTW擴展了Car而不是Audi (這在 IMO 中毫無意義)。


但是對於相同的 object,我無法調用奧迪 class 的第一個(int x,int y)。

您需要區分變量類型和(對象)類型。 的情況下

Car car = new Audi();

變量類型是Car而它持有的 object 類型是Audi

您需要意識到編譯器不會假設變量的值是什么。 它應用相同的規則,就好像它是方法的參數一樣

void someMethod(Car car){
    //do something with `car`
}

在該方法的內部,我們不知道它是否會與someMethod(new Audi());一起使用someMethod(new BMW()); .

那么哪些方法可以通過someMethod體內的car變量安全地調用呢? 只有那些保證所有可用作方法 arguments 的對象中實現(出現)的對象。 如果該方法可以讓我們編寫car.first(1, 2); 它適用於someMethod(new Audi())這樣的場景,但對於someMethod(new BMW())會失敗,因為 BMW 沒有first(int x, int y)方法。

調用方法取決於編譯類型而不是運行時類型。

Car car = new Audi();
^               ^
compile-type    runtime type

編譯類型與運行時類型: 來源

信用:@duffymo

假設我們有

A test = new B();
  • 在編譯時:編譯器只知道變量 test 的類型是 A。他不知道我們實際上給了他一個 B 的實例。因此 test 的編譯類型是 A。

  • 在運行時:測試類型已知為 B,因此運行時類型為 B

由於編譯器不知道在運行時將存儲什么類型,它只允許我們調用 Class A 的方法

解決方案:

如果你想從實例化類型調用方法,那么你將能夠首先訪問方法first(int x, int y)

Audi car = new Audi();
car.carName();
car.first(); // Original Method
car.first(3, 3); // Overloading

Output:

This is Audi
Base - Parent
AUdi Overload

PS 像 OldProgrammer 提到的奧迪應該擴展 Car 而不是 BMW

如果您在基礎 class 中定義了另一種方法,如下所示:

public int first(int a, int b) {
    System.out.println("Base - Parent");
    return 2;
}

As the final object you are trying to create is an object of class Car , it only has the methods from the Car class which if are present in Audi class, will override the methods in Car class.

您不會首先從Car in Audi覆蓋,因為簽名不同。

簽名包括方法名稱、參數和 throws 子句。

Car中的first()方法不使用 arguments。

Audi中,它需要兩個整數作為 arguments。 不一樣。

即使是簡單的層次結構也不是一個好的設計。 您遇到問題是因為您的實施很糟糕。

嘗試這個:

public abstract class Car {
    private String name;
    private int id;

    public Car(String name, int id) { 
        this.name = name;
        this.id = id;
    }

    public String getName() { return this.name; }
    public int getId() { return this.id; }

    public static void main(String [] args) {
        List<Car> cars = new ArrayList<>();
        cars.add(new Audi());
        cars.add(new Bmw());
        System.out.println(cars);
    }
}

class Audi extends Car {
    public Audi() {
        super("Audi", 1);
    }
}

class Bmw extends Car {
    public Bmw() {
       super("BMW", 2);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM