Java 面向对象 第三部分(多态)

Java面向对象的多态性

一. 概念

定义:多态可以理解为事物存在的多种体现形态,多态是在运行期间,判断引用实际类型,根据实际类型调用相应的方法。

举例:比如说人又男女之分,我们可以说男人是人,也可以说是男人。动物有猫、狗,我们可以说猫是动物,动物也是猫中的一种。
:男人,女人

动物:猫,狗

x = new();

动物 x = new();

二. 多态的体现形式

1.     父类的引用指向了自己子类的对象

2.     父类的引用可以接收子类的对象

三. 多态的前提

1.     必须是类与类之间有关系,要么继承,要么实现

2.     通常还有一个前提,存在覆盖

四. 多态的有点和缺点

1.     优点

A.     多态出现大大提高了程序的扩展性。

2.     缺点

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

不可预先使用子类。这是由于,子类在父类之后加载,此时还没有子类被加载,如果要使用子类中的成员,就必须使用强制类型转换,但是发生强制类型转换之前是一定发生过多态的。

注意:

1、一定不能将父类的对象转换成子类类型。
2
、可转换的:父类引用指向自己子类的对象时,该引用可被提升,也可被强制转化。
3
、多态自始至终均为子类对象在做变化。

/*分析: 

    1、定义一个动物类这个超类类型(抽象),含有一个吃饭的抽象方法 

     2、定义子类(如猫,狗等),含有自己的方法(猫:抓老鼠;狗:看家) 

     3、用多态实现子类方法 
 */  

 abstract class Animal   //抽象类  

 {  
     abstract void eat();  
 }  

class Cat extends Animal  //Cat继承父类Animal  
{     
    //复写父类的抽象方法  
    void eat(){  
       System.out.println("吃鱼");  
    }  
    //定义自身
    void catchM(){  


       System.out.println("抓老鼠");  

    }  

}  

  

class Dog extends Animal  

{  

      

    //复写父类的抽象方法  

    void eat(){  

        System.out.println("啃骨头");  

    }  

    //定义自身功能  

    void kanJ(){  

       System.out.println("看家");  

    }  

}  

class DuoTaiTest  

{  

    public static void main(String[] args)  

    { 
  

      Animal a1 = new Cat();//多态运用a2.eat();  

       Dosome(a1);  

        Cat c = (Cat)a1;  

        Dosome(c);  

       c.catchM();  

        Animal a2 = new Dog();  

        a2.eat();  

        Dosome(a2);  

        Dog d = (Dog)a2;  

        Dosome(d);  

        d.kanJ();  

    }  

    public static void Dosome(Animal a)  

    {  

        a.eat();  

    }  


五. 在多态的中(父类引用指向子类对象)成员函数的特点

1.     在编译期间:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。

2.     在运行时期:参阅对象所属的类中是否有调用的方法(包括父类继承过来的方法)

3.     简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

六. 多态中(父类引用指向子类对象)成员变量的特点:无论编译和运行,都参考做左边。

七. 多态中(父类引用指向子类对象)静态成员方法特点:无论编译和运行,都调用左边

八. 多态中(父类引用指向子类对象)静态成员变量特点:无论编译和运行,都调用左边

publicclass PloyDemo
{
       publicstaticvoid main(String[] args)
       {
                 /*
                       编译通过
                           Zi z = new Zi();
                           z.method1();//覆盖父类的方法,调用的还是子类覆盖后的
                           z.method2();//覆盖父类的方法,调用的还是子类覆盖后的
                           z.method3();//子类特有的方法
           */
 
        /*
         整个程序编译失败,因为f.method3()在父类中不存在
         Fu f = new Zi();
         f.method1();//覆盖父类的方法,调用的还是子类覆盖后的
               f.method2();//覆盖父类的方法,调用的还是子类覆盖后的
               f.method3();//父类中没有这个方法,编译失败
       */
 
             /*
             调用的是父类的num,无论如何变化是否为静态,调用的都是父类的num
              Fu f = new Zi();
           System.out.println(f.num);
        */
             
             /*
           调用的是子类的num,无论如何变化是否为静态,调用的都是子类的num
           Zi z = new Zi();
        System.out.println(z.num);
       */
                                          /*
                                           子类引用指向子类对象,调用的是子类的 
                                                Zi z = new Zi();
                                                z.method3();//调用的是子类的方法
                                  */
                           
                              /*
                                   method4()是父类静态的方法,调用的一直都是父类的
                                   Fu f = new Zi();
                                   f.method4();//调用的是父类的方法
                             */
       }
}
class Fu
{
       staticintnum = 5;
       void method1()
       {
             System.out.println("fu method_1");
       }
       void method2()
       {
             System.out.println("fu method_2");
       }
       staticvoid method4()
       {
             System.out.println("fu method_4");
       }
}
class Ziextends Fu
{
       staticintnum = 8;
       void method1()
       {
             System.out.println("zi method_1");
       }
       void method3()
       {
             System.out.println("zi method_3");
       }
       static void method4()
       {
             System.out.println("zi method_4");
       }
}


九. 应用练习

/*
需求:
电脑运行实例,
电脑运行基于主板。
*/
interface PCI
{
       publicvoid open();
       publicvoid close();
}
 
class MainBoard
{
       publicvoid run()
       {
             System.out.println("mainboard run ");
       }
//PCI p = new NetCard()//接口型引用指向自己的子类对象。
       publicvoid usePCI(PCI p){
             if(p!=null)
             {
                    p.open();
                    p.close();
                    
             }
       }
}
 
 
class NetCardimplements PCI
{
       publicvoid open()
       {
             System.out.println("netcard open");
       }
       publicvoid close()
       {
             System.out.println("netcard close");
             method();
       }
      
}
class SoundCardimplements PCI
{
       publicvoid open()
       {
             System.out.println("SoundCard open");
       }
       publicvoid close()
       {
             System.out.println("SoundCard close");
       }
}
 
 
class DuoTaiDemo5
{
       publicstaticvoid main(String[] args)
       {
             MainBoard mb =new MainBoard();
             mb.run();
             mb.usePCI(null);
             mb.usePCI(new NetCard());
             mb.usePCI(new SoundCard());
             
       }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值