gpt4 book ai didi

java - 接口(interface)的骨架实现中的抽象方法

转载 作者:行者123 更新时间:2023-11-30 09:58:55 25 4
gpt4 key购买 nike

我正在重新阅读 Effective Java(第 2 版)第 18 项,prefer interfaces to abstract classes .在该项目中,Josh Bloch 提供了 Map.Entry<K,V> 的骨架实现示例。界面:

// Skeletal Implementation
public abstract class AbstractMapEntry<K,V>
implements Map.Entry<K,V> {
// Primitive operations
public abstract K getKey();
public abstract V getValue();

// ... remainder omitted
}

这个例子有两个问题:

  1. 为什么 getKey 和 getValue 在这里明确声明为抽象方法?它们是 Map.Entry 的一部分接口(interface),所以我看不出在抽象类中进行冗余声明的原因。
  2. 为什么要像 Bloch 先生所说的那样,将这些基本方法保留为抽象?为什么不这样做:

    //骨架实现公共(public)抽象类 AbstractMapEntry 实现 Map.Entry { 私钥; 私有(private)V值;

        // Primitive operations
    public K getKey() {return key;}
    public V getValue() {return value;}

    // ... remainder omitted

这样做的好处是每个子类都不必定义自己的字段集,并且仍然可以通过它们的访问器访问键和值。如果子类确实需要为访问器定义自己的行为,它可以直接实现 Map.Entry 接口(interface)。另一个缺点是,在骨架实现提供的 equals 方法中,调用了抽象访问器:

// Implements the general contract of Map.Entry.equals
@Override public boolean equals(Object o) {
if (o == this)
return true;
if (! (o instanceof Map.Entry))
return false;
Map.Entry<?,?> arg = (Map.Entry) o;
return equals(getKey(), arg.getKey()) &&
equals(getValue(), arg.getValue());
}

Bloch 警告不要从为继承而设计的类中调用可覆盖的方法(第 17 项),因为这会使父类(super class)容易受到子类所做更改的影响。也许这是一个见仁见智的问题,但我希望确定这个故事是否还有更多内容,因为 Bloch 并没有在书中详细说明这一点。

最佳答案

  1. 我会说它有助于强调具体类打算处理什么,而不是让编译器告诉你(或者你必须比较两者以查看缺少什么)。一种 self 记录的代码。但这当然没有必要,据我所知,它更像是一种风格。
  2. 与简单的 getter 和设置相比,返回这些值有更重要的逻辑。我在标准 JDK(1.5) 中抽查的每个类都至少在其中一种方法上做了一些不简单的事情,所以我猜他认为这样的实现太天真了,它会鼓励子类使用它而不是仔细考虑自己解决问题。

关于 equals 的问题,如果抽象类实现它们,则不会有任何改变,因为该问题是能够的。在这种情况下,我会说 equals 正在尝试谨慎实现以预测实现。由于协方差问题(父类(super class)会认为它等于子类,但子类不会认为它等于父类(super class)),通常不应该实现 equals 以在其自身及其子类之间返回 true(尽管有很多这样做) ,因此无论您做什么,这种 equals 的实现都是棘手的。

关于java - 接口(interface)的骨架实现中的抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/237140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com