【问题标题】:Using subclass' method in superclass在超类中使用子类的方法
【发布时间】:2013-07-25 21:15:29
【问题描述】:

我有一个扩展 SuperClass 并实现 IClass 的类(为简单起见称为 SubClass)。 我知道你可以使用 super.method() 调用 SuperClass 的方法,但是是否可以从 IClass 中实现的 SubClass 中调用方法?

例子:

public class SuperClass {

    public void method(){

        implementedMethod();

    }

}

子类:

public class SubClass extends SuperClass implements IClass{

    public void implementedMethod() {

        System.out.println("Hello World");

    }

}

IClass:

public interface IClass {

    public void implementedMethod();

}

我想从 SuperClass 调用 SubClass'impliedMethod()(它从 IClass 获得)

我该怎么做呢?

【问题讨论】:

  • 如果您需要从超类调用子类方法,您的 is-a 关系可能存在设计问题。
  • 我不明白你的问题,你想达到什么目的?如果你有一些抽象的超类类型,你想选择哪个子类将执行?
  • 用例是什么?为什么你会想要从超类调用子类的方法,而该方法不是抽象的,因此保证存在于子类中?

标签: java inheritance interface subclass superclass


【解决方案1】:

调用该方法的唯一方法是创建一个 SubClass 类型的对象(在 SuperClass 中)并调用 subClassInstance.implementedMethod()。

我还想强调这是非常不雅的。正如对您的问题的评论中所述,如果您的超类需要调用子类方法,您应该重新考虑您的类设计。

【讨论】:

  • 一个新的子类实例不需要需要在超类中创建。虽然通常是不可取的,但这会“工作”:class SuperClass { void ick() { ((IClass)this).implementedMethod(); } .. } .. new SubClass().ick()。在这种情况下,虽然 ick 方法(在 SuperClass 中定义,但在 SubClass 的实例上调用)要求当前实例符合特定的 Type(此处为 IClass),否则转换将失败。
  • (请注意,在我之前的评论/示例中,有 no 类型的子类对象“在超类中创建 ..”。对象的实际类型和对象的类型作为所述对象的视图的表达式可以不同。)
【解决方案2】:

你可以让超类抽象:

public abstract class SuperClass implements IClass {
    public void method(){
        implementedMethod();
    }
}

【讨论】:

  • @tbodt 为什么不呢?这似乎正是他想要做的。
【解决方案3】:

鉴于上述类型,必须使用anExpressionOfTypeSubClassOrIClass.implementedMethod()。请注意,表达式的类型 - 它提供的视图 - 必须具有要使用的方法。在这种情况下,这里不能使用 SuperClass 类型的表达式,因为它没有声明的 implementedMethod 成员。

一种方法(可以说是首选方法)是使用abstract methods。尽管Polymorphism 并不严格要求抽象方法,但它们描述了诸如此类的场景,其中子类应提供实现。 (抽象方法可以替换为空方法期望 - 但不要求 - 在子类中被覆盖,但为什么不将abstract 用于其设计目的?)

abstract class SuperClass implements IClass {
    // Don't implement this, but declare it abstract
    // so that we can conform to IClass as well
    public abstract void implementedMethod();

    public void method () {
       // Now this object (which conforms to IClass) has implementedMethod
       // which will be implemented by a concrete subclass.
       implementedMethod();
    }
}

这具有“负面”方面,即 SuperClass 不能直接实例化(毕竟它是抽象的)并且 SuperClass 必须实现(或者,如图所示,通过抽象委托)预期的签名。在这种情况下,我还选择让 SuperClass 实现 IClass,尽管它不是严格要求的,因为它保证 SuperClass 和所有子类都可以查看作为 IClass。

另外,请记住表达式类型只是对象的视图,不一定与对象的实际具体类型相同。虽然我建议不要使用以下代码,因为它失去了一些类型安全,但我认为它说明了重点。

class SuperClass {
    public void method () {
        // We try to cast and NARROW the type to a
        // specific "view". This can fail which is one
        // reason why it's not usually appropriate.
        ((IClass)this).implementedMethod();
    }
}

class SubClass extends SuperClass implements IClass {
  // ..
}

class BrokenSubClass extends SuperClass () {
}

// OK! Although it is the SAME OBJECT, the SuperClass
// method can "view" the current instance (this) as an IClass
// because SubClass implements IClass. This view must be
// explicitly request through a cast because SuperClass itself
// does not implement IClass or have a suitable method to override.
(new SubClass()).method();

// BAD! ClassCastException, BrokenSubClass cannot be "viewed" as IClass!
// But we didn't know until runtime due to lost type-safety.
(new BrokenSubClass()).method();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多