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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 葛晓东 中级黑马   /  2014-5-27 21:26  /  2030 人查看  /  18 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 葛晓东 于 2014-5-28 23:39 编辑

多态中
父类引用指向自己的子类对象,
调用方法时,只能运行子类重写后的方法,不能调用子类特有的方法,常常遇到ClassCastException这样的提示,我想知道怎么能调用子类特有的方法

18 个回复

倒序浏览
本帖最后由 yang1352546 于 2014-5-27 22:48 编辑

   1  在多态中,只能调用子类父类共有方法,不能调用子类的特有方法!!这就是多态的弊端
   2 调用子类特有方法,必须进行类型的强制转换,将提升为父类类型的子类对象,转回子类的类型,手动!!
   3 但是为了 保证程序的安全性,避免发生类型转换异常ClassCastException,采用instancof运算符,进行健壮性判断
     变量 instanceof 类名 如果是返回真  说明可以转回子类类型   4 利用         目标类型 变量 = (目标类型)被转的变量,转换为子类类型后就可以调用子类特有的方法。


评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
如果是父类引用指向子类对象,调用子类特有方法的时候,必须将已经提升为父类类型的子类对象,强制转回子类的类型,类似数据类型的强制转换。
回复 使用道具 举报 1 0
老师的视频中详细的讲过哦!!!!!!
  1. abstract class Animal1{
  2.         public abstract void eat();
  3. }

  4. class Cat1 extends Animal1{
  5.          public  void eat(){
  6.                  System.out.println("吃鱼");
  7.          }
  8.          public void catchMouse(){
  9.                  System.out.println("抓老鼠");
  10.          }
  11. }
  12. class Dog1 extends Animal1{
  13.         public void eat(){
  14.                 System.out.println("吃骨头");
  15.         }
  16.         public void KanJia(){
  17.                 System.out.println("看家");
  18.         }
  19. }
  20. class Pig1 extends  Animal1{
  21.          public void eat(){
  22.                  System.out.println("饲料");
  23.          }
  24.          public void gongDi(){
  25.                  System.out.println("拱地");
  26.          }
  27. }

  28. public class DuoTaiDemo1 {

  29.        
  30.         public static void main(String[] args) {
  31.                
  32.                
  33. //                   Animal a = new Cat();//类型提升。向上转型。
  34. //                   a.eat();
  35. //1---------------------------------------------------------------------------------------                  
  36.                 //如果想要调用猫的特有方法时,如何操作。
  37. //                  强制将父类的引用。转成子类类型。向下转型。
  38. //                   Cat c =(Cat)a;
  39. //                   c.catchMouse();
  40. //2--------------------------------------------------------------------------------------               
  41.                    //千万不要出现这样的操作,就是将父类对象转成子类类型。
  42.            //我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
  43.                    //多态自始至终都是子类对象在做着变化。
  44. //                   Animal1 a = new Animal1();
  45. //                   Cat c = (Cat)a;
  46. //3---------------------------------------------------------------------------------------               
  47.                 function(new Dog());
  48.                 function(new Cat());
  49.         }
  50.         public static void function(Animal a){
  51.                 a.eat();
  52.                 if(a instanceof Cat){
  53.                         Cat c = (Cat)a;
  54.                         c.catchMouse();
  55.                 }else if(a instanceof Dog){
  56.                         Dog d = (Dog)a;
  57.                         d.KanJia();
  58.                 }
  59.                        
  60.                
  61.         }
  62. }
复制代码

看看1,2, 3,的部分 你就懂了!!!

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报 1 0
强制转换成子类就可以调用了
回复 使用道具 举报
孟祥钰 发表于 2014-5-27 21:34
如果是父类引用指向子类对象,调用子类特有方法的时候,必须将已经提升为父类类型的子类对象,强制转回子类 ...

:handshake:handshake
回复 使用道具 举报

今天刚刚学完的

  1. /*
  2.    通过养宠物的案例,展示多态
  3. */
  4. //每个动物的共性抽取
  5. class Animal{
  6.   public void eat(){}
  7. }
  8. //养个鸟,吃的功能,飞翔
  9. class Bird extends Animal{
  10.   public void eat(){System.out.println("鸟吃虫子");}
  11.   public void fly(){System.out.println("鸟在飞");}
  12. }
  13. //养狗,吃的功能,看家
  14. class Dog extends Animal{
  15.    public void eat(){System.out.println("狗吃狗粮");}
  16.    public void lookHouse(){System.out.println("狗看家");}
  17. }

  18. //养猫,吃的功能,抓老鼠
  19. class Cat extends Animal{
  20.    public void eat(){System.out.println("猫吃猫粮");}
  21.    public void catchMouse(){System.out.println("猫抓老鼠");}
  22. }

  23. class DuoTaiDemo3{
  24.    public static void main(String[] args){
  25.             Cat c = new Cat();
  26.                         eat( c)        ;
  27.                         eat(new Bird())        ;
  28.    }
  29.   
  30.       public static void eat(Animal a){//eat(new Cat());  Animal a = new Cat(); 向上转,多态
  31.             a.eat();
  32.                         //进行类型转换的时候,判断一下,传递的对象是不是猫对象
  33.                         //最后的一个比较运算符  instanceof 关键字,结果肯定真或者假
  34.                         //判断一个引用,是不是由一个类创建的   :格式 引用类型变量 instanceof 类
  35.                         // a instanceof Cat==>true   a instanceof Dog==>false
  36.                         if(a instanceof Cat){
  37.                           Cat c = (Cat)a;
  38.                           c.catchMouse();
  39.                         }
  40.                         
  41.                         if(a instanceof Dog){
  42.                           Dog d = (Dog)a;
  43.                           d.lookHouse();
  44.                         }
  45.                         
  46.                         if(a instanceof Bird){
  47.                           Bird b = (Bird)a;
  48.                           b.fly();
  49.                         }
  50.       }
  51.    
  52.    
  53. }
复制代码

回复 使用道具 举报
abstractclass Animal {
        public abstractvoid 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 kanJia()  {   
                System.out.println("看家");   
        }   
}   
class Pig extends Animal  {   
        public void eat()  {   
                System.out.println("饲料");   
        }   
        public void gongDi()  {   
                System.out.println("拱地");   
        }   
}   
   
class DuoTaiTest   {   
        public static void main(String[] args)   {   
                Animal a = new Cat();
                //类型提升。 向上转型。 父类类型指向子类对象  
                a.eat();  //吃鱼
   
                //如果想要调用猫的特有方法时,如何操作?   
                //强制将父类的引用。转成子类类型。向下转型。   
                Cat c = (Cat)a;   
                c.catchMouse(); //抓老鼠
   
                //不要出现这样的操作,就是将父类对象转成子类类型。   
                //我们能转换的是父类应用指向了自己的子类对象时。
                //该应用可以被提升,也可以被强制转换。   
                //多态自始至终都是子类对象在做着变化。   
                //      Animal a = new Animal();   
                //      Cat c = (Cat)a;   
                  
   
                /*  
                父 x = new 子();  
  
                x.工作();  
  
                子 y = (子)x;  
  
  
                y.玩();  
                */   
                function(new Cat());
                function(new Dog());   
                function(new Pig());   
   
   
            }   
            public static void function(Animal a){//Animal a = new Cat();   
                if(!(a instanceof Animal)) {  
                    System.out.println("类型不匹配");  
                }  
                else{
                        a.eat();
                        if(a instanceof Cat)  {   
                                Cat c = (Cat)a;   
                                c.catchMouse();   
                        }
                        else if(a instanceof Dog)  {   
                                Dog c = (Dog)a;
                                c.kanJia();
                        }
                       else if (ainstanceof Pig()){
                                Pig p = (Pig)a;
                                a.gongDi();
                        }
                }
                //instanceof : 用于判断对象的类型。  
               //对象 intanceof 类型(类类型 接口类型)   
           }   
}   
中间的就是强转部分  格式
回复 使用道具 举报
强制类型转化就可以了
回复 使用道具 举报
正常情况一般都是  父类引用指向子类对象,  都应该复写子类特有方法,然后调用的。  也可以转换类型。 就是类型提升。
回复 使用道具 举报
学习了学习了
回复 使用道具 举报
四楼说的很明白
回复 使用道具 举报
多态
  A. 父类或者接口指向自己的子类对象
     Fu f = new Zi();   NO ~~ Zi zi = new Fu();
  B. 调用方法的时候,运行的是子类重写后的方法
  C. 调用成员变量的时候,运行的是父类的成员变量
  D. 在多态中,只能调用子类父类共有方法,不能调用子类的特有方法!!多态的弊端
  E. 调用子类特有方法,必须进行类型的强制转换,将提升为父类类型的子类对象,转回子类的类型,手动!!
  F. 保证程序的安全性,避免发生类型转换异常ClassCastException,采用instancof运算符,进行健壮性判断
