3

我正试图围绕java中的继承。到目前为止,我了解到,如果我以以下方式声明一个对象:Superclass object = new Subclass()创建的子对象仅限于父对象的方法。如果我想访问孩子的其他方法,我将不得不向孩子施放。但是为什么子类中的方法仍然被覆盖。

这是我的例子

public class Parent {

    public Parent() {       

    }

    public void whoAmI(){       
        System.out.println("I'm a parent");
    }

}
public class Child extends Parent { 

public Child() {        

}

public void whoAmI(){       
    System.out.println("I'm a child");
}

public void childMethode() {
    System.out.println("Foo");

}
}

public class Test {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    List<Parent> list = new ArrayList<>();      

    Child c = new Child();  
    Parent p = new Parent();
    Parent pc = new Child();

    c.whoAmI();
    p.whoAmI();
    pc.whoAmI();

    // Access child methodess
    ((Child) pc).childMethode();

    list.add(c);    
    list.add(p);
    list.add(pc);

    System.out.println(list.size());

}

}

pc.whoAmI()打印“我是个孩子”。为什么不打印“我是父母”?

4

5 回答 5

4

为避免混淆,请务必了解您创建的子类对象始终包含所有方法。向下转换是无操作的;您只需将相同的对象视为子类型的实例。

推论:你永远不能通过向下转换来改变对象的行为。由此直接得出结论,您始终访问相同的覆盖方法,而不是来自超类的方法。

这种行为允许您用不同的行为替换同一个声明的超类型。它被称为多态,是 Java 编程和一般 OOP 的主力。没有它,一开始就没有类层次结构。至少,它的用处要少得多。

于 2012-12-02T15:10:40.423 回答
1

为什么是一个很难回答的问题,这是 Java 团队很久以前做出的设计决定。

他们决定所有方法都是虚拟的,除非它们被明确标记为静态。在某些语言中,情况正好相反(除非声明为虚拟方法,否则默认情况下方法是静态的),它没有真正的区别。

重要的是要了解静态和虚拟方法是如何工作的。(或者它们有时在 Java 中被称为:实例和类/静态方法。)

于 2012-12-02T15:05:05.740 回答
1

您可以将继承想象为创建名为super.

Java 中的每个对象实例都有自己的常量类型。你不会在铸造时改变它。在强制转换时,您只需对 Java 说您确定该对象是子类型。

被覆盖的方法仍然被覆盖,这是 Java 的思想。如果您了解 C++,您可以说 Java 中的所有函数都是虚拟的。

于 2012-12-02T15:05:27.080 回答
0
class Person{

   public void run(){
       //running

   }

}

class OneLeggedPerson extends Person{
    @Override
    public void run(){
        //cant run have only one leg
   }
}


Person p = new OneLeggedPerson();
p.run();    //cannot as it is actually a one legged person


Hope that makes sense now..
于 2012-12-02T15:13:45.590 回答
0

假设您是 Apple,并且您正在销售 iPod。

iPod 的制造方式可能在一个工厂和另一个工厂之间存在细微差别,或者在 iPod 模型的第一个版本和最后一个模型之间存在细微差别,因为过程发生了变化。

你,Apple,知道你制造什么样的 iPod:

IPodWithFirstWayOfBuildingIt ipod = new IPodWithFirstWayOfBuildingIt();

或者

IPodWithSecondWayOfBuildingIt ipod = new IPodWithSecondWayOfBuildingIt();

但最终客户(即代码的其余部分)对 iPod 的构建方式毫不在意。对他而言,重要的是 iPod 的工作方式和行为方式与 iPod 相似(广告中、最终用户手册或 Ipod 类的 javadoc 中显示的方式)。他没有要求商店“给我一个 iPod,用第一种方式构建它”。但事实是,他得到的 iPod 要么采用第一种构建方式,要么采用第二种构建方式。他称其为“iPod”这一事实并没有改变 iPod 的制造方式,因此:

IPod iPod = new IPodWithFirstWayOfBuildingIt();

是这样说的。我用第一种方式构建了一个 iPod,但我将像使用任何其他 iPod 一样使用它,而不关心它是如何构建的。

于 2012-12-02T15:17:58.983 回答