0

假设您有一个带有子类 SC1、SC2、...的基类 BC 和一个对象集合 C(一些类型为 SC1,一些类型为 SC2,......)。方法 m 在子类中定义,而不是在 BC 中。我希望做这样的事情:

class AnotherClass {
  private BC getObj(Container c) { /*return something from c*/ }

  private void anotherMethod() {
    ...
    BC o = getObj(c);
    o.m();
  }
}

现在 getObj 将返回一个对对象的引用 o 并且据我所知它必须是 BC 类型(或者有没有办法在这里应用泛型?)。我收到一个编译错误(m() 在 BC 中不存在)。我假设有一种很好的方法可以做到这一点(无需“手动”以某种方式找出 o 的真实类型)?

4

3 回答 3

2

为什么没有定义方法BC?这就是多态性的全部意义所在。

您的另一个选择是让对象实现一个接口,该接口包含m并拥有该接口的集合,而不是BC. 或者使用反射(ew),或者检查类型(ew)。

于 2013-07-17T23:08:43.743 回答
0
public class BC 
{
    protected void m()
    {
        System.out.println("BC:M");
    }

}


public class SC1 extends BC 
{
    public void m()
    {
        super.m();
        System.out.println("SC1:M");

    }

}


public class SC2 extends BC 
{
    public void m()
    {
        super.m();
        System.out.println("SC2:M");

    }

}


public class TestClass 
{

    public static void main(String args[])
    {
        SC1 sc1_one= new SC1();
        SC1 sc1_two= new SC1();

        SC2 sc2_one= new SC2();
        SC2 sc2_two= new SC2();
        ArrayList al = new ArrayList<BC>();
        al.add(sc1_one);
        al.add(sc2_one);
        al.add(sc1_two);
        al.add(sc2_two);

        BC bc = (BC) al.get(3);
        bc.m();
    }

}

输出:BC:M SC2:M

对于这些场景,您需要在基类中声明方法 m。然后你可以覆盖到子类

于 2013-07-17T23:40:10.380 回答
0

在此刻

BC o = getObj(c);

你有一个对象的引用,o。在编译时,您的代码唯一知道的事实是,无论此引用指向什么(BC 或 BC 的子类)都具有 BC 中定义的方法。它无法知道您给它的子类是 SC1 或 SC2 的实例。因此,您的问题是您需要执行仅在子类上定义的方法。您在这里有几个选择。

  1. 反射 - 使用 Java 的反射功能检查给定的对象,查看该方法是否可用,然后调用它。但是您会丢失编译时间检查,这很慢。不是首选解决方案
  2. 检查 c 的实例,转换为适当的类型,然后调用方法。这会起作用,但 instanceof 也很慢,并且违背了子类化和多态的目的。也不推荐。
  3. 将一个方法(如果 BC 永远不需要实例化,则可能是抽象的)引入 BC,然后您的子类将覆盖该方法。直接调用此方法。这是更好的解决方案,可能是您应该追求的。
  4. 如上所述,但使用您的子类实现的接口,并让您的方法返回该接口。
于 2013-07-18T00:03:12.650 回答