通过不可变继承重用方法

时间:2015-09-03 16:49:27

标签: java

如果我有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

3 个答案:

答案 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表示无法扩展。这基本上意味着你认为这个类是完美的,没有人会需要(或能够)扩展它或覆盖它在更具体的子类中的任何行为。

一般来说,除非你有充分的理由使用它们,否则你应该避免使用最终的类。

因为你不能扩展最终的类,所以它永远不能在继承层次结构中的任何地方使用,除非在最底层。

你确定你真的想让你的课程成为最终的吗?