【问题标题】:Inheriting specifid methods in java在java中继承特定的方法
【发布时间】:2019-06-01 12:40:48
【问题描述】:

在java中是否可以从基类继承一些方法,但不是全部?为了清楚起见,我将向您展示我的意思: 假设我们有基类 Visitor

public abstract class Visitor {}

我们从访问者创建了另外 2 个对象,客户端和同伴:

public class Client extends Visitor {}
public class Companion extends Visitor {}

在客户端,我们创建方法:

boolean has_Companion() {}

为了实现运行时多态,我们还需要在Visitor中声明方法:

abstract boolean has_Companion();

问题在于,由于我们在 Visitor 中声明了该方法,因此 Companion 也继承了它。我们不希望那样。编译时出现以下错误:

Companion 类型必须实现继承的抽象方法 Visitor.has_Companion()

为 Companion 实现方法 has_Companion() 没有意义,因为它永远不会被使用。这是对代码的浪费。我可以以某种方式避免它吗? has_Companion() 方法只能被Client继承,不能被Companion继承吗?

【问题讨论】:

  • 您不必在超类中将方法声明为抽象。或者创建一个接口而不是超类,并让方法在接口中有一个默认实现
  • 方法 has_Companion() 是否只能由 Client 继承,而不能由 Companion 继承? 。有一个 Visitor 是没有意义的,其中该方法仅在 一些 子类中可用。
  • 您自相矛盾:首先您说要实现多态性,这意味着客户端代码必须能够知道访问者是否有同伴而不知道访问者是客户端还是同伴,并且那么你说 has_Companion() 永远不会在 Companion 上被调用。如果它永远不会在 Companion 上调用,则意味着客户端代码知道访问者是客户端,因此您不需要在访问者中声明它。
  • @JBNizet 我明白了。也许我还没有理解多态的含义。在我的项目中,我有一个访客类型的列表,其中包含客户和同伴。从我的实现中,我知道我什么时候有客户或同伴,但变量是访客类型。我想通过 Visitor 变量调用 has_Companion(),这实际上是一个客户端。这不就是多态吗?
  • 当然,但是您怎么知道访问者是客户,而不是同伴?如果你知道,为什么不直接使用((Client) visitor).hasCompanion()

标签: java inheritance methods abstract run-time-polymorphism


【解决方案1】:

简短的回答是 Java 不支持您正在尝试做的事情,但好消息是有很多方法可以解决它。

想法 1:让 Companion 覆盖 hasCompanion 并始终返回 false

想法2:让Visitor 提供hasCompanion 的实现,它总是简单地返回false。然后客户端会用实际逻辑覆盖hasCompanion,以确定客户端是否有同伴。

想法3:根本不要给Visitor一个hasCompanion方法,而是只给Client中的方法。然后代码通过instanceof 运算符进行运行时类型检查,并通过强制转换调用Client 上的方法。示例:

if (visitor instanceof Client) {
    Client client = (Client) visitor;
    boolean hasCompanion = client.hasCompanion();
    // other logic
}

这充其量是假的多态性,也是一个非常笨拙的解决方案。如果可能,我建议不要这样做。

想法 4:重新考虑设计并重构类型树以及代码如何使用继承。如果在Companion extends Visitor 上调用hasCompanion 没有任何意义,那为什么hasCompanionVisitor 的方法呢?

Java不支持多重继承,所以需要接口:

public interface MightHaveCompanion {
    public boolean hasCompanion();
}

public abstract class Visitor {
    // methods that all Visitors must have
}

public class Client extends Visitor implements MightHaveCompanion {
    // overriding implementations of MightHaveCompanion and Visitor methods 
}

public class Companion extends Visitor {
    // overriding implementations of Visitor methods
}

然后调用代码必须根据需要更改为使用MightHaveCompanionVisitor 类型。很清楚哪些方法属于哪些类型。毫无疑问,在较大的项目中,执行此操作的工作量会扩展,但可能会导致代码更简洁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 2017-12-22
    相关资源
    最近更新 更多