亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

創建子類的兩種方法實際上是相同的?

創建子類的兩種方法實際上是相同的?

蝴蝶刀刀 2023-08-16 16:29:46
我是 Java 新手。我創建了一個超類和一個從它擴展的子類:class Car {    private String name;    private int wheels;    public Car(String name, int wheels) {        this.name = name;        this.wheels = wheels;    }}class Ford extends Car {    public Ford(String name, int wheels) {        super(name, wheels);    }}然后在 main 方法中我可以創建超類和子類的實例:  Car car = new Car("car", 4);   Ford ford = new Ford("ford", 6);   Car ford2 = new Ford("ford", 6);我只是想問一下,創建實例時以 Ford 開頭,還是以 Car 開頭,有什么區別嗎?正如您所看到的 ford 和 ford2 的創建方式不同。請注意,我知道 ford 和 ford2 不一樣,因為它們是具有不同指針的引用變量。我只是想知道它們創建的語法。謝謝編輯:我發現了差異,但不明白其背后的邏輯。如果您在 Car 類中有一個方法,您可以從 ford 和 ford2 調用它如果您在 Car 和 Ford 類中有一個同名的方法,您可以從 ford 和 ford2 調用它,并且它將調用子類中的方法如果您僅在 Ford 類中擁有一個方法,則無法從 ford2 中調用它 - 您將收到錯誤。我真的不明白為什么,ford2仍然是福特的一個實例
查看完整描述

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 Iterableover a” Collection、“prefer Collectionover a” List、“prefer Listover an” ArrayList。


查看完整回答
反對 回復 2023-08-16
?
不負相思意

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 超類的類型。


查看完整回答
反對 回復 2023-08-16
?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

我只是想問一下福特和福特2有什么區別嗎?或者它們完全一樣嗎?

最好的答案是:這取決于。

這取決于您所說的“相同”到底是什么意思。

在Java中,new需要操作符來創建一個新對象。因此,這兩個賦值會將新創建的對象分配給變量fordford2。這些對象將具有不同的引用,因此在 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相同的類型(即它們都是Fords)、相同的屬性,但不同的標識。如果如圖所示為類定義了值比較Ford,那么它們將具有相同的值,否則它們不會。


查看完整回答
反對 回復 2023-08-16
?
四季花海

TA貢獻1811條經驗 獲得超5個贊

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



查看完整回答
反對 回復 2023-08-16
?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

您可以調用Ford上的任何方法ford。

您可以調用Car上的任何方法ford2。


查看完整回答
反對 回復 2023-08-16
  • 5 回答
  • 0 關注
  • 207 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號