在超类中使用子类'方法

时间:2013-07-25 19:34:12

标签: java inheritance interface subclass superclass

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

示例:

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的implementsMethod()(它来自IClass)

我将如何做到这一点?

3 个答案:

答案 0 :(得分:2)

你可以使超类抽象:

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

鉴于上述类型,必须使用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();