Java中的多态

目录

一、final关键字

二、方法的重写

三、静态绑定

四、向上转型

五、向下转型

六、动态绑定

七、多态

格式

多态调用成员方法

多态调用成员属性

使用多态的好处

避免在构造方法中调用重写的方法


一、final关键字

final关键字用来修饰变量(常量)、类(密封类)、方法(表示该方法不能被重写)

二、方法的重写

方法重写的规则与注意事项:

1.方法名相同

2.方法的参数列表相同(个数、顺序、类型)

3.方法的返回值相同

4.被重写的方法返回值类型可以不同,但是必须是具有父子关系的

5.父类被final、static、private修饰的方法、构造方法都不能被重写

6.访问权限不能比父类中被重写的方法的访问权限更低

例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected

7.重写的方法可以使用@Override注解来显示指定,主要起合法性校验的作用。例如不小心将方法名字拼写错了(原本eat()方法写成aet()),那么此时编译器就会发现父类中没有aet()方法,就会编译报错,提示无法构成重写。

三、静态绑定

在编译的时候就确定调用哪个方法了

四、向上转型

向上转型就是创建一个子类对象,把它当作父类对象来使用。

发生向上转型的三种情况

注意事项:

1.向上转型一定是安全的。

2.优点:让代码实现更简单灵活。

3.弊端:无法调用子类的特有方法,如上图。

五、向下转型

向下转型就是还原子类对象,用强制类型转换的方式实现。

注意事项:

1.谁"new"的就还原成谁。

2.还原之前使用 对象名 instanceof 类名 进行判断,避免出错。

六、动态绑定

动态绑定的概念:编译的时候确实认为调用的是父类的方法,但是在运行的时候调用了子类的方法,这个机制就叫做动态绑定!

发生动态绑定的条件:

1.父类引用引用子类对象(向上转型)

2.通过父类引用调用重写的方法

class Animal {
    public String name;
    public int age;

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

    public void eat() {
        System.out.println(this.name+"正在吃!");
    }
}


class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);//alt+回车
    }

    public void bark() {
        System.out.println(this.name+"汪汪叫!");
    }

    @Override
    public void eat() {
        System.out.println(this.name+"正在吃狗粮!");
    }
}


class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }

    public void qiqi() {
        System.out.println(this.name+"吱吱叫!");
    }

    public void fly() {
        System.out.println(this.name+"正在飞!");
    }

    @Override
    public void eat() {
        System.out.println(this.name+"正在吃鸟粮!");
    }
}


public class Test {
    public static void func(Animal animal1) {
        animal1.eat();   //动态绑定
    }
    public static void main(String[] args) {

        Dog dog = new Dog("小黄",10);
        Bird bird = new Bird("小鸟",10);
        func(dog);  //向上转型
        func(bird);
    }
}

当animal引用的对象不一样调用eat方法表现的行为不一样此时就叫做多态!因为同一个引用调用同一个方法表现的行为不一样!

七、多态

概念:具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。

通过同一个父类引用调用同一个被重写的方法,此时父类引用引用的子类对象不一样表现的形式也不一样,此时叫做多态!!!

格式

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

父类接口名 对象名 = new 子类名();

多态调用成员方法

编译看左:编译器在编译时根据等号左边的类来界定对象的类型。

运行看右:在运行访问成员方法的时候,根据等号右边实例化的对象来访问相应的成员方法。

多态调用成员属性

编译和运行都看左:编译器在编译时根据等号左边的类来界定对象的类型,在访问的时候,也是根据等号左边的类来访问相应的成员变量。

使用多态的好处

1.能够降低代码的“圈复杂度”,避免使用大量的if-else

示例代码:

class Shape {
    public void draw() {
        System.out.println("画图形!");
    }
}


class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个矩形!");
    }
}

class Cycle extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个圆圈!");
    }
}


class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个三角形!");
    }
}

public class Test {

    public static void drawMaps2() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Triangle triangle = new Triangle();

        String[] shapes = {"1", "2", "2", "1", "3"};
        for (String s : shapes) {
            if(s.equals("1")) {
                cycle.draw();
            }else if(s.equals("2")) {
                rect.draw();
            }else if(s.equals("3")) {
                triangle.draw();
            }
        }
    }

    public static void drawMaps() {
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Triangle triangle = new Triangle();

        Shape[] shapes = {cycle, rect, rect, cycle, triangle};
        for (Shape shape : shapes) {
            shape.draw();

        }

    }
    public static void main(String[] args) {
        drawMaps2();
        System.out.println("=====================");
        drawMaps();

    }
}

运行结果:

2.可扩展能力更强

避免在构造方法中调用重写的方法

执行结果:

1.构造D对象的同时,会调用B的构造方法。

2.B的构造方法中调用了func方法,此时会触发动态绑定,会调用到D中的func

3.此时D对象自身还没有构造完成,此时num处在未初始化的状态,值为0。

结论:“用尽量简单的方式使对象进入可工作状态”,尽量不要在构造器中调用方法(如果这个方法被子类重写,就会触发动态绑定,但是此时子类对象还没构造完成),可能会出现一些隐藏的但是又极难发现的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值