黑马程序员技术交流社区

标题: java多态问题? [打印本页]

作者: 文江江    时间: 2014-3-13 17:38
标题: java多态问题?
本帖最后由 文江江 于 2014-3-13 23:20 编辑

java 中的多态怎么理解啊?(很含糊)它实现的机制是怎么样的,求解?
作者: chen20134    时间: 2014-3-13 17:49
java 中的多态
打个比方  
对于吃饭这件事.中国人是用筷子吃.   外国人呢用刀和差子
就是同一件事,不同的对象做起来,产生的效果会不一样....

多态靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
java多态性的机制
1 重载:有同样的方法名称不同的参数列表。a(){} a(String b){}...
2 重写(也称覆盖):即可以重新编写与父类同名方法形象的称之为重写(覆盖)。

作者: l939    时间: 2014-3-13 18:13
多态:
        -体现在父类的引用指向了自己的子类(也可以说父类的引用可以接收自己的子类对象)
        -我们之前学的时候不是都是用子类来获取子类的功能吗,父类只是用来提供共有的功能
        -而学了多态后,我们就可以通过父类对象的引用来获取子类的功能,这样子大大的提高了扩展性,当然,它也有弊端,那就是它访问的成员是父类的成员,也就是说子类的特有功能父类引用无法直接获取的。必须得添加判断来获取,但是如果子类成员过多,并且特有功能也多的时候,这样就降低的多态的扩展性。
       -下面我就通过一段代码来说明多态的体现吧:
abstract class Student//定义了一个学生父类
{
        abstract void study();//因为不同的学生学习方法不同,所以定义了一个抽象功能
        void sleep()
        {
                System.out.println("躺着睡");//定义了共同的睡觉形式
        }
}

interface Smoking//这是接口的使用,因为现在的学生有些抽烟,所以扩展了一个抽烟接口
{
        public abstract void smoke();
}
class BaseStudent extends Student implements Smoking//定义了基础学生子类对象,继承于学生,并拓展了抽烟接口功能(就是说基础学生会抽烟)
{
        void study()
        {
                System.out.println("base study");//复写父类,并定义自己的学习方式
        }
        void sleep()
        {
                System.out.println("坐着睡");//覆盖了父类的睡觉功能,并定义了自己的新的睡觉模式
        }
        public void smoke()
        {
                System.out.println("抽烟");
        }
}

class AdvStudent extends Student//定义了高级班学生子类,继承于学生
{
        void study()
        {
                System.out.println("adv study");
        }
}
class GetStudent//定义了一个类,来体现多态的体现
{
        public static void getStudent(Student s)//定义了一个功能,获取学生,实际的表现可以看成是:Student s = new  BaseStudent()  /  new AdvStudent()因为只定义了这两个子类,如果再定义了新的子类,也一样可以这样来看。
        {
                s.study();
                s.sleep();
                if(s instanceof BaseStudent)//这里的判断是因为基础班学生拓展了抽烟的行为,所以需要进行特有功能获取。
                {
                        BaseStudent b= (BaseStudent)s;//这是一个向下转型的过程。是让父类可以获取到子类的特有功能。
                        b.smoke();
                }       
               
        }
}
class DuotaiTest1
{
        public static void main(String[] args)
        {
                GetStudent gs = new GetStudent();
                gs.getStudent(new BaseStudent());
                gs.getStudent(new AdvStudent());
        }
}
希望这对楼主有些帮助吧-。-
        

作者: 黄翔    时间: 2014-3-13 18:14
有一个用来判断是否应该设计为继承关系的简单规则,这就是“is-a”规则,它表明子类的每个对象也是超类的对象。例如:每个经理都是雇员,因此,将Manager类设计为Employee类的子类是显而易见的,反之,并不是每一名雇员都是经理。

