繁体   English   中英

通过不可变继承重用方法

[英]reuse methods through immutable inheritance

如果我有一个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 ,因此如何在AddressBook类中为IPAddressPhysicalAddress重用add方法?

首先,您需要意识到Java中的“最终类”并不意味着不可变,而是“不可继承”。 使用“ final”关键字的不可变性仅适用于变量(且仅在设置其初始值之后)。

如果希望Item是不可继承的(最终类),并且还希望IPAddress和PhysicalAdress也是最终的,则可以使用接口。 (编辑:这两个类不是最终的要求,只是想指出的是,您可以根据需要将它们保持为最终状态,尽管正如其他人评论的那样,您应该确保将其最终确定)。

您可以将Item更改为接口,并使IPAddress和PhysicalAddress实现该接口。

这样,AdressBook实际上会添加类型为“ ItemInterface”的对象(助记符不好,但您会明白),只要您设法对所有Items进行通用操作抽象,就可以使用接口代替继承。

例如

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
    }
}

通常,随着开发越来越复杂的代码,对接口进行编程比尝试继续使用继承变得更加有用。

这样,每当需要在地址簿中添加另一种类型的条目时,都可以使其实现ItemInterface,并且理想情况下,您不必在AddressBook中更改一行,因为所有内容都是ItemInterface。

我认为,您可能混合了不可变的课程和期末课程

不可变对象表示创建后无法更改。 参见https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

诚然,不能继承最终班级。 如果您真的想要继承类,那么它不能是最终的。

但关键是,不可变的类不必是最终的。

将一个类标记为final表示无法扩展。 从根本上讲,这意味着您认为该类是完美的,并且没有人将需要(或能够)扩展它或覆盖更具体的子类中的任何行为。

一般来说,除非有充分的理由使用final类,否则应避免使用final类。

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

您确定您确实要使课程最终结业吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM