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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 戴振良 黑马帝   /  2012-3-11 00:09  /  3502 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 戴振良 于 2012-3-11 00:36 编辑

class Ren
{
        String name;
        public void run(){}
}
class NanRen extends Ren
{
        public void zhuanQian(){}//男人赚钱        
}
class NvRen extends Ren
{
        public void xiWan(){}//女人洗碗
}
class Test
{
        public static void main(String args[])
        {
                Ren r=new NanRen();//可以把男人赋值给人
                Ren r2=new NvRen();//可以把女人赋值给人
                NanRen nr=(NanRen)new Ren();//不能把人当成男人赋值给男人,运行类时会报错的
                NanRen nr2=(NanRen)r2;//也不能把认不出性别的女人赋值给男人,运行类时会报错
                NvRen nv=(NvRen)r2;//可以把认不出性别的女人赋值给女人,但是必须强制转换为女人后才可以赋值,否则会报错
                nv.xiWan();        //叫女人去洗碗        
        }
}
这搞的我有点晕:
  • 为什么子类对象可以赋值给父类的引用,而父类对象却不能赋值给子类的引用?
  • 为什么允许把子类对象赋值给父类的引用,直接赋值给子类的引用不就行了吗?搞这么复杂!
  • 编译器不知道r2这个引用是男人、女人的,只知道这个引用是一个人,是这样的吗?运行时蓝色那句代码的异常信息是:NvRen cannot be cast to NanRen ,我在有 道词典翻译了一下说是“女人不能抛给男人”,这不是说明了编译器知道r2是一个女人吗?
  • 如果编译器知道r2这个引用是个女人,为什么红色那句代码需要我强制转换为女人才可以赋值给女人的引用?
     
         问了这么多,其实我最想知道的是问题2,这样做的好处在哪里啊?

点评

学习了  发表于 2012-4-11 09:09

10 个回复

倒序浏览
1.子类即父类,动物是一个类,狗是一个类,而狗是动物的子类,我们可以说狗是动物(子类是父类),而不能说动物是狗(父类是子类);
2.子类的对象赋值给父类,这里用到了多态性。多态是面向对象的一个重要特性。
3.翻译的并不准确,正解是NvRen类型不能转换成NanRen类型。这并不是编译器,而是运行时才能发现此问题。所以编译是能通过的,而运行通不过的。蓝色的上一句在运行时也是会出错的。
4.并不是编译器知道,是“运行器”运行的时候才会知道。此程序编译没有错误!r2只是一个Ren的引用,它没有不能调用子类的方法,必须强制转换成相应的子类才能调用子类的方法。
回复 使用道具 举报
晕 这 了  求教
回复 使用道具 举报
哥们你真强!!!
其实就是多肽,它的好处就是可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化,提高代码复用性。
比如你可以在男人和女人中重写父类中的run方法,但是可以让男人跑的快点,女人跑的慢点。
回复 使用道具 举报
本帖最后由 黄秋 于 2012-3-11 04:29 编辑

多态的理论、好处,我就不啰嗦了,只举一例,有时还必须用到多态:
  1. public static void main(String args[]){
  2.         String[] s={"aa","bb","b3"};
  3.         List<String> list=new ArrayList<String>();
  4.         list=Arrays.asList(s);
  5.         // List<String> list=Arrays.asList(s);
  6.         System.out.println(list);
  7. }
复制代码
1、上面的 list,不能定义为ArrayList,否则报“不兼容的类型”,因Arrays.asList(s) 返回的是List。至于它为何返回List,因 List则实现它的类都可用,象LinkedList。否则,要有多个:asArrayList,asLinkedList,……  
2、如你所见,List<String> list=Arrays.asList(s); 一句顶两句,但有时我们需要定义与赋值分开的,且多态更灵活。追求代码短的话,List<String> list=Arrays.asList("aa","bb","b3"); 一句顶三句。
3、兄弟,不要new List() 啊,原因自己分析。JAVA的规矩就这样,细则也多,慢慢体会,品味吧!
回复 使用道具 举报
本帖最后由 袁野 于 2012-3-11 08:41 编辑

1为什么子类对象可以赋值给父类的引用,而父类对象却不能赋值给子类的引用?

你可以这么想 父亲可以叫你儿子,可以支配你,翻过来 你能管你父亲叫儿子么?你能支配你父亲么,程序 也是一样的道,想不明白程序就想生活
2.为什么允许把子类对象赋值给父类的引用,直接赋值给子类的引用不就行了吗?搞这么复杂!
父类型引用 给子类对象 这属于向上转(没有向上转型 就没有多态)多态的好处 ,提高了代码的扩展和复用性

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
袁野 黑马帝 2012-3-11 08:44:45
7#
回头在看看老师的视频 ,看完一定要去写代码 ,慢慢的理解 不理解就在回头看 看明白在继续学习下去
回复 使用道具 举报
  1. class Ren
  2. {
  3.         String name;
  4.         public void run(){System.out.println("谁赚钱 ");}
  5. }
  6. class NanRen extends Ren
  7. {
  8.         public void run(){System.out.println("男人赚钱 ");}//男人赚钱        
  9. }
  10. class NvRen extends Ren
  11. {
  12.         public void run(){System.out.println("女人洗碗");}//女人洗碗
  13. }
  14. public class TestStudent
  15. {
  16.         public static void main(String args[])
  17.         {
  18.                 Ren r=new NanRen();//可以把男人赋值给人
  19.                 Ren r2=new NvRen();//可以把女人赋值给人
  20.                 //NanRen nr=(NanRen)new Ren();//不能把人当成男人赋值给男人,运行类时会报错的  
  21.                 //NanRen nr2=(NanRen)r2;//也不能把认不出性别的女人赋值给男人,运行类时会报错
  22.                 NvRen nv=(NvRen)r2;//可以把认不出性别的女人赋值给女人,但是必须强制转换为女人后才可以赋值,否则会报错
  23.                 nv.run();        //叫女人去洗碗        
  24.         }
  25. }

复制代码
注:多态: 父类引用指向子类对象
                有继承
                有重写
另外,还涉及到转型问题
回复 使用道具 举报
王杰 黑马帝 2012-3-11 09:55:23
9#
上面说的很好了,你只要知道这是多态的特性了。因为多态能为我们提供代码的扩展性大大比多态带给你的“晕”多得多!所以,这点“晕”是值得的!
回复 使用道具 举报
嗯,谢谢大家了!{:soso__8961432591078930798_3:}
回复 使用道具 举报
{:soso__8961432591078930798_3:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马