• Java基础之面向对象之多态


    多态

    什么是多态:父类引用指向子类对象

    猫 x = new 猫();

    动物 y = new 猫();

    多态的三个前提是?

    1. 要有继承实现关系
    2. 要有父类引用指向子类对象.
    3. 要有方法的重写

     

    格式:

    /*

    代码当中体现多态性,其实就是一句话:父类引用指向子类对象。

    格式:

    父类名称 对象名 = new 子类名称();

    或者:

    接口名称 对象名 = new 实现类名称();

     */
    
       public static void main(String[] args) {
    
            // 使用多态的写法
    
            // 左侧父类的引用,指向了右侧子类的对象
    
            Fu obj = new Zi();
    
            obj.method();
    
            obj.methodFu();
    
        }

    多态中调用成员的特点?

    a成员变量:
    /*
    访问成员变量的两种方式: 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。 2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。 public class Demo01MultiField { public static void main(String[] args) { // 使用多态的写法,父类引用指向子类对象 Fu obj = new Zi(); System.out.println(obj.num); // 父:10 // System.out.println(obj.age); // 错误写法! System.out.println("============="); // 子类没有覆盖重写,就是父:10 // 子类如果覆盖重写,就是子:20 obj.showNum(); } } b成员方法:
    多态中成员方法的使用特点 /* 在多态的代码当中,成员方法的访问规则是: 看new的是谁,就优先用谁,没有则向上找。 口诀:编译看左边,运行看右边。 对比一下: 成员变量:编译看左边,运行还看左边。 成员方法:编译看左边,运行看右边。
    */ public class Demo02MultiMethod { public static void main(String[] args) { Fu obj = new Zi(); // 多态 obj.method(); // 父子都有,优先用子 obj.methodFu(); // 子类没有,父类有,向上找到父类 // 编译看左边,左边是Fu,Fu当中没有methodZi方法,所以编译报错。 // obj.methodZi(); // 错误写法! } }

    c静态成员:(稍微看下)

    编译看左边, 运行看左边

    思路: 静态修饰的成员跟类相关, 跟对象没有关系

    Animal a = new Dog();

    System.out.prinltn(a.num); // a.num --> 在编译的时候也会翻译成 Animal.num

    这时候, 类名是谁, 调用的数据就是谁的.

    使用多态的好处

    /**无论右边new的是那个子类对象, 左边都不会发生变化,**/

    提高代码的扩展性:

    可以将一个方法的形参定义为父类类型, 该方法就可以接受这个父类的任意子类对象了

     

    useAnimal(new Dog());
    useAnimal(new Cat());

    public static void useAnimal(Animal a){

    }

    使用多态的弊端

    弊端:
                        
      不能调用子类特有的属性和行为.
                            
        问题: 非要调用怎么办?
                                
         向下转型.
                                        
         向下转型的注意事项:
                                
                         1. 向下转型必须发生在子父类的关系当中
                               Animal a = new Dog();
                               Cat c = (Cat)a;        // Dog和Cat没有子父类关系.
                                        
                         2. 向下转型必须要事前转上去, 才能转下来
                                    
                               Animal a = new Animal();
                               Dog d = (Dog)a;        // 没有提前转上去.
                                        
                                
                        正确案例:
                              Animal a = new Dog();
                              Dog d = (Dog)a;
    ------------------------------------
    向上转型
    1.多态的使用就是向上转型
    1.Animal a = new Dog();// 父类引用指向子类对象

    注意事项:向上转型一定是安全的,从小范围转向大范围.

    类似于double num=100; 正确 今天->double 自动类型转换

    向下转型

    弊端:不能访问子类的特有方法.

    解决方案:用对象的向下转型.

     Animal a = new Dog();/**多态的使用就是想上转型*/
      Dog d = (Dog)a;     /**父类的a 转型为Dag 的  d*/

     

    注意:  向下转型的强转必须发生在子父类的关系内, 而且必须是转上去, 才能转下来.

    什么情况下需要用到向下转型?

    答:  为了调用子类特有的属性和行为.

    ClassCastException(类型转换异常): 引用数据类型的强转, 出现了错误.

     

    例如:  

    1. Animal a = new Cat();

    Dog d = (Dog)a; --> Cat和Dog之间没有子父类关系, 不能强转

     

    2. Animal a = new Animal();

       Dog d = (Dog) a; --> 必须要先进行向上转型, 才可以将数据正常的转型下来.

     

    如果一个方法的参数是一个类名(多态     其实调用传入的是地址值) ???

     

    用instanceof关键字进行类型判断,(稍微看一下,不是重点,就是一个方法,理解)

    >* instanceof关键字的作用是什么?

     

    你好,这个关键字的用法是:A instanceof B ,返回值为boolean类型,用来判断A是否是B的实例对象或者B子类的实例对象。如果是则返回true,否则返回false。
    如:Person p = new Person() ; //
    Man m = new Man() ; //Man是Person的子类
    Animal a = new Animal() ;
    m instanceof Man //返回true
    m instanceof Animal//返回false
    m instanceof Person//返回true

    总结:

    1. 判断左边的引用, 是否是右边的数据类型.

    /*

    如何才能知道一个父类引用的对象,本来是什么子类?

    格式:


    对象 instanceof 类名称 这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。 */ public class Demo02Instanceof { public static void main(String[] args) { Animal animal = new Dog(); // 本来是一只狗 animal.eat(); // 狗吃SHIT // 如果希望掉用子类特有方法,需要向下转型 // 判断一下父类引用animal本来是不是Dog if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.watchHouse(); } // 判断一下animal本来是不是Cat if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.catchMouse(); } giveMeAPet(new Dog()); } public static void giveMeAPet(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.watchHouse(); } if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.catchMouse(); } } }

     

    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    【WPF】城市级联(XmlDataProvider)
    【C#】利用反射构建实体
    毕业档案保存
    【WPF】淡入淡出切换页面
    【C#】Lamada表达式演变过程
    【C#】实现INotifyPropertyChanged的3种方法
    【Unity】矩阵运算
    (win7/8/10)鼠标右键添加按下SHIFT键时弹出带管理员权限的“在此处打开命令窗口”
    如何给grldr.mbr和grldr改名
    常用的时间同步服务器地址
  • 原文地址:https://www.cnblogs.com/lihailong/p/11576149.html
Copyright © 2020-2023  润新知