2021-07-20

java之多态

1、多态的实现过程

public class Triangle extends Shape{
    @Override
    public void draw(){
        System.out.println("△");
    }
}
public class Test {
    public static void main(String[] args) {
        //多态
        //创建若干子类实例
        Shape shape1 = new Rect();
        Shape shape2 = new Circle();
        Shape shape3 = new Flower();
        Shape shape4 = new Triangle();

        draw(shape1);
        draw(shape2);
        draw(shape3);
        draw(shape4);
    }

    public static void draw(Shape shape){
        shape.draw();
    }
}

1.1 向上转型

向上转型(父类的引用指向子类的对象)是多态的前提

        Shape shape1 = new Rect();
        Shape shape2 = new Circle();
        Shape shape3 = new Flower();
        Shape shape4 = new Triangle();

1.2 动态绑定:

        shape.draw();

1.3 为方法重写

    @Override
    public void draw(){
        System.out.println("△");
    }

1.4、 向下转型

package java41_0122;

public class Cat extends Animal{

}
package java41_0122;

public class Bird extends Animal{

}
package java41_0122;

public class Animal {
    
}
package java41_0122;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        //向上转型
        Animal animal = new Cat();

        //向下转型
        //向下转型确保 animal 指向的的确是一个 Cat 类型的实例。
        Cat cat = (Cat)animal;

        Animal animal2 = new Bird();
        //此向下转型是非法的,虽然编译可以通过,但是运行时会报错
        Cat cat2 = (Cat)animal2;
    }
}

运行结果
在这里插入图片描述
向下转型是存在限制的,不能随便转。相当于向上转型的逆过程。向上转型是得到父类的引用,可以借助向下转型还原到原来的类型。
向下转型应用的场景:有些方法只在子类中存在,但是在父类中不存在,此时使用多态的方式就无法执行到对应的子类的方法,就必须把父类引用先转回子类的引用,然后再调用对应的方法。
向下转型的时候若是类型不一致会出现类型转换失败抛出异常,为了解决此问题,可以在向下转型之前先做判定,判定当前父类的引用是否是指向子类的,若不是则不进行向下转型。
判断关键字使用instanceof

2、构造方法中调用重写

package java41_0122;

class A{
    public A(){
//        func();
        this.func();
        //this 的类型是A的类型,实际对应的的是整个子类的实例;A的父类是object,没有func方法
    }

    public void func(){
        System.out.println("A.func");
    }
}
class B extends A{
    private int num = 1;

    public void func(){
        System.out.println("B.func " + num);
    }

}


//构造方法中调用重写
public class Test2 {
    public static void main(String[] args) {
        //1、A 是 B 的父类,构造 B 的时候需要先构造 A 的实例
        //2、构造 A 的实例时,会调用 A 的构造方法
        //3、调用 A 的实例时,就会调用到 this.func(),此时的 this 是指向子类的实例,
        // 触发了方法的动态绑定,就地初始化 num = 0
        //4、如果 B.func 打印 B 的 num 值,结果为 0
        B b = new B();
    }
}

3、抽象类

        //Shape 虽然自己也有 draw 方法,但是此处的draw无实质性内容,其目的是为了让其他的子类进行重写
        //Shape自己也不需要创建实例,搭配多态来使用
        //对于不需要实例化的类定义为“抽象类”,其本身没有方法,只是为了被子类重写的方法,
        //此方法定义为“抽象方法”
        Shape shape1 = new Circle();
        Shape shape2 = new Flower();
package java41_0122;


//抽象类如果尝试创建类的实例,就会编译出错
abstract public class Shape {

    //抽象类方法不需要方法体
    //抽象类方法只能在抽象类中存在(也可以在接口中存在),不能在普通类中存在
    //抽象方法的作用就是让子类进行重写
    abstract public void draw();
}
    对于不需要实例化的类定义为“抽象类”,其本身没有方法,只是为了被子类重写的方法,
    此方法定义为“抽象方法”;java中使用abstract关键字来描述抽象类和抽象方法

在这里插入图片描述
abstract 关键字的作用是程序员提示编译器抽象类不能实例化。除此之外其他的语法规则都和普通类保持一致
1、抽象类也可以有普通属性和方法;
2、抽象类也可以有静态的属性和方法;
3、抽象类也可以继承其他的类,还可以被其他的类继承。

在这里插入图片描述

4、接口

接口是抽象类的更近一步,接口再抽象类的基础上不具备其他类的各种特性。
接口中可以放抽象方法,此处的抽象方法不必写 abstract 关键字(写或者不写都是抽象方法),即:
1、接口中不能放普通方法;
2、不能放普通的属性,只能放 public static final 修饰的属性;
3、接口不能继承自其他的类,但是可以继承自其他的接口;
4、接口不能被类继承,而是被其他的类“实现”,“实现”的关键字是 implements;

package java41_0122;

public class Rect implements Shape {

    @Override
    public void draw() {
        System.out.println("□");

    }
}

5、接口相当于是一种约束,要求了实现该接口的类,必须重写所有的接口中的抽象方法;
6、一个类可以实现多组接口,表示不同的约束条件,每个接口里面可以实现多个抽象方法;
7、实现多个接口的时候,接口之间使用“,”分割;
8、接口和接口之间是可以继承的,更严谨的说应该是组合。

public interface ISwinmming {
    void swim();
}
public interface IRuning {
    void run();
}
package java41_0124;

public interface IAmphibious extends IRuning,ISwinmming{
//    void swim();
//    void run();
}

4.1 抽象类和接口的区别

1、抽象类和普通类差不多,只是不能实例化,而接口和普通的类之间差别很大。
2、一个类只能继承自一个抽象类,但是一个类可以同时实现多个接口。
接口的作用:可以解决java中不能多继承的问题,因为java类的继承都是单继承。
接口既能够实现多继承的效果,同时又能规避多继承带来的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值