/* 这个是github上面的连接地址*/

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(); } } }

 

 

posted @ 2019-09-24 06:32  李海龙  阅读(219)  评论(0编辑  收藏  举报