/*
   通过养宠物的案例,展示多态
*/
//每个动物的共性抽取
class Animal{
  public void eat(){}
}
//养个鸟,吃的功能,飞翔
class Bird extends Animal{
  public void eat(){System.out.println("鸟吃虫子");}
  public void fly(){System.out.println("鸟在飞");}
}
//养狗,吃的功能,看家
class Dog extends Animal{
   public void eat(){System.out.println("狗吃狗粮");}
   public void lookHouse(){System.out.println("狗看家");}
}

//养猫,吃的功能,抓老鼠
class Cat extends Animal{
   public void eat(){System.out.println("猫吃猫粮");}
   public void catchMouse(){System.out.println("猫抓老鼠");}
}

class DuoTaiDemo3{
   public static void main(String[] args){
            Cat c = new Cat();
                        eat( c)        ;
                        eat(new Bird())        ;
   }

      public static void eat(Animal a){//eat(new Cat());  Animal a = new Cat(); 向上转,多态
            a.eat();
                        //进行类型转换的时候,判断一下,传递的对象是不是猫对象
                        //最后的一个比较运算符  instanceof 关键字,结果肯定真或者假
                        //判断一个引用,是不是由一个类创建的   :格式 引用类型变量 instanceof 类
                        // a instanceof Cat==>true   a instanceof Dog==>false
                        if(a instanceof Cat){
                          Cat c = (Cat)a;
                          c.catchMouse();
                        }
                       
                        if(a instanceof Dog){
                          Dog d = (Dog)a;
                          d.lookHouse();
                        }
                       
                        if(a instanceof Bird){
                          Bird b = (Bird)a;
                          b.fly();
                        }
      }


}





回复 使用道具 举报
怎么感觉你么有看视屏呢!
如果父类初始化应用指向了子类的实例对象(多态)
这是如果想要调用子类特有的方法,必须将父类引用向下转型
eg:
Animal al=new Cat();Cat cat=(Cat)al;//抓老鼠是猫咪特有的功能,不是所有动物都有,因此向下转型
cat.catchMouse();


回复 使用道具 举报
武维京 发表于 2014-5-27 21:49
老师的视频中详细的讲过哦!!!!!!

看看1,2, 3,的部分 你就懂了!!!

看你发的代码  我看懂了  也想明白了   谢谢啊
回复 使用道具 举报
强制转换为子类啊 就可以使用了
回复 使用道具 举报
如果想要使用的东西不会报classcastexcepiton的话,你后面学会使用了泛型之后,就可以考虑用泛型,这样就不会报错了,子类,如果你用多态,只哎哟是能转换过去,而且必须是子类有这个特定的方法,子类就可以使用,否则,转换过去了,还会报错
回复 使用道具 举报
强转成子类方法
回复 使用道具 举报
看完之后终于想明白了~~~~~:)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马