5 回答

TA貢獻1790條經驗 獲得超9個贊
到目前為止,我真的不喜歡這些答案。他們正在把簡單的事情變得復雜起來。
變量只是一個引用的持有者。
正如您從示例中看到的,變量的類型不必與其所保存的引用的確切類型相匹配。該變量只需等于或比其引用更通用(或者,如果您愿意,等于或不那么具體)。Car
比 更通用Ford
,因此該分配是可以的。
每個引用都可以由變量保存Object
,因為這是Java 中存在的最通用的類型。
Object foo = new Car(1, 6);Object bar = "hello world";
現在,使用這些變量的困難在于我們只能調用類中的方法Object
。通過將變量聲明為Object
,當我嘗試訪問內容時,我只能使用方法,無論Object
其中實際存儲了什么。
Object
(例如)有幾個方法toString
,所以這可能沒問題,但在大多數情況下分配給Object
并不是很有用。
因此,我們對變量越具體,我們可能訪問的功能就越多。
當你說
Car car = new Ford("ford", 6);
當從此變量引用它時,我們可能無法訪問一些福特特定的功能。我們總是可以稍后通過強制轉換實例來解決這個問題,但除非絕對必要,否則應該避免這樣做。
然而,我們越通用,我們的代碼就越靈活。如果一個方法只以福特汽車作為參數,那是相當有限制的。如果可以取任何一輛車作為參數,那就更加靈活了。
一般來說,在為變量選擇正確的類型時,您可以在心里盡可能地從最通用的類型開始,然后不斷使其變得更加具體,直到它適合您的用例。
例如,如果您可以選擇“prefer Iterable
over a” Collection
、“prefer Collection
over a” List
、“prefer List
over an” ArrayList
。

TA貢獻1777條經驗 獲得超10個贊
Ford ford = new Ford("ford", 6); Car ford2 = new Ford("ford", 6);
兩個對象變量都引用福特類對象。但對象變量的類型不同。就像福特是福特的類型,但福特2是汽車的類型。
它被稱為概括對象創建。始終建議概括對象引用創建,因為您可以通過分配繼承相同超類的不同類型的子類來更改對象引用類型。
除此之外,下面提到的差異也是一個有用的情況。
Car car = new Car("car", 4);
該汽車對象只能訪問 Car 類方法。
Ford ford = new Ford("ford", 6);
該對象可以訪問兩個類的所有方法。但是假設你在兩個類中都有如下所示的 1 個方法
public static void a(){ system.out.println("static method"); }
如果福特對象調用方法a()。它將運行子類中存在的方法。因為 Ford 變量是 Ford 子類的類型。
Car ford2 = new Ford("ford", 6);
該對象可以訪問兩個類的所有方法。但是假設你在兩個類中都有如下所示的 1 個方法
public static void a(){ system.out.println("static method"); }
如果福特對象調用方法a()。它將運行超類中存在的方法。因為 ford2 變量是 Ford 超類的類型。

TA貢獻1794條經驗 獲得超8個贊
我只是想問一下福特和福特2有什么區別嗎?或者它們完全一樣嗎?
最好的答案是:這取決于。
這取決于您所說的“相同”到底是什么意思。
在Java中,new
需要操作符來創建一個新對象。因此,這兩個賦值會將新創建的對象分配給變量ford
和ford2
。這些對象將具有不同的引用,因此在 JVM 中具有不同的標識。結果,以下內容將評估為false
:
boolean b = (ford == ford2);
然而,這兩個對象可以說具有相同的屬性,因為它們的實例字段包含相同的值。就目前而言,該表達式的計算結果也為false
:
boolean b = (ford.equals(ford2));
equals()
因為從Object
分配變量的兩種類型(即Car
和)繼承的默認方法Ford
執行與上一條語句中評估的相同的引用比較。如果類equals()
中的方法Ford
被重寫以執行值比較(而不是默認的引用比較),如下所示:
@Override boolean equals(Object ob) { if (!(ob instanceof Ford)) return false; Ford f = (Ford) ob; return this.name.equals(f.name) && this.wheels == f.wheels; }
那么下面的表達式將計算為true
:
boolean b = ford.equals(ford2);
TL;DR:變量引用的對象ford
具有ford2
相同的類型(即它們都是Ford
s)、相同的屬性,但不同的標識。如果如圖所示為類定義了值比較Ford
,那么它們將具有相同的值,否則它們不會。

TA貢獻1811條經驗 獲得超5個贊
從技術上講,它們不一樣 -==
會給出false
- 但它們保存相同的數據(不一樣意味著修改一個不會影響另一個)并且它們是相同的類型。但是,您只能通過將ford2
其強制轉換來調用僅在Ford
類中定義的方法(如果有的話)Ford
(在這種狀態下,ford2
您只能調用Car
的方法)。
添加回答
舉報