黑马程序员技术交流社区

标题: 多态转型问题 [打印本页]

作者: jonn    时间: 2013-1-14 16:16
标题: 多态转型问题
  1. class  Anamil{
  2.   public abstract void eat();      
  3.   }
  4. class cat extends Anamil{
  5.   void eat(){
  6.    ....
  7.    }
  8.   }
  9. class Dog extends Anamil{
  10.    void eat(){
  11.    ......
  12. }
  13. }
  14. public class Test{
  15.   public static void main(String args[]){
  16.   Anamil a=new Anamil();
  17.   Dog d=(Dog)a;
  18.   d.eat();    // 这里会出错,为撒?  请详细画个图解释下
  19. }
  20. }
复制代码

作者: 曹睿翔    时间: 2013-1-14 16:59
class  Anamil{                     // 1:这个地方,Anamil 类,因为包含eat();这个抽象方法,所以也需要为抽象

  public abstract void eat();      

  }

class cat extends Anamil{

  void eat(){



   }

  }

class Dog extends Anamil{

   void eat(){



}

}

public class Test{

  public static void main(String args[]){

  Anamil a=new Anamil();  //  如果为抽象类,则不能直接实例化,需要被继承,Anamil a=new Dog();  这也可以(多态)。

  Dog d=(Dog)a;  //那么这里就不需要强转了

  d.eat();    // 这里会出错,为撒?  请详细画个图解释下()

}

}
抱歉就不画图了,解释的不好


作者: 王晓斌    时间: 2013-1-14 17:17
首先,如楼上说的,需要把Animal改为抽象类,并且不能直接实例化。
其次,所谓多态的转型,可以如下
Animal a=new Dog()//类型提升,向上转型
a.eat()
当然,我们也可以向下转
Dog d=(Dog)a
但是不能出现下面操作,即直接把父类转为子类
animal a=new animal()//此处假设animal不是抽象类的话
dog d=(dog)a
其实,道理很简单,所有的dog都是animal,但不是所有的animal都是dog(手机发的,有点乱楼主将就下)
作者: jonn    时间: 2013-1-14 17:22
王晓斌 发表于 2013-1-14 17:17
首先,如楼上说的,需要把Animal改为抽象类,并且不能直接实例化。
其次,所谓多态的转型,可以如下
Animal ...

实体类里面完全可以包含抽象方法,只要继承的子类实现就ok了,抽象类只描述事物而已
作者: jonn    时间: 2013-1-14 17:34
王晓斌 发表于 2013-1-14 17:17
首先,如楼上说的,需要把Animal改为抽象类,并且不能直接实例化。
其次,所谓多态的转型,可以如下
Animal ...

完全可以向下转型,用 intanceof 关键字实现
此题我画个图...



实体类完全可以包含抽象方法,抽象类主要用于继承...只不过子类覆写父类所有抽象方法而已,那为何不解释抽象类可以有成员,变量,有普通成员方法,有构造方法呢
作者: 张云杰    时间: 2013-1-14 18:15
本帖最后由 张云杰 于 2013-1-14 18:18 编辑
赵文 发表于 2013-1-14 17:34
完全可以向下转型,用 intanceof 关键字实现
此题我画个图...


首先 你这定义的就有问题,
01.class  Anamil{

02.  public abstract void eat();      

03.  }

你这符合标准么?  实体类中怎么有抽象方法?  首先你的错误就是, 这个类 必须是抽象类 抽象类才能有抽象方法.. 否则就是接口

这个是概念问题..  目测你概念理解错了,  intanceof  是干嘛用的?  它用在继承中的子类的实例是否为父类的实现,是判断用的..

1楼说的对...

至于报错也很简单,  不用画图,  这也是概念问题...

你的Animal是父类, 这里是指向父类的引用..

而子类.. 强转了父类的引用,, 这自然就报错 ..

如果想调的话, 那么 你可以Animal a = new Dog();

这样 把父类指向子类,  子类强转 就不会报错了
作者: jonn    时间: 2013-1-14 18:28
张云杰 发表于 2013-1-14 18:15
首先 你这定义的就有问题,
01.class  Anamil{

是我糊涂了,谢谢哥们的解答....谢谢所有哥们解答:lol
作者: 张云杰    时间: 2013-1-14 18:29
赵文 发表于 2013-1-14 18:28
是我糊涂了,谢谢哥们的解答....谢谢所有哥们解答

不客气, 能理解就好
作者: 王阳    时间: 2013-1-14 21:22
你这段代码可以编译通过? 首先子类方法的访问修饰符不能低于父类方法的访问修饰符,其次,Animal需要抽象,所以不能有实例对象,所以楼主的代码可以改为。不知道是不是楼主想要的。
package test;

abstract class Anamil {
        public abstract void eat();
}

class cat extends Anamil {
        public void eat() {
                System.out.println("cat eat");
        }
}

class Dog extends Anamil {
        public void eat() {
                System.out.println("Dog eat");
        }
}

public class Test {
        public static void main(String args[]) {
                Anamil a = new Dog();
                a.eat();
        }
}

作者: 范德农    时间: 2013-1-15 14:46
错误:1、抽象方法是在普通类内。抽象类不能实例化。
          抽象方法只能在抽象类和接口中,      
      2、父类强转化为子类
         为什么一般父类不能转化为子类,extends实际意思为扩展,就是说子类是父类的扩展,打个比方,
         子类是大瓶子,父类是小瓶子。而所有的转换都可以理解为大瓶子做小瓶子的事,用小瓶子自然
         不一定能做大瓶子的事。
              Anamil a=new Anamil();

               Dog d=(Dog)a;
              以上这句翻译成人话,是这样的:
         //目前,有只动物叫a
         Anamil a=new Anamil();
             //现在我们叫a为狗d,可是动物不是都会汪汪汪啊
               Dog d=(Dog)a;
    a是动物不假,狗也是动物不假。可不一定a就能做狗的事情啊

再说明下intanceof  是干嘛用的,它是判断继承中的子类的实例是否为父类的实现。

           
作者: 周志强    时间: 2013-1-15 15:56
给你一个通俗的解释:
沿用 毕老师的一句话就是,“你能让所有动物都转成猫吗?”
Anamil a=new Anamil();//这是创建了一个动物对象
Dog d=(Dog)a;//这是吧一个动物对象强转狗
你说能通过吗?
作者: 陈迎春    时间: 2013-1-15 22:20
谢谢大家的互动




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