Java的多态

来源:互联网 发布:软件用户说明书 编辑:程序博客网 时间:2024/06/08 09:04

1.多态

我们知道继承关系是一种”is  A”的关系,也就说子类是父类的一种特殊情况

问题: 子类的对象是动物?
既然子类是一种特殊的父类,那么我们可不可以认为狗对象/猫对象就是动物类型的对象.
Animal  d = new Dog();  //创建一只狗对象
Animal  c  = new Cat();    //创建一只猫对象
--------------------------------------------------------------
当我的代码变成以下的样子的时候,多态就产生了:
Animal    a   =  new    Dog();
对象(a)具有两种类型:
编译类型:  声明对象变量的类型,Animal,表示把对象看出什么类型.
运行类型:  对象的真实类型,Dog.运行类型--->对象的真实类型.
编译类型必须是运行类型的父类/或相同.
当编译类型和运行类型不同的时候,多态就出现了.

所谓多态: 对象具有多种形态,对象可以存在不同的形式.
Animal    a   = null;
                a   =  new    Dog();   //a此时表示Dog类型的形态
                a   =  new    Cat();    //a此时表示Cat类型的形态
--------------------------------------------------------------------
多态的前提:可以是继承关系(类和类)/也可以是实现关系(接口和实现类),在开发中多态一般都指第二种.
--------------------------------------------------------------------
我家里养了一只动物,名字叫”乖乖”,此时”乖乖”可以有多种形态;
                               乖乖  是狗,  乖乖的叫声: one one one.
                               乖乖  是猫,  乖乖的叫声: 喵    喵    喵.
多态的特点:
            把子类对象赋给父类变量,在运行时期会表现出具体的子类特征(调用子类的方法).
             Animal a = new Dog();

2多态的好处:

需求:给饲养员提供一个喂养动物的方法,用于喂养动物.

没有多态:
发现,针对于不同类型的动物,我们得提供不同的feed方法来喂养.我想,只提供一个方法,就能统一喂养所有动物

.
存在多态:
统一了喂养动物的行为。


从上述例子,可以得知多态的作用:当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化。

3.多态时方法调用问题

多态时方法调用问题:
前提:必须先存在多态情况
存在父类:SuperClass,子类:SubClass,方法:doWork.
--------------------------------------------------------------------
测试代码:
 SuperClass clz =  new   SubClass();//多态
 clz.doWork();//???输出什么结果.

情况1: doWork方法存在于SuperClass中,不存在于SubClass中.
//父类class SupClass {public void doWork(){System.out.println("SupClass.doWork");}}//子类class SubClass extends SupClass{}//测试类class TestDemo{public static void main(String[] args){SupClass clz = new SubClass();clz.doWork();}}
此时执行结果:编译通过,执行SuperClass的doWork方法.
应该先从SubClass类中去找doWork方法,找不到,再去父类SuperClass类中找.

情况2: doWork方法存在于SubClass中,不存在于SuperClass中.
//父类class SupClass {}//子类class SubClass extends SupClass{public void doWork(){System.out.println("SubClass.doWork");}}//测试类class TestDemo{public static void main(String[] args){SupClass clz = new SubClass();clz.doWork();}}
此时执行结果: 编译错误.因为编译时期,会去编译类型(SuperClass)中找是否有doWork方法:
                找    到:编译通过.
                  找不到:编译报错.

情况3: doWork方法存在于SuperClass和SubClass中.
//父类class SupClass {public void doWork(){System.out.println("SupClass.doWork");}}//子类class SubClass extends SupClass{public void doWork(){System.out.println("SubClass.doWork");}}//测试类class TestDemo{public static void main(String[] args){SupClass clz = new SubClass();clz.doWork();}}
此时执行结果: 编译通过,执行SubClass的doWork方法.
      在运行时期,调用运行类型(SubClass)中的方法.

情况4: doWork方法存在于SuperClass和SubClass中,但是doWork是静态方法.
//父类class SupClass {public static void doWork(){System.out.println("SupClass.doWork");}}//子类class SubClass extends SupClass{public static void doWork(){System.out.println("SubClass.doWork");}}//测试类class TestDemo{public static void main(String[] args){SupClass clz = new SubClass();clz.doWork();}}
此时执行结果: 编译通过,执行SuperClass的doWork方法.
    静态方法的调用只需要类即可.如果使用对象来调用静态方法,其实使用的是对象的编译类型来调用静态方法.和对象没有关系.通过反编译工具可以查看结果为直接使用编译类型类名调用:SuperClass.doWork();


原创粉丝点击