大数据---javase基础---day7

本文介绍了Java中的抽象类和接口的概念及其用法。抽象类用于定义有抽象方法的类,不能实例化,而接口则包含抽象方法和静态方法,可以多继承。Java中的类可以单继承抽象类并实现多个接口,实现类必须重写抽象方法。同时,接口的默认方法和静态方法提供了更多灵活性。Comparable和Comparator接口常用于对象比较,但在使用时需要进行类型转换以避免冲突。
摘要由CSDN通过智能技术生成

额外知识点

方法的调用并不是方法的运行,当方法的调用被运行时才叫方法的运行

抽象关键字—abstract

举例说明

假设有两个实体类—Teacher类(图一)和LangTeacher类(图二),其中Teacher类中写了个讲课的方法但该方法体为空,LangTeacher类内什么也没有写。(原因:父类觉得子类一定会重写jiangKe方法,而子类认为父类一定写了JiangKe方法,所以导致双方都没写),此时若新建一个测试类来调用jiangKe方法则运行结果一定为空,如图三所示

在这里插入图片描述
请添加图片描述
请添加图片描述

所以既然父类中的jiangKe方法的方法体内不写代码,则直接将大括号删掉(如图一所示),但此时会报错,所以在方法的特殊修饰区加上abstract,但此时仍会报错(如图二所示),因为只要有抽象方法,则该抽象方法所在的类也必须是抽象类,所以需要给该类也加上abstract(如图三所示)
请添加图片描述
请添加图片描述
请添加图片描述
此时必须在子类中重写jiangKe方法,否则子类会报错。如下图一(报错状态),图二(更正状态)。由此可引出抽象父类的子类的特点请添加图片描述

请添加图片描述

abstract相关知识点

  • 定义
    只可以修饰类和方法。修饰类时叫做抽象类;修饰方法时叫做抽象方法
  • 特点
    1、抽象的方法必须在抽象的类中,且抽象的类中不仅有抽象的方法,还可以有普通的方法
    2、抽象的类不能实例化,即抽象的类不能创建对象(也就是不能new)
    3、抽象的方法没有方法体,且抽象方法是不能够运行的(原因:因为它没有方法体),但其不会报错。如图所示
    请添加图片描述

抽象父类的子类

相当于多态的另一种形式:即抽象父类+普通子类------更适用于多态
原因:抽象的类不能实例化(即抽象的类不能创建对象),所以无法创建父类对象,所以只能够“父类的引用指向子类的对象”

  • 特点
    1、一个普通子类继承自抽象父类,必须重写父类中所有的抽象方法请添加图片描述
    2、一个子类继承自抽象父类,若其不想重写抽象父类中的抽象方法,则将子类也变为抽象类即可
    请添加图片描述
    注意: 子类必须在其自己的构造器中调用父类的构造器
    以上两个特点的原因:
    1、子类继承自父类,所以子类包含父类中的所有属性和方法,所以子类中也有跟抽象父类一模一样的jiangKe方法,由于jiangKe方法是抽象方法,所以两种解决方式:一就是重写jiangKe方法;二就是将子类变为抽象类
    2、缺陷:如果采用将子类也变成抽象类,则此时“父类的引用指向子类的对象”就会报错,如图一所示,因为此时子类已经是抽象的类(抽象类不能实例化)。唯一的解决办法就是在创建一个该子类的子类,来对jiangKe方法进行重写(图二)。并创建一个该子类的子类的对象来进行调用(图三)请添加图片描述
    请添加图片描述
    请添加图片描述

为什么抽象的类不能new对象(不能实例化),但其却有构造器?

答:抽象类是一种特殊的类,它不能被实例化,因为它存在抽象方法,这些方法没有具体的实现。抽象类的构造器的主要作用是为它的子类提供一个初始化的入口,而不是用于创建抽象类的实例。因此,当我们创建一个抽象类的子类时,需要调用父类的构造器来初始化父类的属性以此来为子类从父类处继承到的属性进行赋值

接口

定义格式

请添加图片描述

类实现接口

  • 定义
    类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类,利用implements关键字实现
    请添加图片描述

jdk1.8之前的公共静态常量和抽象方法(无方法体)

特点

  • 接口中声明的属性默认是public static final修饰的(即接口中声明的属性是公开静态常量),所以在定义属性时,属性名是斜体且大写且必须给属性赋初始值

  • 在接口中声明的方法的特殊修饰符默认是abstract关键字,所以接口不允许实例化
    请添加图片描述
    注意:

  • 右键创建时,new class声明类,用new interface声明接口

  • 接口和类属于统一等级

  • 写上修饰符后修饰符并未显示出其该有的颜色,而是呈灰色,是因为系统在告诉你此时这个修饰符写不写都一样,所以可以省略(所以这也说明了当不写修饰符时不一定时default修饰符)

  • 接口中修饰属性和方法时唯一可以使用的修饰符为:public

  • 接口中定义属性时(属性为灰色,在类中属性为紫色)必须赋值,否则会报错。原因:接口中的属性默认是由final修饰的,此处只是省略没写final而已。且final修饰的属性必须赋初始值,这使得属性成为了常量,而常量的每个字母都必须大写
    请添加图片描述

  • 接口中定义的属性name为斜体,原因:static修饰的均为斜体,此处static只是省略没写,若写出来则如图所示,static也为灰色。所以在接口中声明的属性默认是public static final修饰的
    在这里插入图片描述

  • 由于接口无法实例化,所以需要创建一个接口的实现类,如下图一所示创建一个接口的实现类Teacher,然后可利用Person的引用指向实现类的对象来进行实例化,如图二所示。此也是多态的一种方式,即接口加实现类实现多态
    在这里插入图片描述
    在这里插入图片描述

  • 若是接口加实现类实现多态,此时@Override 代表实现方法,而不是重写方法

