笔记_多态

1. 多态的概述

1.1 多态的概述

  • 同一种事物表现出来的多种形态则称为多态。

    "俊杰" ==> 班长

"俊杰" ==> 儿子

"俊杰" ==> 父亲

"俊杰" ==> 路人甲

1.2 多态的前提

  • 必须有子父类关系或类实现接口关系
  • 必须有方法重写
  • 必须有父类引用指向子类对象或接口引用指向实现类对象

1.3 多态的格式

  • 父类类名 变量名 = new 子类类名();
  • 接口名 变量名 = new 接口实现类();

2. 多态案例

 
 
// 抽象类:动物父类
abstract class Animal{
    public abstract void eat();
    public abstract void sleep();
}
// 子类Dog 继承 动物类
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    @Override
    public void sleep() {
        System.out.println("狗趴着睡");
    }
}
interface Play{
    public void playing();
}
class Cat implements Play{
    @Override
    public void playing() {
        System.out.println("和猫玩耍");
    }
}
// 人类
class Person{
    public void eat() {
        System.out.println("人吃饭");
    }
}
// 学生类
class Student extends Person{
    public void eat() {
        System.out.println("学生吃饭");
    }
}
public class Demo01 {
    public static void main(String[] args) {
        // 创建Dog对象
        Dog d = new Dog();
        // 调用方法
        d.eat();
        d.sleep();
        System.out.println("--------");
        // 使用多态形式
        Animal a = new Dog();
        a.eat();
        a.sleep();
 
        // 使用多态形式:创建猫对象
        Play p = new Cat();
        p.playing();
 
        // 使用多态形式:创建学生对象
        Person stu = new Student();
        stu.eat();
    }
}

3. 多态的注意细节

  • 多态的注意事项

    • 多态情况下,如果子父类出现同名的成员变量时,访问的是父类的成员变量。
    • 多态情况下,如果子父类出现同名的成员方法时,访问的是子类重写后的成员方法
 
 
编译特性
    成员变量:编译看左边,运行看左边。
    成员方法:编译看左边,运行看右边。
成员变量:属于静态绑定
成员方法:属于动态绑定

4. 多态的好处(优点)与弊端(缺点)

  • 多态的缺点

    • 不能访问子类特有的成员:成员变量和成员方法
  • 多态的优点

    • 提高了代码的复用性。
    • 提高了代码的扩展性。
    • 提高了代码的维护性。

5. 多态的使用场景

  • 作为方法的形式参数,可以接收更多数据类型的对象。
  • 作为方法的返回值类型,可以方法更多的数据类型的对象

6. 多态的转型

  • 向上转型:父类引用指向子类对象的过程就是向上转型的结果。
 
Animal a = new Dog();
  • 向下转型:将父类引用强制转换为子类引用的过程
 
 
格式:子类类型 变量名 = (子类类型)父类引用;

7. instanceof关键字

  • 作用:用来判断多态后父类引用到底指向哪个子类类型的对象。
  • 格式:boolean b = 引用变量 instanceof 类名或接口名;
  • 注意事项:如果instanceof关键字后面的是类名,则要求引用变量和类之间有子父类关系。
 
 
/**
 * 抽象类 动物类
 */
public abstract class Animal {
    // 成员方法
    public abstract void eat();
    public abstract void sleep();
}
public class Dog extends Animal implements Play {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
    @Override
    public void sleep() {
        System.out.println("趴着睡");
    }
 
    public void lookHome() {
        System.out.println("老老实实看家");
    }
    @Override
    public void playing() {
        System.out.println("狗玩耍的方法");
    }
}
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    @Override
    public void sleep() {
        System.out.println("猫躺着睡");
    }
    public void catchMouse() {
        System.out.println("猫捉老鼠");
    }
}
public interface Play {
    void playing();
}
/*
* 测试类
*/
public class Demo01 {
    public static void main(String[] args) {
        // 养一只狗对象
        Dog d1 = new Dog();
        // 喂养狗
        /*d1.eat();
        d1.sleep();*/
        // feedDog(d1);
        feedAnimal(d1);
 
        // 再养一只狗
        Dog d2 = new Dog();
        /*d2.eat();
        d2.sleep();*/
        // feedDog(d2);
        feedAnimal(d2);
        // 再养一只狗
        Dog d3 = new Dog();
        /*d3.eat();
        d3.sleep();*/
        // feedDog(d3);
        feedAnimal(d3);
 
        // 养一只猫
        Cat c1 = new Cat();
        /*c1.eat();
        c1.sleep();*/
        // feedCat(c1);
        feedAnimal(c1);
 
        // 再养一只猫
        Cat c2 = new Cat();
        /*c2.eat();
        c2.sleep();*/
        // feedCat(c2);
        feedAnimal(c2);
 
        feedAnimal(new Tiger());
 
        // 调用工厂方法获得一只动物
        Animal aa =  productAnimal(1); // Animal aa = new Dog()
        aa.eat();
        aa.sleep();
    }
    /**
     * 工厂方法
     *  type =  1  狗
     *  type =  2  猫 
     */
    public static Animal productAnimal(int type) {
        if(type == 1) {
            //此次省略一万行代码
            return new Dog();           
        } else if (type == 2) {
            return new Cat();
        }
        return new Tiger();
    }
    /**
     * 喂养动物
     */
    public static void feedAnimal(Animal a) { // Animal a = new Tiger();
        a.sleep();
        a.eat();
 
        // 格式:boolean b = 引用变量 instanceof 数据类型;
        boolean b = a instanceof Dog;
        if(a instanceof Dog) {
            // 格式:子类类型 变量名 = (子类类型)父类引用;
            Dog d = (Dog)a;
            // 调用子类特有的成员
            // d.lookHome();
        } else if(a instanceof Cat) {
            // 向下转型为Cat
            Cat c = (Cat)a;
            c.catchMouse();
        } 
        // 判断引用变量a是否实现了指定的接口:Play,如果实现了则返回true,否则false
        if(a instanceof Play) {
            // 调用狗的playing方法
            Play p = (Play)a;
            p.playing();
        }
    }
    /*
    *//**
     * 喂养猫
     * @param d
     *//*
    public static void feedCat(Cat c) {
        c.eat();
        c.sleep();
    }
    *//**
     * 喂养狗
     * @param d
     *//*
    public static void feedDog(Dog d) {
        d.eat();
        d.sleep();
    }*/
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值