麻烦理解来自'Effective Java'的关于compareTo的摘录

时间:2013-07-21 17:22:16

标签: java oop object compareto

这是关于类可以实现的compareTo契约。

  

无法使用新值扩展可实例化的类   组件,同时保留compareTo合同,除非你是   愿意放弃面向对象抽象的好处。相同   解决方法也适用。如果要向a添加值组件   实现Comparable的类,不要扩展它;写一个无关的   包含第一个类的实例的类。然后提供一个“视图”   返回此实例的方法。这使您可以实现   无论你喜欢什么比较你喜欢的第二课,同时允许   它的客户端将第二个类的实例视为一个实例   需要时的第一堂课。

我看过Why can't I extend an instantiable class with a new value component while preserving the compareTo contract?。它帮助回答了我的一两个问题。但是下面的问题对我来说仍然没有答案。

1)如果我将两个类定义为无关,我可以随心所欲地实现compareTo方法。但是我知道如何使这两个类具有is-a / parent-child关系。可以有人解释约书亚所说的"观察"方法

1 个答案:

答案 0 :(得分:4)

  

有人可以解释约书亚所谓的“观察”方法吗?

我将从answer that you linked in your post

继续Jon Skeet的简单示例
// In Jon's code, Person derives from NamedThing
class NamedThing {
    String name;
}

class Person extends NamedThing {
    Date dateOfBirth;
}

“提供视图”而不是“扩展”意味着设计类层次结构如下:

class NamedThing {
    String name;
}

class Person {
    private  NamedThing namedThing;
    // Here is the view method
    public NamedThing asNamedThing() {
        return namedThing;
    }
    // Here is a convenience method for accessing name directly
    public String getName() {
        return namedThing.name;
    }
    Date dateOfBirth;
}

这使您可以在compareTo内部实现新的Person,因为不需要与超类保持兼容。如果您需要以NamedThing身份查看自己的人,请致电asNamedThing()以查看被裁减为具有姓名的人的人。

请注意,由于这不是一个is-a关系,asNamedThing有点误导:你在个人内部获得了命名的东西,而不是恰好是命名的东西。这限制了compareTo的适用性:例如,您无法在其他NamedThing中对人进行排序。