抽象类和接口

前言

本文为华为开发者学堂-面向对象编程的课程笔记,仅供个人学习使用。

抽象方法和抽象类(欧内的手方法和奥利安费类

抽象方法

书接上文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Master{//主人类写法
public void cure(Pet pet){//父类作为方法的形参
if(pet.health<50){
pet.cure();
}
}
}
public class Pet{//父类写法
public int health;
public String name;
public String sex;
public void cure(){
//这里不要写属性的修改,因为要修改的是子类的属性(我好像在说废话x)
}
}
public class Cat extends Pet{//子类写法
public void cure(){
System.out.println("打针");
this.heatlh=60;
}
}

我们注意到,在上面Pet类里的cure方法内没有具体内容,而它的实现在子类里,此时我们就可以将它写成public abstract void cure();,也就是将其写成一个抽象方法。而抽象方法所在的类也要通过public abstract class Pet的改写来转变为抽象类

抽象类

当声明这个类的一个对象是没有意义的时候,就可以将这个类写为抽象类,抽象类不能被实例化

需要注意

  • 抽象类不能被实例化(不存在抽象构造方法),但可以创建一个抽象类的引用变量指向非抽象的子类实例
  • 如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类
  • 抽象方法没有方法体
  • 抽象方法必须在抽象类里,而抽象类里可以没有抽象方法。
  • 不存在抽象静态方法
  • 抽象类可以有非抽象构造方法,因为构造非抽象子类实例时可能需要用到,这样可以节省代码
  • 抽象方法必须在子类中被实现除非子类是抽象类

    小结

  • 当子类们既有共性方法又有各自特性方法的时候,我们可以通过声明抽象方法和抽象类来简化代码、方便调用。

接口

我们为什么需要接口

我们知道一个类只能有一个父类,而当一个类需要继承多组相互之间不相关的方法时,这些方法都塞在一个父类里或者多个间接父类里显然不合理,因此我们需要多个接口来存放和管理各组方法。

什么是接口

  • 概念性的接口指系统对外提供的所有服务。
  • interface定义的接口叫接口类型,但是接口不是类
  • JDK8之前的接口特性
    • 接口中的变量默认都是静态常量,必须显式初始化
    • 接口中所有方法默认都是抽象方法
    • 接口没有构造方法,不可以被实例化,但可以被实现
    • 通过implements关键字声明实现类,一个实现类可以实现多个接口
    • 实现类必须实现接口的所有方法,除非实现类也是一个抽象类
  • JDK8新增接口特性1:接口内可以有默认方法
    • 通过default关键字来声明默认方法,默认方法的用处在于简化代码,降低实现类和接口的耦合度,提升代码可维护性
    • 默认方法可以被继承,通过实例调用
    • 如果一个类实现了多个接口,多个接口都定义了多个同样的默认方法
      • 实现方案1:实现类需要覆盖重写接口中的默认方法不然会报错
      • 实现方案2:可以使用this来调用指定接口的默认方法
    • 如果一个类继承了一个抽象类,实现了一个接口,抽象类和接口存在相同的方法
      • 采取类优先的原则,有限继承抽象类的方法
  • JDK8新增接口特性2:**接口内可以声明(并且可以提供实现)静态方法了
    • 回顾:静态方法可以直接用类名调用(不用专门new一个对象了)
    • 接口中的静态方法必须是public的,public修饰符可以省略,static修饰符不能省略
    • 静态方法不能被继承及重写,所以只能被具体所在的接口调用
    • 接口中可以有多个静态方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*接口格式
访问修饰符 interface 接口名称 extends 其他接口名(如果有的话){
声明变量
声明方法
}*/
//接口示例
public interface Interface1{
public static final double PI =3.14;//在接口里,你写个double PI =3.14 也等同于左边的写法
public void m2();//等同于 public abstract void m2();
default void m3(){
System.out.println("已调用接口Interface1中的默认方法m3");
}
}
//实现类示例
public class Implementation implements Interface1{//多个接口间用逗号隔开
public void m2(){
System.out.println("实现用接口Interface1中的默认方法m2");
}
public void usem3(){
this.m3();
}
}

抽象类和接口的比较

  • 相同点
    • 代表系统的抽象层
    • 都不能被实例化
    • 都能包含抽象方法
  • 不同点
    • 在抽象类中可以为部分普通方法提供默认实现,而接口在JDK8之前只能包含抽象方法,JDK8之后接口可包含默认方法
    • 一个类只能继承一个直接的父类,但可以实现多个接口
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022 Daniel Qi
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信