假使,父类为 :Parent  子类为:Son则会有下面的情况: 
   Parent p = new Son();
   那么这个只能调用父类是的方法,如果子类Son有重写这些方法,就会调用Son中重写父类的方法。        有了这个前提,问题来了:  
  这里有一个方法传入的参数是父类(Parent),那么也可以传入它的子类Son。因为可以这样转换            Parent p = new Son();    
  public void test(Parent p){……}    但是传入Son时,为什么可以调用son自己特有的方法,而是不前一种情况:只调用子类中重写父类的法。     
   这里我只能理解前一种情况,后一种不知道该怎么理解。

解决方案 »

  1.   

    可以将p强转为Son类型来调用Son类的方法,参考以下代码:public class Test3 {
    public static void main(String[] args) {
    Parent parent = new Son();
    parent.a();
    test(parent);
    Son son = new Son();
    son.a();
    test(son);
    } static void test(Parent p) {
    p.a();
    // error
    // p.b();
    if (p instanceof Son) {
    ((Son) p).b();
    }
    }
    }class Parent {
    public void a() {
    System.out.println("pa");
    }
    }class Son extends Parent {
    @Override
    public void a() {
    System.out.println("sa");
    } public void b() {
    System.out.println("sb");
    }
    }
      

  2.   

    new的是son 自然是可以调用son的所有方法了    因为parent和son不是同一个对象,new的那个对象就能调用它的所有方法!
      

  3.   

    这个问题的本质在于如何理解java向上转型,java当中的向上转型或者说多态是借助于动态绑定实现的,所以理解了动态绑定,也就搞定了向上转型和多态。
    动态绑定
    后期绑定:在运行时根据具体对象的类型进行绑定。
    若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
    动态绑定的过程:
    虚拟机提取对象的实际类型的方法表;
    虚拟机搜索方法签名;
    调用方法。
      

  4.   

    不是的吧,
    Parent p = new Son();
    这个p不能调用son的特有方法,所以也就是说“new的是son 自然是可以调用son的所有方法了”,是不成立的例如public class test2 { /**
     * @param args
     */
    public static void main(String[] args) {
    /**
     * 为了测试当new出一个子类,是否同时new它的父类,并且它们的顺序是怎么样的
     */
    // Son s = new Son(); 
    /**
     * 显示结果为:
     * parent构造方法
     *son构造方法
     *
     *说明:实现子类的同时会实现它的父类,顺序是 父类-->子类
     */

    // Parent p = new Son();
    // p.method();
    // p.parentMethod();
    /**
     * 显示结果为:
     * parent构造方法
     *son构造方法
     *son_method
     *parent的方法
                       *
                       *而且这个p不能调用son的特有方法sonMethod()
     */
    Son s = new Son();
    test2.test(s);
    }

    public static void test(Parent p){
    p.method();
    p.parentMethod();
    }
    }class Parent{
    public Parent(){
    System.out.println("parent构造方法");
    }

    public void method(){
    System.out.println("parent_method");
    }
    public void parentMethod(){
    System.out.println("parent的方法");
    }
    }class Son extends Parent{
    public Son(){
    System.out.println("son构造方法");
    }

    @Override
    public void method() {
    System.out.println("son_method");
    }

    public void sonMethod(){
    System.out.println("son的方法");
    }
    }
      

  5.   


    不好意思,我是楼主……我特意来道歉的,szx_zsx 的说法是完全正解的,是我没有理解清楚 继承与多态。
      

  6.   


    这个我再仔细一想,我理解的才是正确的
    Parent p = new Son();
    对象p 只能调用son中重写Parent的方法和继承自Parent但没有重写的方法,但是不能调用Son自己特有的方法sonMethod()
    这里举一个生动的例子:
    一个老铁匠还有一个他的儿子小铁匠,老铁匠使用的是传统工艺的打铁方法(daMethod()),他儿子从父亲那里学会打铁(也就是重写 daMethod()),但是小铁匠的是个21世纪的新青年不喜欢用传统方法打铁(嫌累)于是他用机器打铁,而且这个小铁匠的接收能力比较强,又学会的其它的技能。
      

  7.   

    不好意思,昨天我说错了!正确的说法: FatherClass f = new SonClass()  当父类引用f指向其子类的对象的时候,通过f无法访问专属于子类对象的成员。假如子类中有对父类方法的重写,那么根据多态机制,通过f访问这个方法的时候实际访问的是子类中重写的方法。  如果想调用子类的特有成员就是 必须 SonClass s = new SonClass();
     
      

  8.   

    额   表示没明白楼主的意思 Parent p = new Son();    
      public void test(Parent p){……}   这个怎么可能可以调用子类扩展的方法呢?除非你做向下转型 不过向下转型是不安全的 违反了里氏代换原则
      

  9.   

    完全不懂你的“问题来了”是什么意思。“传入Son时,为什么可以调用son自己特有的方法”???
    可能吗?如果向下造型,也和前面的情形一样。
      

  10.   

    Parent parent = new Parent();…………3
    谢谢各位的耐心解答,自己也仔细的思考了,确实传入子类是不能调用它自己的特有方法,也就是等同于
    Parent p = new Son();…………1
    将p作为参数传入,也是等同
    Son s = new Son();…………2
    将s作为参数传入。
    其效果是一样的……首先检测子类中是否有重写的方法,如果没有就会调用父类中的方法(继承)。而这里是不会调用到子类特有的方法的(除非使用三楼 zyc13701469860 所提到的判定条件 “p instanceof Son” 说明:传入的参数p是否是Son类的实例 也就是说1和2都是Son类的实例 ,但是3却却不是,那么条件判断是false )。1的说明:就是Parent父类给出了一个模板p,而new出来的Son不管它有多少自己特有的方法,但是都得往这个模板去靠,也就是说不符合这个模板的(son的特有方法)就会被屏蔽掉。而2做为参数传入时,也是向这个定义的模板去靠拢(1是作为参数前就已经屏蔽掉了,而2是传入时才做屏蔽掉的)在此谢谢zyc13701469860 szx_zsx chengxu2011 huage1998 yqj2065 hhwyyda 各位的帮助!!!你们的回答对我很有用处