黑马程序员-java多态

来源:互联网 发布:小米线刷软件 编辑:程序博客网 时间:2024/05/18 12:43

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------



面向对象编程有三个特征,即封装、继承和多态

封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护数据。

继承是为了重用父类代码,同时为实现多态性做准备。

下面我们介绍多态。


多态的体现:

父类型的引用可以指向子类型的对象。如,

Parent p=new Child(); //Child类继承了Parent类


多态的好处:

大大提高程序的扩展性。因为java只允许单继承,这样虽然保证了继承关系的简单明了,但也势必在功能上有很大的限制。多态的引入用于弥补这点不足,另外,抽象类和接口也是解决单继承规定限制的重要手段。

多态的弊端:

虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员。


下面用例子来讲解多态中几个重要的概念

例1:

public class PolyDemo{    public static void main(String[] args)    {                Animal a1=new Cat();  //自动向上类型转换        Animal a2=new Dog();//调用子父类共有方法a1.eat();             //动态绑定a2.eat();//调用子类特有方法//a1.catchMouse();    //错误,父类中没有catchMouse()方法Cat c=(Cat)a1;      //强制向下类型转换Dog d=(Dog)a2;        c.catchMouse();       d.guardHouse();           //Animal a3 = new animal();        //Cat c2 = (Cat)a3;   //错误,不能将父类对象转成子类类型    }}class Animal{    public void eat()    {        System.out.println("Animal is eating!");    }}class Dog extends Animal{    public void eat()    {        System.out.println("Dog is eating!");   //Dog类重写了eat()方法    }public void guardHouse()                //Dog类特有的方法{System.out.println("Dog is guarding house!");}}class Cat extends Animal{    public void eat()    {        System.out.println("Cat is eating!");    }    public void catchMouse()    {        System.out.println("Cat is catching mouse!");    }}

输出结果:

Cat is eating!Dog is eating!Cat is catching mouse!Dog is guarding house!
由此例,我们讲解以下几个概念:
1、类型转换

1)自动向上类型转换(Upcast):将子类型转为父类型

对于向上的类型转换,不需要显示指定转换类型,类型自动提升

2)强制向下类型转换(Downcast):将父类型转化为子类型

对于向下的类型转换,必须要显示指定转换类型,即必须使用强制类型转换

注意:由上例可知,我们能转换的是父类引用指向子类对象时,该引用既可以被提升,也可以被强制转换。多态自始至终都是子类对象在做着变化


2、多态时成员的特点

1)成员函数:

当父类引用指向子类对象时,该引用变量可以调用子父类共有的成员方法,而不能调用子类中定义但父类中没有的成员方法(否则会编译失败)。

同时,对于父类中定义的成员方法,如果子类重写了该方法,那么父类引用将会调用子类中的该方法,而这就是动态绑定

简单总结:成员方法在多态调用时,编译时期参阅引用变量所属类中是否有调用的方法,如果有则通过,否则编译失败;在运行时期参阅被引用对象所属的类中的成员方法。

2)成员变量:

无论编译时期还是运行时期,都参阅引用变量所属类中的成员变量。

3)静态成员方法:

无论编译时期还是运行时期,都参阅引用变量所属类中的静态成员方法。


下面我们再来看一个例子,以便更好的理解java的多态性

例2:

class PolyDemo {public static void main(String[] args) {A a1 = new A();  A a2 = new B();          B b = new B();          C c = new C();           D d = new D();           System.out.println(a1.show(b));             System.out.println(a1.show(c));            System.out.println(a1.show(d));            System.out.println(a2.show(b));            System.out.println(a2.show(c));           System.out.println(a2.show(d));            System.out.println(b.show(b));             System.out.println(b.show(c));             System.out.println(b.show(d)); }}class A {  public String show(D obj){  return ("A and D");      }       public String show(A obj){          return ("A and A");      }   }   class B extends A{      public String show(B obj){          return ("B and B");      }      public String show(A obj){          return ("B and A");      }   }  class C extends B{}   class D extends B{} 
输出结果:

A and AA and AA and DB and AB and AA and DB and BB and BA and D

在分析结果前,我们先讲一下方法调用的优先问题,优先级由高到低依次为:

this.show(O)>super.show(O)>this.show((super)O)>super.show((super)O)

现在我们来分析结果。1~3的结果应该很好理解。

以4为例,引用变量为a2,类型是A,则this是a2。于是它先在类A中寻找show(B obj)方法,未找到;然后到A的super类(父类)中找,然而A没有父类;于是它转到第三优先级this.show((super)obj),此时this为a2,而O(即B)的父类为A,故在A中寻找show(A obj),类A有此方法。但因为a2引用的是B的一个对象b,而B中重写了A的show(A obj)方法,根据动态绑定,故最终调用的是B中的show(A obj)方法,输出“B and A”。

例5~9同理可得。


下面讲一些多态的应用

需求:电脑运行实例

/*未考虑多态的思考方式(不好)*/class MainBoard{public void run(){System.out.println("主板运行!");}public void useNetCard(NetCard c)    //加载一个网卡,则添加一段调用网卡的代码;若还要加载声卡等,{                                    //则再添加调用声卡的代码。扩展性极差。c.open();c.close();}}class NetCard{public void open(){System.out.println("网卡打开!");}public void close(){System.out.println("网卡关闭!");}}/*考虑多态的思考方式*/class MainBoard{public void run(){System.out.println("主板运行!");}public void usePCI(PCI p){if (p!=null){p.open();p.close();}}}interface PCI{public abstract void open();public abstract void close();}class NetCard implements PCI{public void open(){System.out.println("网卡打开!");}public void close(){System.out.println("网卡关闭!");}}



---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

0 0
原创粉丝点击