Java upcast范围解析问题

时间:2010-12-08 21:17:00

标签: java

我有一个基类“Shapes”和一个扩展类“Circle”。两者都有一个getName方法。 我的测试类是“Driver”类。

我将Circle对象向上转换为Shapes并将其传递给名为polyTest的函数。 在该函数中,我想调用getName,但我不希望触发get对象的循环对象实现,而是希望触发基类实现。

super.getName()不起作用。

我的代码如下:

public class Driver{
     public static String polyTest (Shapes s){
        return s.getName(); 
       /*Instead of s.getName()... (gives me the Circle class implementation of getName() )
       I want to call s.Shapes::GetName, the base class implementation of getName. */
     }

     public static void main(String[] args){
      Circle c = new Circle();

      //Test Basic inheritance & basic polymorphism.
      //System.out.print(c.getName());

      //Upcast test.
      Shapes s = (Shapes) c;
      System.out.print( polyTest(s) );    
     }
}

public class Circle extends Shapes{
     Circle(){
      super();
     }

     public String getName(){
      return "I am a Circle";
     }
}

public abstract class Shapes{
     Shapes (){
     }

     public String getName(){
      return "I am a Shape";
     }
}

2 个答案:

答案 0 :(得分:5)

这就是多态Java工作的方式,我很害怕。您不能强制虚拟方法调用在方法本身之外(您可以调用super.getName())非虚拟地执行。这样做的能力会破坏封装 - 例如,一个类可以在调用super方法之前以重写方法以特定方式验证其参数...如果你可以绕过它并说“我只想调用原始方法”实施“然后你就会违反首先覆盖方法的整个目的。

您应该重新设计代码,以便需要调用特定的实现。多态性的要点是允许子类专门化行为,而不会让调用者提前知道该实现是什么。

当然,如果你想让一个方法不可覆盖,你就可以把它作为最终方法。

答案 1 :(得分:0)

  1. 您无需将Circle转发给Shapes。 (顺便说一句,为什么Shapes但是Circle?)
  2. 如果您不希望Circle类实现自己的getName方法,请不要覆盖它。
  3. 如果您需要覆盖其他内容的getName方法,则可能需要将getNameInSomeContext添加到Shapes类,并在必要时在派生类中覆盖它。