黑马程序员技术交流社区

标题: 关于多态的小问题,求解 [打印本页]

作者: 郑雪    时间: 2013-4-27 19:40
标题: 关于多态的小问题,求解
本帖最后由 郑雪 于 2013-4-28 10:48 编辑

多态的体现是父类的引用指向了自己的子类对象,父类的引用也可以接受自己的子类对象。这里,父类的引用可以接收自己的子类对象是什么意思?
多态的前提:必须是类与类之间有关系,要么继承,要么实现。通常还有一个前提是存在覆盖。这里为什么还要单独强调覆盖呢?不理解。

作者: 杨同旺    时间: 2013-4-27 19:44
本帖最后由 杨同旺 于 2013-4-27 21:38 编辑

只所以要求父类引用指向子类对象,是面向对象语法这样设计的,因为这样设计有好处:
好处就是父类可以调用 子类中的方法了,
可以认为父类一时间无法完成某个功能,就让子类去实现,而父类自己就等着调用就可以了,它不用管子类是怎么实现的,只管用,扩展性和分层思想就实现了,
多态举例:
  1. class Person
  2. {
  3.         void method()
  4.         {
  5.                 System.out.println("我是父类");
  6.         }
  7. }

  8. class Student extends Person
  9. {
  10.         @Override
  11.         void method()
  12.         {
  13.                 System.out.println("我是子类");
  14.         }
  15. }
  16. public class TestTest
  17. {
  18.         public static void main(String[] args)
  19.         {
  20.                 Person p = new Student(); //父类引用指向子类对象
  21.                 p.method(); //结果是,"我是子类"
  22.         }

  23.      
  24. }
复制代码

作者: 海不扬波    时间: 2013-4-27 20:28
多态体现在父类引用或者接口的引用指向了自己的子类对象。这样提高敢程序的扩展性。
多态的前提是必须要有关系,比如继承,或者实现。多态的出现,思想上也做着变化,以彰是创建对象并指挥对象做事情,有了多态以后,我们可以找到对象的共性类型,
直接操作共性类型即可,这样,可以指挥一批对象做事情,即通父类或接口实现。
如以下:
class 毕姥爷{
    void 讲课(){
        System.out.println("企业管理");
    }
    void 钓鱼(){
        System.out.println("钓鱼");
    }
}
class 毕老师 extends 毕姥爷{
    void 讲课(){
        System.out.println("JAVA");
    }
    void 看电影(){
        System.out.println("看电影");
    }
}
class {
    public static void main(String[] args) {
        毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。
//      x.讲课();
//      x.看电影();  //错误.
        毕老师 y = (毕老师)x; //将毕姥爷类型强制转换成毕老师类型。
        y.看电影();//在多态中,自始自终都是子类对象在做着类型的变化。
    }
}

作者: 蚂蚁搬家    时间: 2013-4-27 20:52
杨同旺 发表于 2013-4-27 19:44
多态是面向对象语法中较难理解的
只所以要求父类引用指向子类对象,是面向对象语法故意这样设计的,为什么这 ...

重写是在实现接口或者继承抽象类的时候才会必须用吧。

不知以下总结对不对,不对的各位兄弟提醒一下啊,先谢了!

父类对象的引用既可以指向父类对象,又可以指向子类对象,根据引用当前指向的不同,可以调用不同对象的方法,这就是多态;

通过父类对象引用只能调用子类中从父类继承过来的成员,而不能调用子类内自己定义的成员;

如果在子类中对父类的方法进行了重写,在调用这个方法时,系统会自动根据当前引用的真正类型来选择调用父类中的方法还是子类中的方法;
作者: 337091921    时间: 2013-4-27 20:53

/*
多态的前提
1,必须有关系,【继承】,实现,而且要把子类【定义】为【父类类型】
2,要有覆盖



*/