“is-a”规则的另一种表述法是置换法则。它表明程序中出现超类对象的任何地方都可以用子类对象置换。例如,可以将一个子类的对象赋给超类变量。
Employee e;
e = new Employee(...);
e = new Manger(...);
在java语言中,对象变量是多态的。一个Employee变量既可以引用一个Employee类对象,也可以引用一个Employee类的任何一个子类的对象。
然而,不能将一个超类的引用赋给子类的变量。

作者: 菜小徐    时间: 2014-3-13 18:26
多态:指同一个实体同时具有多种形式
好比,你去面馆吃面,说我要吃面,那么;老板给我牛肉面,鸡蛋面等都可以,
这就是说"面"有多种形态,也就是说实体有多种形态;
编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给变量的对象决定。
如果编译时类型和运行时类型不同,就出现多态。

Eg:
前提:Student  extends   Person:

Person p = new Person();
Student s = new Student();
Person p = new Student();//多态

引用关系:父类变量指向子类实例对象

实现多态的机制:
父类的引用变量可以指向子类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的真正实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

多态的作用:
把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
只修改方法的实现,不必修改方法的声明
继承是多态产生的前提条件;

分类:
编译时多态:方法重载
运行时多态:方法覆写

Eg:
package test;

class Dog{
        void eat(){
                System.out.println("一般的狗吃一般的狗粮!");
        }
}

class HashDog extends Dog{
        void eat(){
                System.out.println("哈士奇吃哈士奇的狗粮!");
        }
}

class ZangAoDog extends Dog{
        void eat(){
                System.out.println("藏獒吃藏獒的狗粮!");
        }
}

//定义一个动物园喂的方法
class Zoo{
       
        void feed(Dog d){
                d.eat();
        }
       
}

public class Demo11 {
        public static void main(String[] args) {
               
                Dog hd = new HashDog();
               
                Dog zd = new ZangAoDog();
               
                Zoo z = new Zoo();
                z.feed(hd);
                z.feed(zd);
        }
}

输出:
哈士奇吃哈士奇的狗粮!
藏獒吃藏獒的狗粮!

作者: 艮昕辶    时间: 2014-3-13 22:29
标题: 借用了版主的代码加了一个类的冲载
  1. class Dog{
  2.        private String s="狗肉";
  3.         void eat(){
  4.                 System.out.println("一般的狗吃一般的狗粮!");
  5.         }
  6.        void eat(String s)
  7.       {
  8.         System.out.println("有的狗也吃"+s);
  9.       }
  10. }

  11. class HashDog extends Dog{
  12.         void eat(){
  13.                 System.out.println("哈士奇吃哈士奇的狗粮!");
  14.         }
  15. }

  16. class ZangAoDog extends Dog{
  17.         void eat(){
  18.                 System.out.println("藏獒吃藏獒的狗粮!");
  19.         }
  20. }

  21. //定义一个动物园喂的方法
  22. class Zoo{
  23.         
  24.         void feed(Dog d){
  25.                 d.eat();
  26.         }
  27.         
  28. }

  29. public class Demo11 {
  30.         public static void main(String[] args) {
  31.                
  32.                 Dog hd = new HashDog();
  33.                
  34.                 Dog zd = new ZangAoDog();
  35.                
  36.                 Zoo z = new Zoo();
  37.                 z.feed(hd);
  38.                 z.feed(zd);
  39.         }
  40. }
复制代码


作者: liuqufei    时间: 2014-3-14 00:05
前面说了很多,都很专业。不知道你是不是对多态的思想和好处不了解。
我就举个例子,人类(父类)、男人(子类)、我(男人的实例)。
我去一个地方,有餐馆,有澡堂。
餐馆只提供人类的食品,经理是不是对看门的服务生说人可以进来,宠物不可以进来就行了,没有必要说“男人可以进,女人可以进,小孩可以进,老人可以进,黑人可以进,白人可以进......“那我这个男人的实例只要向上转换成人的类型,在门口向服务生报一声”我是人“不就可以了。同样一个女士也向上转换成人的类型就可以了。
到了澡堂,当然要向下转换回男人的身份进去。
这样说多态的好处不知能理解不。




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