A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马任雪刚 中级黑马   /  2012-6-16 14:59  /  1986 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

abstract class Animal
{
        public abstract void eat();
}
class Cat extends Animal
{
        public void eat()
        {
                System.out.println("吃鱼");
        }
        public void cathMouse()
        {
                System.out.println("抓老鼠");
        }
}
public class Duotai
{

       
        public static void main(String[] args)
        {
                Animal a = new Cat();//这句代码在内存中是怎样的一个表现形式呢???
                a.eat();
                a.cathMouse();//既然父类的引用已经指向了子类对象,那不就是已经拥有子类中的所有内容了吗,那为什么
                                                //不能掉用子类中的方法呢???

        }

}

8 个回复

倒序浏览
本帖最后由 刘克方 于 2012-6-16 15:22 编辑

Animal a = new Cat();//这句代码在内存中是怎样的一个表现形式呢???
具体解释:
因为cat继承了animal那么Cat类型的对象有两部分主成,一部分是从父类继承来的方法和属性;另一部非父类、自己所特有的方法和属性;

既然父类的引用已经指向了子类对象,那不就是已经拥有子类中的所有内容了吗,那为什么不能掉用子类中的方法呢???
具体解释:
因为父类的引用指向了子类对象,那么子类所特有的方法和属性对父类是隐藏的,也就是说父类无法使用;
如果你想使用那么必须进行类型转换( Cat)a这样就能使用所有的方法了;
回复 使用道具 举报
本帖最后由 李盼 于 2012-6-16 15:17 编辑

父类引用指向子类对象,实际上是指向子类对象中的父类对象,因为子类在调用构造函数new对象的时候,实际上会先调用父类的构造函数。
我给你画了个图,a实际指向的是new Cat中的Animal,当我们调用a的eat方法时,确不是调用Animal的eat方法,而是调用Animal子类Cat的eat方法,这就是多态。
而Animal本身不会CathMouse方法,所以a不能调用该方法.!

1.jpg (17.66 KB, 下载次数: 17)

1.jpg
回复 使用道具 举报
当变量的编译时类型和运行时类型不同时,通过该变量访问它所引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定。
通过该变量调用它所引用的对象的实例方法时,该方法行为将由它实际所引用的对象来决定。
此时通过父类声明的对象去调用一个父类中并没有存在的一个方法,编译肯定是通不过的。当父类也有这个方法的时候,去调用,那么它将去执行它实际所引用的对象中的方法。
回复 使用道具 举报
如果你想实现多态,那么必须有三个条件,父类引用,子类对象,方法覆盖你父类的方法,例如像你这里的eat()方法。
如果 没有方法覆盖,那你这里只能解释为父类引用去访问一个子类的方法,当然,父类引用没有这么大范围的权限,
当然会报错 ,多态实际上是一种机制,在编译时刻,会生成一张虚拟表,来记录所有覆盖的方法,没有被覆盖的方法
是不会记录到这张表的.若一个父类引用调用了没有覆盖的子类方法,那么是不符合该表的,那么编译时刻就会报错.
就像你这里的cathMouse()这个方法。。
回复 使用道具 举报
  1. Animal a = new Cat();//这句代码在内存中是怎样的一个表现形式呢???
复制代码
这句在内存中是父类引用指向了子类对象,也可以说是子类对象直接赋给了父类引用.
  1. a.cathMouse();//既然父类的引用已经指向了子类对象,那不就是已经拥有子类中的所有内容了吗,那为什么
  2.                                                 //不能掉用子类中的方法呢???
复制代码
至于这句:其实在毕老师的视频中你可以很清晰知道
毕老师用自己和他爸爸的例子很形象的说明了为什么父类的引用不能调用子类特有的方法.
例如:
毕姥爷 x = new 毕老师();
x.看电影();错误  因为毕老师会看电影,他爸爸不会看电影,虽然毕姥爷是毕老师自己演的,
但是他现在的身份不是他自己,而是毕姥爷,所以他没有看电影这个功能,他必须下转型变成毕老师
之后才能看电影.
毕老师 y = (毕老师)x;
y.看电影();对.

回复 使用道具 举报
Animal a ,创建了一个Animal类的引用, =指向,指向哪里,指向new Cat();
所以调用a.eat();会查看Animal类中是否定义了eat方法,如果有,则去=号后面取,
那就是new Cat();里面了。
而检查Animal中没有cathMouse()方法,所以错误
回复 使用道具 举报
本帖最后由 王明明 于 2012-6-16 15:58 编辑

abstract class Animal
{
        public abstract void eat();
}
class Cat extends Animal
{
        public void eat()
        {
                System.out.println("吃鱼");
        }
        public void cathMouse()
        {
                System.out.println("抓老鼠");
        }
}
class Duotai
{

        
        public static void main(String[] args)
        {
                Animal a = new Cat();//这句代码在内存中是怎样的一个表现形式呢??? //在堆内存中建立了一个对象呗               
                a.eat();
                a.cathMouse();//既然父类的引用已经指向了子类对象,那不就是已经拥有子类中的所有内容了吗,那为什么
                                                //不能掉用子类中的方法呢???//因为你的数据类型是动物 你总不能说动物去抓老鼠 不是所有动物都会抓老鼠
        }

}
回复 使用道具 举报



父类对象引用子类对想 他只能看到 被子类继承的防范
看见黑色的那个方法没有 那是子类自己定义的 不是从父类继承的 所有 对父类来说 是隐藏的
父类不知道子类自己定义的方法 除了 子类继承的  父类对子类一无所知!

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马