面向对象——多态

多态

1extends继承或者implements实现,是多态性的前提。

2. 一个对象拥有多种形态,这就是:对象的多态性。例如:小明是一个对象,这个对象既有学生形态,也有人类形态。

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

// 格式:继承
父类名称 对象名 = new 子类名称();
// 或者格式:接口
接口名称 对象名 = new 实现类名称();

4. 访问成员变量的两种方式:

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

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

5. 在多态的代码当中,成员方法的访问规则是:看new的是谁,就优先用谁,没有则向上找。

总结:(编译只的是编译时,即eclipse、IDEA等集成软件中敲代码时;运行时点击运行后)

  • 成员方法:编译看左边,运行看右边。
  • 成员变量:编译看左边,运行还看左边。

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

7. 对象的向上转型,其实就是多态写法:格式:父类名称 对象名 = new 子类名称();

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

b. 注意事项:

向上转型一定是安全的。从小范围转向了大范围。
弊端:对象一旦向上转型为父类,那么就无法调用子类原本持有的内容。

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

a. 格式:子类名称 对象名 = (子类对象) 父类对象;

b. 含义:将父类对象,【还原】成本来的子类对象。

c. 注意事项:(以父类:动物类 子类:猫类 狗类为例)

必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。

如果对象创建的时候不是猫是狗,现在非要向下转型成为猫,就会报错<ClassCastException 类转换异常>。

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

a. 格式: 对象 instanceof 类名称

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

10. 代码案例

package cn.sunxn.interfacetest.demo06;

public abstract class Animal {

    public abstract void eat();
}
package cn.sunxn.interfacetest.demo06;

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    // 子类特有方法
    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
package cn.sunxn.interfacetest.demo06;

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃SHIT");
    }

    public void watchHouse() {
        System.out.println("狗看家");
    }
}
package cn.sunxn.interfacetest.demo06;

/**
 * 向上转型一定是安全的,没问题的,正确的。但是也有一个弊端:
 * 对象一旦向上转型为父类,那么就无法调用子类原本特有的内容
 * 解决方案:对象的向下转型【还原】
 */
public class Demo01Main {

    public static void main(String[] args) {
        // 对象的向上转型,就是:父类引用指向子类对象。
        Animal animal = new Cat(); // 本来创建的时候就是一只猫
        animal.eat();
     // animal.catchMouse(); // 编译错误!对象一旦向上转型为父类,那么就无法调用子类原本持有的内容。

        // 向下转型,进行“还原”动作
        Cat cat = (Cat) animal;
        cat.catchMouse(); //猫抓老鼠

        // 下面是错误的向下转型
        // 本来new的时候是一直猫,现在非要当成狗
        // 错误写法,编译不会报错,但是运行会出现异常
        // ClassCastException类转换异常
        /*Dog dog = (Dog) animal;
        dog.watchHouse();*/
    }
}
package cn.sunxn.interfacetest.demo06;

/**
 * 如何才能知道一个父类引用的对象,本来是什么子类?
 */
public class Demo02Instanceof {

    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.eat();

        // 如果希望调用子类特有方法,需要向下转型
        // 判断一下父类引用animal本来是不是Dog
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        // 判断一下animal本来是不是Cat
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }

        giveMePet(new Dog());
    }

    public static void giveMePet(Animal animal) {
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }
    }
}

 

posted @ 2019-06-27 20:03  sunxn77  阅读(109)  评论(0编辑  收藏  举报