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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 包晗 中级黑马   /  2012-7-15 17:43  /  1853 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 包晗 于 2012-7-16 18:21 编辑
abstract class Animal
{
        abstract void eat();
}


class Cat extends Animal
{
        public void eat()
        {
                System.out.println("吃鱼");
        }
        public void catchMouse()
        {
                System.out.println("抓老鼠");        
        }
}
  
  class Dog extends Animal
{
        public void eat()
        {
                System.out.println("吃骨头");
        }
        public void kanmen()
        {
                System.out.println("看门");        
        }
}


class Pig extends Animal
{
        public void eat()
        {
                System.out.println("吃饲料");
        }
        public void gongdi()
        {
                System.out.println("拱地");        
        }
}

class DuotaiDemo
{

        public static void main(String[] agrs )
        {
         chi(new Dog());
}


        public static void chi(Animal a)
        {
                Dog o = (Dog)a;
                a.eat();       // 问题在这里!
                o.eat();
                o.kanmen();
        }

}


想请教大家
我已经强制转换了
Dog o = (Dog)a;
为何 a.eat();  还会执行   按照我的理解 强制转换了后  a.eat(); 应该作废  
可是 a.eat(); o.eat();
都执行了
(12期我会来)

5 个回复

倒序浏览
a.eat()这就是多态的体现了。
chi(new Dog());将一个Dog对象传给了父类对象Animal a,就是父类类型的指向了子类对象。
在运行时调用a.eat()的时候,此时调用的是方法,那么虚拟机会找到a实际指向的对象类型进行方法的调用,由于a实际指向的是Dog对象,因此调用的是Dog类中的eat()方法。
但是此时a不能调用kanmen()方法,因为a声明的是Animal类型,而Animal类中没有kanmen()方法。
在这里,使用的就是多态的思想,即父类类型的引用指向子类对象,在运行时调用子类中重写了的方法。
建议再看下多态的概念。
回复 使用道具 举报
abstract class Animal
{
        abstract void eat();
}


class Cat extends Animal
{
        public void eat()
        {
                System.out.println("吃鱼");
        }
        public void catchMouse()
        {
                System.out.println("抓老鼠");        
        }
}
  
  class Dog extends Animal
{
        public void eat()
        {
                System.out.println("吃骨头");
        }
        public void kanmen()
        {
                System.out.println("看门");        
        }
}


class Pig extends Animal
{
        public void eat()
        {
                System.out.println("吃饲料");
        }
        public void gongdi()
        {
                System.out.println("拱地");        
        }
}

public class DuotaiDemo
{

        public static void main(String[] agrs )
        {
         chi(new Dog());
}


        public static void chi(Animal a)  这里是多态,编译时只要Animal当中有eat()方法编译就可以通过,但是运行是运行的是子类的方法,不是Animal的方法
        {
                Dog o = (Dog)a;
                a.eat();      面向多态,此处编译成功,所以这里运行的是子类Dog的方法,不是Animal里面的方法
                o.eat();      这里你又调用了一次Dog的eat()方法,所以有两次吃骨头
                o.kanmen();   这里如果换做是a.kanmen()方法将编译失败,因为父类(Animal中没有kanmen()方法)
        }

}
回复 使用道具 举报
张_涛 发表于 2012-7-15 17:50
a.eat()这就是多态的体现了。
chi(new Dog());将一个Dog对象传给了父类对象Animal a,就是父类类型的指向了 ...

貌似您没有理解我的问题  
我的问题是 在强制从父类引用转换成子类引用后
为什么Dog o = (Dog)a;
中  a.eat();  还会执行
回复 使用道具 举报
王飞 发表于 2012-7-15 18:07
abstract class Animal
{
        abstract void eat();

就是说 强制转换后  子类的方法没有变 还是存在于内存当中 是吗
回复 使用道具 举报
包晗 发表于 2012-7-15 18:29
就是说 强制转换后  子类的方法没有变 还是存在于内存当中 是吗

是的

比如:
动物 dw = new 猫();   这里就有转换,把一只猫提升成了动物,那么他肯定还有吃鱼的方法,

我要个动物,你给我一只猫,这当然可以啊,而且猫中吃鱼的方法肯定还在啊,总不能说:我要一动物,然后你给了我一只猫,然后猫吃鱼的方法就没有了吧  这。。。。不可能没有吧 对吧

我的答案希望你满意:handshake

点评

谢谢  发表于 2012-7-15 19:16

评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

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