abstract class Animal//用为动物是抽象的  不知道具体是什么样子;所一定义抽象的类
{
         public void eat()
         {}
}
class Cat extends Animal
{
         public void eat ()//因为父类是抽象的,必须要覆盖
         {
         System.out.println("chi yu");
         }
         public void dai()
         {
         System.out.println("逮老鼠");
         
         }
}
class Dog extends Animal
{
         public void eat()
         {
         System.out.println("吃骨头");
         }
         public void kanjia()
{
                 System.out.println("看家");
}
}
        class Java
        {
        public static void main(String []args)
                {
               methond(new Cat());//因为调用函数没有返回值,所以直接调用,前面不加类的类型看看前面的函数的调用,别忘了
                   Dog d=new Dog();//这行和下行就等于  methond(new Dog())
                   methond(d);//这里面的d就等于new  Dog‘
            d.kanjia();
        }

        public static void methond(Animal a)//函数的调用,与主函数必须在一个类中,如果把animal转换成cat ,就意味这只能给猫这么一个变量//,狗就不可以了
                {
                a.eat();//函数的调用
        }
        }//把调用函数和主函数包含在一块,
            //如果是对象的调用就必须单个单个,与函数的调用不一样啊
作者: 黑马-秦歌    时间: 2013-4-27 21:12
多态体现的是一种模板方法的设计模式。父类中定义了子类共有的方法。 一些相同代码在父类中实现。 一些子类可能有特殊的方法实现细节。父类将该方法定义为 abstract 抽象的。 子类继承父类后 需要覆盖抽象方法实子类特有的功能。
作者: 蔚蓝小嗨    时间: 2013-4-27 21:25
多肽成员函数的特点:
程序编译的时候:引用型变量所属的类中是否有调用的方法,如果有,编译通过,否则,编译失败。
程序运行的时候:对象所属的类中是否有调用的方法。
如果没有覆写的话,就没有可以调用的方法了。
作者: xiaohu1218    时间: 2013-4-27 23:35
多态可以理解成某一类事物的多种存在形态;
比方说:猫和狗都是动物,你可以说这只猫(这条狗)真可爱,你也可以说这个小动物真可爱;但是你说这个小动物真可爱的时候,你就不能强制的将小动物改成猫(狗),因为可爱的动物有很多。
这就是说:定义 父类(小动物)的对象实例可以指向 猫/狗实例对象;
而定义猫/狗 实例对象时,却不能直接指向动物的实例对象(可爱的小动物不一定就是猫/狗),除非进行强制类型转换,将小动物认定是猫(狗),结果如何,我还没试过;
关于覆盖:多种存在形态肯定有覆盖。
可以将猫和狗都有吃东西这个共性,但是它们吃的东西不一样:狗吃骨头,猫吃鱼;
这时候子类狗(猫)就要重写父类的方法(abstract voidA eat());
当然还可以定义成别的动物:熊猫啊,老虎什么的。
这样就大大提高了程序的扩展性,但是这时候只能使用父类的引用访问父类的成员。

作者: 郑雪    时间: 2013-4-28 09:22
杨同旺 发表于 2013-4-27 19:44
只所以要求父类引用指向子类对象,是面向对象语法这样设计的,因为这样设计有好处:
好处就是父类可以调用 子 ...

父类引用指向子类对象我是知道的,我想知道的是父类引用可以接收自己的子类对象是怎么回事?
作者: 杨同旺    时间: 2013-4-28 10:36
本帖最后由 杨同旺 于 2013-4-28 11:20 编辑

举个例子.
  1. public class Test
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 new Test().someMethod(new Student());
  6.         }

  7.         void someMethod(Person p)
  8.         {
  9.                 p.method();
  10.         }

  11. }

  12. class Person
  13. {
  14.         void method()
  15.         {
  16.                 System.out.println("实现");
  17.         }
  18. }

  19. class Student extends Person
  20. {
  21.         @Override
  22.         void method()
  23.         {
  24.                 System.out.println("实现");
  25.         }
  26. }
复制代码

作者: 郑雪    时间: 2013-4-28 10:47
杨同旺 发表于 2013-4-28 10:36
父类引用可以接收自己的子类对象,用代码来说明吧.

很清楚了,谢谢。




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