Java-多态

面向对象三大特征
封装继承多态
对象代表什么,就得封装对应的数据,并提供数据对应的行为当类与类之间,存在相同(共性)内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码同类型的对象,表现出不同的形态
多态的表现形式

父类类型  对象名称  =  子类对象;

多态的前提

有继承/实现关系

有父类引用指向子类对象 eg: Fu f = new Zi();

有方法重写

多态的好处

使用父类类型作为形参可以接收其所有的子类对象

体现多态的扩展性与便利

//多态的最基本引用

public class Test {
    public static void main(String[] args) {

        Student s = new Student();
        s.setName("彭于晏");
        s.setAge(18);

        Teacher t = new Teacher();
        t.setName("刘亦菲");
        t.setAge(20);

        register(s);//打印结果:  学生的信息为: 彭于晏 18
        register(t);//打印结果:  老师的信息为: 刘亦菲 20

    }

    //这个方法既能接收学生,又能接收老师
    //只能把参数写成这两个类型的父类
    public static void register(Person p) {
        p.show();
    }
}


//父类
class Person {

    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show() {
        System.out.println(name + " " + age);
    }
}

//子类1
class Student extends Person {

    @Override
    public void show() {
        System.out.println("学生的信息为: " + super.getName() + " " + super.getAge());
    }
}

//子类2
class Teacher extends Person {

    @Override
    public void show() {
        System.out.println("老师的信息为: " + super.getName() + " " + super.getAge());
    }
}
多态调用成员的特点
调用成员变量的特点编译看左边,运行也看左边
调用成员方法的特点编译看左边,运行看右边
//多态中调用成员的特点

public class Test {
    public static void main(String[] args) {

        //多态方式创建对象
        Animal a = new Dog();
        //调用成员变量: 编译看左边,运行也看左边
        System.out.println(a.name);//打印结果: 动物
        //调用成员方法: 编译看左边,运行看右边
        a.show();//打印结果: Dog----------show方法
    }
}

//父类
class Animal {

    String name = "动物";

    public void show() {
        System.out.println("Animal----------show方法");
    }
}

//子类1
class Dog extends Animal {

    String name = "狗";

    @Override
    public void show() {
        System.out.println("Dog----------show方法");
    }
}

//子类2
class Cat extends Animal {

    String name = "猫";

    @Override
    public void show() {
        System.out.println("Cat----------show方法");
    }
}
多态的优势
1.在多态形势下,右边对象可以实现解耦合,便于扩展和维护

Person p = new Student();

p.work();  //业务逻辑发生改变时,后续待码无需修改,直接改"="右边的子类就行

2.定义方法的时候,使用父类类型作为形参,可以接收其所有子类对象,体现多态的扩展性与便利性

public static void register(Person p) {......} 

多态的弊端
弊端解决方案
不能调用子类的特有功能强制类型转换
//多态的弊端
//不能调用子类的特有功能

public class Test {
    public static void main(String[] args) {
        //多态方式创建对象
        Animal a1 = new Dog();
        a1.eat();//打印结果: 狗在吃骨头!

        //但很显然 a.lookHome(); 根本就调用不了
        //那怎么解决呢?
        //解决方案: 强制类型转换
        Dog d = (Dog) a1;
        d.lookHome();//打印结果: 狗在看家!

        //补充: 强转不能瞎转,之前创建的对象是Dog类型的,那我们就不能转成Cat类型的
        //那怎么避免强转类型与真实对象类型不一致会报错呢?
        //加一个判断的方法(用instanceof关键字来判断)
        Animal a2 = new Cat();
        if(a2 instanceof Cat){
            Cat c = (Cat) a2;
            c.catchMouse();//打印结果: 猫在抓老鼠!
        }
        else if(a2 instanceof Dog){
            Dog c = (Dog) a2;
            c.lookHome();
        }else{
            System.out.println("没有这个类型,无法转换");
        }

        //代码好麻烦
        //jdk14后有新特性
        Animal a3 = new Cat();
        //先判断a3是否为Cat类型,如果是,则强转成Cat类型,转换之后变量名为cc
        //如果不是,则不强转,结果直接是false
        if(a3 instanceof Cat cc){
            cc.catchMouse();//打印结果: 猫在抓老鼠!
        }

    }
}

//父类
class Animal {

    public void eat() {
        System.out.println("动物在吃东西!");
    }
}

//子类1
class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("狗在吃骨头!");
    }

    public void lookHome() {
        System.out.println("狗在看家!");
    }
}

//子类2
class Cat extends Animal {

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

    public void catchMouse() {
        System.out.println("猫在抓老鼠!");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值