[英]Regarding Java subclasses inheriting methods that return “this”
有一個公共方法的類Car
public Car myself() {
return this;
}
有一個子類Ferrari
,以及一個包含Ferrari
對象的變量foo
。
最后,
Ferrari bar = foo.myself();
這會警告你,因為方法myself()
返回一個Car
對象,而不是預期的Ferrari
。
注意:我知道這個例子很愚蠢,因為你只需要做bar = foo
。 這只是一個例子。
解決方案:
Ferrari
的myself()
方法。 bar
時,將Car
對象轉換為Ferrari
對象。 兩種解決方案都有效,我對此感到滿意。 但是,當你有幾個Car
子類時,第一個是不可取的。 我覺得一遍又一遍地覆蓋一種方法會破壞繼承它的意義。 接下來,關於第二種解決方案,鑄造並不漂亮。 感覺很愚蠢 - 如果我的變量屬於Ferrari
,那么Java不應該在沒有警告我的情況下隱式地施放它嗎? 畢竟,Java必須知道返回的對象可以轉換為Ferrari
,不是嗎?
還有另一種解決方法嗎? 只是出於好奇 - 我可以忍受鑄造的東西,告訴Java應該是什么東西......
此解決方案以Java庫中更常用的方式使用泛型。
它有效,您不必每次都轉換結果,也不必在每個子類中覆蓋myself
方法。
我相信這是唯一不需要覆蓋或轉換的解決方案。 它確實要求每個子類使用自己的類型作為超類Car
的類型參數: class Ferrari extends Car<Ferrari>
class Car<X extends Car<X>> {
public X myself() {
return (X) this;
}
}
class Ferrari extends Car<Ferrari> {
}
然后按預期使用它:
Ferrari testarossa = new Ferrari().myself();
這個概念在Java標准庫中也以這種或那種方式使用了幾次:
java.lang.Enum
public abstract class Enum<E extends Enum<E>>
java.util.Comparable
public interface Comparable<T>
(當您實現class ShoeSize implements Comparable<ShoeSize>
時,您應該傳遞自己的類類型: class ShoeSize implements Comparable<ShoeSize>
)
方法鏈
對此也有很好的用處 - 有一種模式,有些人喜歡,允許方法鏈接。 這就是StringBuilder
作用: new StringBuilder().append("a").append("b").toString()
。 但是,支持方法鏈接的類通常很難進行子類化。 使用上面概述的方法可以在這種情況下進行子類化。
這也取決於你如何知道foo
變量。
如果你知道的話
Ferrari foo = new Ferrari();
那么一個被覆蓋的方法就像
class Ferrari extends Car {
@Override
public Ferrari myself() {
return this;
}
}
將允許你利用covaraince,你可以做到
Ferrari foo = new Ferrari();
Ferrari bar = foo.myself();
雖然可能沒有多少應用案例這是有道理的:當你已經知道它是法拉利時,你可以寫
Ferrari bar = foo;
當你只知道它時,情況就不同了
Car foo = new Ferrari();
然后你運氣不好:你不再知道運行時類型,無論如何你都要投。
(注意:當涉及到自引用泛型類型時,這種重寫方法以更具體的類型返回this
有一個真實的應用案例。這有時被稱為getThis技巧 )
關於你的陳述
感覺很愚蠢 - 如果我的變量屬於法拉利,那么Java不應該在沒有警告我的情況下隱式地施放它嗎? 畢竟,Java必須知道返回的對象可以轉換為法拉利,不是嗎?
這不是真的。 沒有人阻止你覆蓋像這樣的方法
class Ferrari extends Car {
@Override
public Car myself() {
return new Volkswagen();
}
}
然后演員陣容將不再有效
子類可以覆蓋基類方法,並且作為該合同的一部分表明它將返回特定類型。 這為類的用戶提供了清晰度,而期望用戶知道返回的類型並相應地投射它不會。 因此,覆蓋更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.