class Father {
public String s() {
            return "Father";
         }      
public void show() {
System.out.print(this.s());  // this代表子类对象?
}
}class Son extends Father {
public String s() {  // 复写了父类同名方法
           return "Son";
         }
}
class Test
{
public static void main(String args [])
{
       Father s = new Son();  // 改成Son s = new Son();有什么区别啊
        s.show(); 
        System.out.println();
}
}
我运行的时候怎么不管怎么改方法,结果都是一样的。既然是这样的,那为什么还要用  Father s= new Son();
到底有没有新的用意 啊。。麻烦高手指点。。谢谢了哦

解决方案 »

  1.   

    运行结果当然是打印出son了。
    因为你这个对象是用Son类进行实例化的,相应的这个对象调用的也是Son类中的代码。
    但是关于你说的父类名 引用 = new 子类名()这个问题,当你这样定义后,你这个对象就只能作为父类对象使用了(虽然它中的代码是执行子类的代码),比如:
    class Father {
    public String s() {
    return "Father";
    }
    public void show() {
    System.out.print(s()); // this代表子类对象?
    }
    }class Son extends Father {
    public String s() { // 复写了父类同名方法
    return "Son";
    }
    public String subS()
    {
    return "child";
    }
    }
    public class Test
    {
    public static void main(String args [])
    {
    Father s = new Son(); // 改成Son s = new Son();有什么区别啊
    System.out.println(s.subS());
    s.show();
    System.out.println();
    }
    }这个时候编辑就会产生一个
    找不到符号 subS()的编译错误(虽然我们是Son实例化的,并且可以肯定的是这个对象中有这个方法),这个时候对象已经被用作Father类的对象对待了,而Father类是没有subS()方法的。
    这种方式明显的好处就是我可以把所有一类对象(不是一个,这一类对象中有共同的特点,但是有一些具体的信息是不一样的)同意方式处理,而不用关心这个对象是这一类中的哪个,比如我现在就想得到一个人一顿吃几碗饭,但是人分男女、大小、老幼,各种情况不一样,那么我就写一个通用方法来返回人的饭量
    public eatNum(Person p)
    {
    return p.getNum();
    }而我调用的时候可能p是大人、小孩、老人、女人等等,但是我都作为Person调用,这个时候你就可以实现任意多种人,每种人的getNum都返回特定的数字,而不管你有多少种人,eatNum都可以不变。
      

  2.   

    这段程序是 告诉你 java 有多态 存在你可以看看这个帖子,他的问题和你一样:
                                        <求助>小弟刚学,关于多态的问题,大哥们讲解下 System.out.print(this.s());  // this代表子类对象?    this 这个关键字就是自生的意思, 
                                                         谁使用他,他就掉用谁的自身
    public String s() // 复写了父类同名方法              这里是重写下面是你自己的程序 仔细看 ,我什么都不改
    class Father {
    public String s() {
                return "Father";
             }      
    public void show() {
    System.out.print(this.s());  
    }
    }class Son extends Father {
    public String s() {  
               return "Son";
             }
    }
    class Test
    {
    public static void main(String args [])
    {
           Father s = new Son();  // 改成Son s = new Son();有什么区别啊  回答:没区别
                                 //  你把这里改成  Father s = new Father();
                                // 回输出 Father;
                               //看了我上面回的 仔细想象  
                              // Father s = new Son(); 为什么会输出Son
                             //而Father s = new Father();  输出 Father
                            //这就是程序的用意 
            s.show(); 
            System.out.println();
    }
    }
      

  3.   

    呵呵,我也是才刚刚学习啊,我们可以共同学习一下,你看懂了没
    我觉得我的表述可能有问题.说的有点乱,没条理不知道的可以说的啊.我先ZZZZZZ 酣眠去的
      

  4.   

    Father s = new Son();  // 改成Son s = new Son();有什么区别啊  回答:没区别纠正一下啊这里的 没区别,不是说真的没, 我是说 输出 ,输出没区别
      

  5.   

    有区别,而且区别很大。如:
    父类有public方法 func1(), func2(), func3();
    子类继承的父类的这三个方法,此外,子类还新增加了public方法 func4(), func5();
    Son s = new Son(); 些时,s 可以调用func1(), func2(), func3(), func4(), func5()这五个方法.但Father s = new Son(); 这时 s 只能调用父类定义的那几个方法 func1(), func2(), func3(),子类扩展的方法 func4(), func5(),这二个方法s些时是不能调用的,即子类扩展的方法对于父类类型的引用是不可见的。
      

  6.   

    xiangfeidecainiao() 
    我当然理解你的意思了哈哈。
    我现在楼上的,你的意思我也理解了。你也说的不错。。
      

  7.   

    在这里没有区别,不过它体现了针对抽象编程的思想,以父类声明的变量可以通过它的任何一个子类实例化,所以我们可以不需要关心具体子类的实现,增加了灵活性,当然在这里是声明的时候直接实例化的,所以上面提到的灵活性在这里体现不出来,但如果Father s中的变量s的值是通过方法的参数传递进去的话就可以看出来了,这时候我们可以传递Father的任意一个子类的实例
      

  8.   

    大家有空也去回答这个吧,里面也是类似的问题,只是复杂了点:
    http://community.csdn.net/Expert/topic/5576/5576255.xml?temp=.7524835
    多多讨论一下,我也搞的不是很清楚,要加强啊。。
      

  9.   

    )在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:
    1)实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的。
    2)静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。
    3)成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。