1.class A{
public void f(){
System.out.println("A");}
}
class B extends A{
public void f(){
System.out.println("B");}
}
class duotai{
public static void main(String args[]){
A p=new B();

p.f();
}
}编译正确
2. class A{
public void f(){
System.out.println("A");}
}
class B extends A{
public void m(){
System.out.println("B");}
}
class duotai{
public static void main(String args[]){
A p=new B();

p.m();
}
}这个编译错误
程序中的A p= new B();不是把A中的P引用指向了B的实例了么,为什么第一个可以调用B中的方法,而第二个不可以调用B中的方法,

解决方案 »

  1.   

    A p=new B()这个是多态中上溯机制,就是把子类对象赋给父类对象,此时p是一个父类对象,父类中是没有定义m()这个方法的,所以p.m()会报错。
      

  2.   

    这个应该和内存中存放没什么关系,和指向有关系。
    简单的说,p.f();这个其实就是调用了父类的方法,因为子类继承了父类的内容,但是子类中如果有重名的方法就把父类的给重写了。于是调用的就是子类的方法了。
    你把例1中的public void f()改为私有的,也是会报错的。
      

  3.   

    第一个代码中,父类的方法实现f()方法,子类重写了父类的f()方法,多态的特点是父类的引用指向子类的对象,并且通过父类的引用调用子类的方法,但是有一个前提就是子类必须重写父类的这个方法,否则就会报错,在代码2中,父类实现的是f()方法,但是子类没有重写父类的方法,而是重新实现了一个方法,这样就不能通过父类的引用调用父类的方法
      

  4.   

    A p=new B();B是A的子类,这是多态中向上转型的做法(不推荐),第二个中由于父类没有p.m这个方法只有子类有m这个方法,所以报错
      

  5.   

    楼上几位的回复基本能解答你的问题,这个问题你应该是对于Java中的多态的概念存在模糊所导致。
      

  6.   

      第二个是  :父类不能调用子类独有的方法 需要强制转换才可以调用子类的方法
       B p=(B)A
      

  7.   

    P中是没有m这个方法的,所以编译直接报错,P能调用到B中的f方法是由于方法的动态绑定,在方法运行时,编译器通过找到P实际引用的对象,找到该对象的方法表,通过方法签名(方法名和方法参数)确定应该调用的方法,B中的f方法覆盖了父类的f方法。