黑马程序员技术交流社区

标题: 多态中的引用对象问题 [打印本页]

作者: 凡延海    时间: 2012-5-21 10:39
标题: 多态中的引用对象问题
public class Test
{
public static void main(String[] args)
{
  Person person=new Student();
  person.age=20;
  person.name="Tom";
  person.say();
  System.out.println(person.country);
}
}
class Person
{
int age;
String name;
String country="China";
public void say()
{
  System.out.println("Perosn"+" age:"+age+",name:"+name+" come from:"+country);
}
}
class Student extends Person
{
int scores;
String country="English";
public void say()
{
  System.out.println("Student"+" age:"+age+",name:"+name+" come from:"+country);
}
}
打印出的结果是Student age: 20 name:Tom come from English
                        China
我知道把子类的实例对象给父类引用变量,调用方法的话用的是子类的方法,调用成员变量的画用的是父类的方法,打印出的Student那一行打印的应该是China才对。
作者: 李哲    时间: 2012-5-21 11:13
可是 person.say();是成员方法,编译看父类,运行看子类。既然是运行子类的 person.say();,这个方法中是country,隐含就是this.country,所以打印English。
System.out.println(person.country);就没什么说的。就像你说的成员变量用父类。

作者: 黑马-唐磊    时间: 2012-5-21 11:25
你那个主函数中的Person person=new Student();
子类型被提升到了父类型,父类引用指向子类对象,所以对于成员函数
编译时期:查看的引用型变量所属的类中中是否有被调用的方法
运行时期:查看所属的类中是否又该方法
造成这种现象原因是:函数在字符类中的一个特性:覆盖
也就是成员函数,编译看等号左边,运行看等号右边,这个结论很重要,所以你那个就看的是new student的方法所以结果是student中的变量English而不是China下面有一个例子可以运行下
class Fu
{
        int num = 4;
       
        public void method()
        {
                System.out.println("fu method ");
        }
        /**/

        public static void show()
        {
                System.out.println("fu static show");
        }
}


class Zi extends Fu
{
        int num = 5;
        public void method()
        {
                System.out.println("zi method");
        }
        public static void show()
        {
                System.out.println("zi static show");
        }
}



class  DuoTaiDemo6
{
        public static void main(String[] args)
        {

               
                Fu f = new Zi();

                f.show();

                Zi z = new Zi();
                z.show();
                //f.method();//

//                Zi z = new Zi();
//                System.out.println(z.num);

//                System.out.println(f.num);
        }
}
你可以尝试自己去运行一下,看看上面的结论可以帮你更好理解
作者: 陈嘉宾    时间: 2012-5-21 14:00
class Person
{
int age;
String name;
String country="China";
public void say()
{
  System.out.println("Perosn"+" age:"+age+",name:"+name+" come from:"+country);
}
}
class Student extends Person
{
int scores;
String country="English";
public void say()
{
  System.out.println("Student"+" age:"+age+",name:"+name+" come from:"+country);这句是当子类出现和父类一模一样函数时,当子类调用该函数会运行子类函数的内容,覆盖了。
作者: 黄克帅    时间: 2012-5-21 15:22
编译期间person 引用指向起父类本身,根本看不到子类的对象。 所以person.country 是 china 。运行期间调用方法的时候不是根据person的引用而是根据实际 new的对象调用其方法,就是调子类的say()方法,所以打出 English。
其实  person.say()掉用的时候; 里面的age  name都是先去看子类是否有这个属性,没有再去父类查看,输出结果age=20,name=tom只是在子类没有的情况下输出的父类的值。如果你在子类里面同样拥有age   name属性,那么 无论person.age  person.name 设什么值  都不影响子类的输出结果。

如果你在student类里面 这样写

public class Student extends Person {
        int age=30;
        String name="jack";
        int scores;
        String country = "English";

        public void say() {
                System.out.println("Student" + " age:" + age + ",name:" + name
                                + " come from:" + country);
        }

}

输出的结果是   Student age:30,name:jack come from:English
                        China

作者: 凡延海    时间: 2012-5-21 15:49
我就是想表达在子类实例对象赋值给父类的时候到底是怎样个情况嗯,是不是有两个引用变量呢,不然怎么会是引用变量调用方法的时候调用子类的方法,引用变量调用成员方法的时候是调用的父类的成员方法的呢。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2