jdk1.8之后的公共默认方法和静态方法(有方法体)

一个实现类若实现一个接口,则必须实现接口中所有的抽象方法

接口中default修饰的方法

  • 特点
    1、default修饰的方法不会强制实现类必须实现
    2、从jdk1.8开始,接口中允许有default修饰的方法,被default修饰的方法有方法体,且此时该方法不是抽象方法,可以被实现类实现
    请添加图片描述

3、default修饰的方法由实现类创建对象,再由实现类的对象调用default方法即可
请添加图片描述

4、实现类对于接口中的default方法可以选择实现,也可以选择不实现,不强制。若实现类中实现了default方法,则再调用时会执行实现类中的方法
请添加图片描述

接口中static修饰的方法(即接口中的静态方法)

  • 特点.
    1、接口中static修饰的方法不能重写
    2、由static修饰的方法有方法体,且由接口名.方法名的方式来调用,如果用对象名来调用则会报错
    请添加图片描述

接口和实现类之间的关系以及接口的继承

特点

  • java语言中,类是单继承的,只能有一个直接父类,但类可以实现多个接口且实现接口时不会影响我们继承父类,即单继承多实现。
  • 一个实现类若想实现多个接口,则必须实现所有接口中的所有抽象方法
    请添加图片描述

多个类实现同一接口(代码示例)

  • 接口请添加图片描述
  • Teacher实现类请添加图片描述
  • Doctor实现类请添加图片描述
  • Master管理者(与多态没啥区别)请添加图片描述
  • 测试类及运行截图(与多态没啥区别)请添加图片描述

一个类实现多个接口

  • 声明格式
    请添加图片描述
    一个类实现多个接口时,如果任何一个它实现的接口需要对象,都可以传递当前类的对象换句话说就是在Java中,一个类可以实现多个接口。如果这个类实现的任何一个接口需要一个对象作为参数,那么在调用这个方法时,可以传递当前类的对象作为参数。这是因为这个类已经实现了这个接口,所以它已经具备了这个接口所需要的方法和属性。通过传递这个类的对象,接口方法就可以访问这个类的属性和方法,从而完成相应的操作。
//接口A
interface InterfaceA {
  void methodWithObject(Object obj);
}
//接口B
interface InterfaceB {
  void methodWithObject(Object obj);
}
//两个接口的实现类
class MyClass implements InterfaceA, InterfaceB {
  public void methodWithObject(Object obj) {
    System.out.println("Object received: " + obj.toString());
  }
}
//测试类
public class MyClass {
  public static void main(String[] args) {
    MyClass myObj = new MyClass();

    InterfaceA interfaceAObj = myObj;
    interfaceAObj.methodWithObject(myObj);

    InterfaceB interfaceBObj = myObj;
    interfaceBObj.methodWithObject(myObj);
  }
}

代码解释:在上面的代码中,我们首先创建了一个MyClass对象myObj,然后将它转换为InterfaceAInterfaceB类型的对象。接下来,我们分别调用了这两个接口的methodWithObject方法,并将myObj对象作为参数传递给它们。由于MyClass类实现了这两个接口,所以这两个方法都可以访问到myObj对象的属性和方法。

接口继承(接口没有隐式继承)

接口可以单继承
  • 父类接口Father请添加图片描述
  • 子类接口Son请添加图片描述
  • 子类实现类Student请添加图片描述
接口可以多继承
  • 子类接口继承了两个父接口请添加图片描述
  • 子类实现类Student(需要实现实现类对应的接口所继承的所有接口的抽象方法)请添加图片描述
    注意:请添加图片描述

接口特点总结

请添加图片描述

接口中不能定义构造器(构造方法)。接口是一种抽象类型,它只能包含方法的声明,而不包含具体的实现或构造方法。构造方法是用于实例化类的特殊方法,而接口本身不能被实例化,因此不允许在接口中定义构造方法。但是你可以在实现类中定义构造器(构造方法),所以在实现多态的三种方式中接口+实现类更实用。

两个经典接口(比较两个对象的大小)

由于引用数据类型是没办法直接使用比较运算符来比奥比较大小,所以java指定了标准接口来解决这个问题

Comparable(需要重写compareTo方法)

在这里插入图片描述

以代码为例详解

  • Work请添加图片描述
    请添加图片描述
  • TestWork请添加图片描述

Comparator(需要重写compare方法)

在这里插入图片描述

  • Work
    请添加图片描述
    请添加图片描述

  • TestWork请添加图片描述

  • 问题
    利用以上两种经典接口比较对象大小的方式为什么都要进行向下转型?

在Java中,利用Comparable接口进行比较两个对象的大小时,需要向下转型是因为Comparable接口的compareTo方法的参数类型是Object,而不是具体的类类型。因此,在实现compareTo方法时,需要将参数对象强制转换为具体的类类型,以便能够访问该类的属性和方法。

冲突问题

默认方法冲突问题

  • 亲爹优先原则
    解释: 当一个类既继承父类又实现若干接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法
    ”super.方法名“调用父类的方法;”接口名.super.方法名“调用接口的方法

  • 左右为难
    解释:当一个类同时实现了多个父接口,而多个父接口中包含方法签名相同的默认方法时,此时有两种解决办法:
    方法一: 保留其中一个父接口:重写方法,然后通过”接口名.super.方法名“的方法选择保留哪个接口的默认方法。
    方法二: 完全重写,即舍弃任何父接口中的代码块中的内容,自己完全重写该方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT机器猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值