首页 > 解决方案 > 是否可以创建一个“超级”变量,然后将其更改为子类类型并能够访问子类方法

问题描述

我想要的是能够使用超类创建一个变量,然后稍后将其“转换”为子类并能够访问子类方法。它总是被定义为一个子类,我只是在定义时不知道是哪个子类。

class SuperClass {
  //superclass methods
}

class SubClass1 extends SuperClass {
  void subClass1method() {
    //do something
  }
}

class SubClass2 extends SuperClass {
  void subClass2method() {
    //do something different
  }
}

class Main {
  public static void main ( String [] args ) {
    SuperClass a;

    if (*some reson to be SubClass1*) {
      a = new SubClass1();
      a.subClass1Method();     //this is undefined it says
      //a instanceof SubClass1 returns true which is what confused me
    } else {
      a = new SubClass2();
      a.subClass2Method();     //this is undefined it says
    }
  }
}

我不是在问它为什么这样做,而是在问解决它并获得我想要的结果的正确方法。

我一直在寻找重复的,但很容易错过一个,所以请告诉我。

标签: javainheritancesubclasssuperclass

解决方案


当您无法控制源时,除了强制转换(或可能使用适配器)之外,您无能为力。如果instanceof你的课程听起来很熟悉,那么这可能就是你的教授所期望的。

以下是您的一些选择:

// to execute those subclass specific methods without casting..
public static void main ( String [] args ) {
    SuperClass superClass;
    if (true /*some reson to be SubClass1*/) {
        SubClass1 subClass1 = new SubClass1();
        subClass1.subClass1Method();
        superClass = subClass1;
    } else {
        SubClass2 subClass2 = new SubClass2();
        subClass2.subClass2Method();
        superClass = subClass2;
    }
    // ... ...
}

// using instanceof and casting
public static void main ( String [] args ) {
    SuperClass superClass;
    if (true /*some reson to be SubClass1*/) {
        superClass = new SubClass1();
    } else {
        superClass = new SubClass2();
    }

    // ... ... ...

    if(superClass instanceof SubClass1) {
        ((SubClass1) superClass).subClass1Method();
    } else if(superClass instanceof SubClass2) {
        ((SubClass2) superClass).subClass2Method();
    }
}

以下是我的建议,以在您控制源代码时实现此目标。

您可以使用组合来为一个类提供不同的行为,而不是为不同的行为创建一个新类。请注意,如果您了解功能接口和方法引用,这将特别方便。

public class SuperClass {
    private MyBehavior behavior;

    public void setBehavior(MyBehavior behavior) { this.behavior = behavior; }

    public void doBehavior() { this.behavior.doBehavior(); }
}

public interface MyBehavior { public void doBehavior(); }

public class MyGoodBehavior implements MyBehavior {
    @Override public void doBehavior() { System.out.print("good behavior"); }
}

public class MyBadBehavior implements MyBehavior {
    @Override public void doBehavior() { System.out.print("bad behavior"); }
}

public static void main(String[] args) {
    SuperClass a = new SuperClass();
    a.setBehavior(new MyBadBehavior());
    
    a.doBehavior();
}

推荐阅读