[英]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.