[英]Mutable class as a child of an immutable class
我希望有這樣的不可變Java對象(強烈簡化):
class Immutable {
protected String name;
public Immutable(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
在某些情況下,對象不僅應該是可讀的而且是可變的,因此我可以通過繼承添加可變性:
public class Mutable extends Immutable {
public Mutable(String name) {
super(name);
}
public void setName(String name) {
super.name = name;
}
}
雖然這在技術上很好,我想知道它是否符合OOP和繼承,mutable也是類型不可變的。 我想避免OOP犯罪為不可變對象拋出UnsupportedOperationException
,就像Java collections API那樣。
你怎么看? 還有其他想法嗎?
避免調用父“不可改變的”,因為它成為了子類謊言-如果你想使一類不可變的,它應該是最后的太為了防止正是這個問題。
Joda Time使用“ReadableXXX”來表示“此類僅提供讀訪問權限;其他子類可能是可變的”。 我不確定我是否喜歡這個想法,但我不能說我見過很多選擇。
基本上問題在於表達否定 - Immutable
描述你不能做什么(改變它)並且不能在子類中明智地強制執行。 (即使Immutable
中的字段是最終的,它也不會阻止具有自己的可變字段的子類。)
我建議你應該有一個可繼承的基礎“ReadableFoo”類,一個派生的密封ImmutableFoo類,以及其他派生的MutableFoo類。 不關心Foo是否可變的代碼可以接受ReadableFoo。 想要保證不會改變的Foo的代碼可以接受ImmutableFoo。 需要更改Foo的代碼可以接受MutableFoo。
請注意,ImmutableFoo和MutableFoo的構造函數通常應該接受ReadableFoo。 這樣,任何Foo都可以轉換為可變或不可變的版本。
不可變類應該是final
以避免可變子類型。
允許不可變類的子類型來破壞不可變合同使得類首先成為不可變類是沒有意義的。 在Java允許你這樣做的意義上它可能是合法的(在語言中不強制實現不變性),但只要它可以被分類,這樣的類就不是真正不可變的。
這就是String是最終的原因。
您的子類很糟糕,因為它違反了Liskov替換原則 。 不要這樣做。
我覺得你的代碼很好奇。
為了實現這樣的不可變行為,我寧願依賴一個Immutable
接口,只提供getter方法,而對象包含兩者。 這樣,依賴於不可變對象的操作就會調用接口,而其他操作則會調用該對象。
而且,如果您真的不希望將不可變對象轉換為可變對象,則可以使用代理和所有企業工具(方面等)。 但通常情況下,依靠其他開發者的善意是讓他們對錯誤負責的一種甜蜜方式(比如將不可變的東西變成可變的)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.