Polymorphism (Multi)多态 的使用和注意事项

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

格式;

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

如果父类和子类成员方法名都一样,会用到成员方法的定律的 :右边new谁,就先用谁。

或者;

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

 

=============================================

多态中,成员变量的使用特点。

1,直接通过对象名称访问成员变量,看等号左边是谁,就优先用谁,没有则往上找。

2,间接通过成员变量,看该方法属于谁,优先用谁,没有则往上找。

 

示范;

父类:

1 public class Fu {
2     int num = 10;
3 
4     public void show() {
5         System.out.println(num);
6     }
7 
8 }

 

子类;

1 public class Zi extends Fu {
2     int num = 20;
3 
4     int age = 10;
5 
6 
7 }

 

实现类;

 1 public class Demo01MultiField {
 2     public static void main(String[] args) {
 3         //使用多态的写法,父类引用指向子类对象
 4         Fu obj = new Zi();
 5         //直接通过对象名称访问成员变量,看等号左边是谁,就优先用谁,没有则往上找。
 6         System.out.println(obj.num); //10
 7 
 8         System.out.println("=========================");
 9 
10         //子类没有覆盖重写,就是父类:10。
11         //子类如果覆盖重写,就是子类:20。
12         //间接通过成员变量,看该方法属于谁,优先用谁,没有则往上找。
13         obj.show();//10
14 
15 
16     }
17 
18 
19 }

 

 

 

多态中成员方法的使用特点:

 

  在多态的代码中,成员方法的访问规则是;
  看new的是谁,就先用谁。没有则往上找。

 

口决:成员变量:编译看左边,运行还看左边。

成员方法:编译看左边,运行看右边。

示范;

父类;

 1 public class Fu {
 2     int num = 10;
 3 
 4 
 5     public void show() {
 6         System.out.println(num);
 7     }
 8     public void methodFu(){
 9         System.out.println("父类接口特有的方法");
10     }
11 
12 
13 }

 子类:

 1 public class Zi extends Fu {
 2     int num = 20;
 3 
 4     int age = 10;
 5 
 6     public void show() {
 7         System.out.println(num);
 8     }
 9     public void methodZi(){
10         System.out.println("子类接口特有的方法");
11     }
12 
13 
14 }

 

实现类:

 1 public class Demo02MultiMethod {
 2 
 3     public static void main(String[] args) {
 4 
 5         Fu obj = new Zi();
 6         obj.show();//父类和子类都有,优先用子类。
 7         obj.methodFu();//子类没有,父类有,都是用往上找的规律。
 8 
 9 
10         //编译看左边, 左边是Fu当中没有methodZi方法,所以编译器报错。
11         //obj.methodZi();  //错误写法!
12         System.out.println(obj.num);
13 
14 
15     }
16 }

 

 

补充一下,

好处: 无论右边new的时候换成那个子类对象,等号左边调用方法都不会变化。

 

=============================================================== 

 

对象的向上转型。

对象的向上转型,其实就是多态写法。

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

含义:右侧创建一个子类对象,把它当做父类来看到使用。

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

 

类似于;

double num = 100;//正确,int -->double,自动类型转换。

 

 示例;

父类;

1 public abstract class Animal {
2 
3     public abstract void eat();
4 }

 

 

 子类;

1 public class Cat extends Animal {
2     @Override
3     public void eat() {
4         System.out.println("猫吃鱼");
5     }
6 }

 

 

 

 实现类;

public class DemoMain {

    public static void main(String[] args) {

        //对象的向上转型,就是:父类引用指向子类对象。
        Animal obj = new Cat();
        obj.eat();

    }
}

 效果;

 

 

 ============================================

 

 对象的向下转型。

对象的向下转型,其实是一个【还原】的动作。

格式; 子类名称 对象名称 = (子类名称)向上转型对象名;

含义;将父类对象,还原成为本来的子类对象;

注意事项;

A,必须保证在同一个类中操作,(就是说:你在cat子类里操作,可以向下转型cat类的,其他类的不可以,)

B,如果在非本类操作的话,就会报错ClassCastException.

 

示例;

父类代码和向上转型里的父类一样代码。

 

子类在原有的上转型都一样 ,在原基础上加多一个方法就可以了。

(父类不用写 子类方法的抽象方法代码)

 

实现类 ;

//子类名称  对象名称 = (子类名称)向上转型对象名称;
Cat cat = (Cat)obj;
cat.子类方法名();

 

 

 

 

================================================

用 instanceof 关键字进行类型判断。

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

格式;

对象 instanceof 类名称

这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。

 

举例

父类;

1 public abstract class Animal {
2 
3     public abstract void eat();
4
5 }

猫;

子类;

 1 public class Cat extends Animal {
 2     @Override
 3     public void eat() {
 4         System.out.println("猫吃鱼");
 5     }
 6 
 7  8     public void watchHouse() {
 9         System.out.println("猫抓老鼠");
10 
11     }
12 
13 
14 }

 

 

 

狗;

子类;

 1 public class Dog extends Animal {
 2     @Override
 3     public void eat() {
 4         System.out.println("狗吃SHIT");
 5     }
 6 
 7  8     public void watchHouse() {
 9         System.out.println("狗看家");
10 
11     }
12 
13 }

 

类;

 1 public class Demo02InstanceOf {
 2 
 3     public static void main(String[] args) {
 4 
 5 
 6         Animal obj = new Dog();//本来是一只狗
 7         obj.eat();//狗吃SHIT
 8 
 9 
10         //如果希望调用子类特有方法,需要向下转型
11         //判断一下父类引用animal本来是不是Dag
12         if (obj instanceof Dog) {
13             Dog dog = (Dog) obj;
14             dog.watchHouse();
15         }
16         if (obj instanceof Cat) {
17             Cat  cat = (Cat) obj;
18             cat.watchHouse();
19         }
20 
21 
22     }
23 }

 

也可以这样用

 

posted @ 2020-10-10 01:32  ZHU_FENG  阅读(355)  评论(0)    收藏  举报