如果我有AddressBook
来存储Items
:
public class AddressBook {
public void add(Item item) {
...
}
}
一个不可变的IPAddress
public final class IPAddress {}
一个不可变的PhysicalAddress
public final class PhysicalAddress {}
潜在的父类Item
public final class Item {}
由于不可变对象无法扩展不可变类Item
,如何在add
类中重用AddressBook
方法来IPAddress
还是PhysicalAddress
?
答案 0 :(得分:2)
首先,您需要注意Java中的“最终类”并不意味着不可变,它意味着“不可继承”。使用“final”关键字的不变性仅适用于变量(并且仅在设置其初始值之后)。
如果您希望Item不可继承(最终类),并且您还希望IPAddress和PhysicalAdress也是最终的,则可以使用接口。 (编辑:这两个类不是最终的要求,只是要注意你可以保留它们,如果你真的需要,尽管其他人评论你应该确定你需要它是最终的)。
您可以将Item更改为接口,并使IPAddress和PhysicalAddress实现该接口。
这样AdressBook实际上添加了类型为“ItemInterface”的对象(糟糕的助记符,但你明白了),只要你设法抽象所有Items的常用操作,就可以使用接口而不是继承。
e.g。
public interface ItemInterface{
public Object getItemValue();
public void setItemValue(Object value);
}
public final class IPAddress implements ItemInterface{
@Override
public Object getItemValue(){
...
}
@Override
public void setItemValue(Object value){
...
}
}
然后你可以这样做:
public class AddressBook {
public void add(ItemInterface item) {
itemsList.add(item);
// or whatever other structure you use to store items
}
}
一般情况下,随着您开发越来越复杂的代码,{I}变得更有用to program to an interface而不是继续使用继承。
这样,无论何时需要向AddressBook添加其他类型的条目,都可以使其实现ItemInterface,理想情况下,您不必更改AddressBook中的一行,因为所有内容都是ItemInterface。
答案 1 :(得分:0)
我认为,你可能混淆了不可变的和最终的类
不可变对象意味着它在创建后无法更改。看到 https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
确实,最后一堂课不能被束缚。如果你真的想要继承类,它就不是最终的。
但重点是,不可变类不必是最终的。
答案 2 :(得分:0)
将类标记为final表示无法扩展。这基本上意味着你认为这个类是完美的,没有人会需要(或能够)扩展它或覆盖它在更具体的子类中的任何行为。
一般来说,除非你有充分的理由使用它们,否则你应该避免使用最终的类。
因为你不能扩展最终的类,所以它永远不能在继承层次结构中的任何地方使用,除非在最底层。
你确定你真的想让你的课程成为最终的吗?