从浅入深讲解Java抽象类和接口
- 一、抽象类
- 二、接口
- 1、为什么需要接口
- 2、接口的语法
- 3、接口的使用
- 4、接口的特性
- (1)接口类型是一种引用类型,但是不能直接new接口的对象
- (2)接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
- (3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
- (4)重写接口中方法时,不能使用默认的访问权限
- (5)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
- (6)接口中不能有静态代码块和构造方法
- (7)如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
- (8)接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
- (9)jdk8中:接口中还可以包含default方法。
- 三、实现多个接口
- 四、接口间的继承
一、抽象类
1、什么是抽象类
当我直接告诉你一个概念,而不告诉你这个概念什么意思,什么用途的时候。读者的脑子里肯定会反映出这样一个想法:“你讲的真抽象。”
所以,当一个类没有告诉你具体的实现的时候,就叫做抽象类。比如说,这个类里面定义了一个方法。但是我不告诉你这个方法怎么实现的,那么这个方法就叫做抽象方法。而当一个类中包含了抽象方法的时候,这个类就是抽象类。
当然这里要解释一个地方:包含抽象方法的类一定是抽象类,抽象类不一定包含抽象方法。
2、为什么需要抽象类
比如我们有一个父类,这个父类提供了一个方法。继承这个父类的所有子类都重写了这个方法。那么此时根据前面讲解的多态的知识,最终只会调用子类重写后的方法。那么此时,在父类中的方法实现就没有意义了,那你就没必要写它的实现,所以此时就可以把它定义为抽象方法。既然它是抽象方法了,那么包含这个抽象方法的类就要定义为抽象类。
3、抽象类和抽象方法的语法
//抽象类
abstract class 类名{
}
//抽象方法
abstract 返回类型 方法名(参数);
例如:
abstract class Animal{
public String name;
public abstract void eat();
}
4、注意事项
(1)抽象类无法实例化对象
因为抽象类中可能含有没有实现的方法,所以你实例化后,这个对象并不知道这个方法该怎么做。因此,不能实例化对象。
(2)子类继承后,必须实现继承过来的抽象方法
因为子类继承抽象类以后,子类前不需要加abstract
关键字,所以子类是可以实例化的。那么你就必须得实现那些抽象的方法。要不然的话,你实例化以后的对象并不知道这个方法怎么执行。
(3)抽象方法不能是private修饰
(4)抽象方法不能被final和static修饰,因为抽象方法要被子类重写
(5)抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
(6)抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
5、抽象类的作用
抽象类本身不能被实例化,要想使用的话,只能创建该抽象类的子类。 然后让子类重写抽象类中的抽象方法。有些读者可能会说, 普通的类也可以被继承,普通的方法也可以被重写, 为什么非要用抽象类和抽象方法呢?
确实如此, 但是使用抽象类相当于多了一重编译器的校验。
如果某个方法的实际实现不应该由父类完成, 而应由子类完成。 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的。 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题。这里的作用就如同之前的final
关键字。
二、接口
1、为什么需要接口
在生活中,接口有很多,比如USB接口、typeC接口等。无论电子产品是什么样的,只要用到了这些接口,你都要符合这些接口所规定的要求,遵循这些接口的规则。所以说,接口可以理解为一种规则,一种规范。
那么回到Java中,如果你想让一些类遵循统一的规范,那么你可以将这些规范设计为一个接口。然后让这些类遵循这个接口。
2、接口的语法
那么接口怎么定义呢?接口中可以定义成员变量,可以定义方法,就像一个类一样。但是与类不同的是,接口中的成员变量固定前缀为public static final
。方法的固定前缀为public abstract
。由于都是固定的,所以在定义一个接口的时候,我们可以不写这些前缀。推荐大家不写,这样能够让代码更加简洁。
[public] interface 接口名 {
int a;//默认前缀public static final
int b;
void c();//默认前缀public abstract
int d(int a, int b);
}
如果关键字interface前面加上public关键字,那么就称这个接口是一个public接口,public接口可以被任何一个类实现。
如果不加public修饰,就称这个接口是一个友好接口,友好接口可以被与该接口在同一个包中的类实现。
3、接口的使用
接口中含有抽象方法,所以你不能直接实例化一个接口的对象,类似于一个抽象类。如果想要使用这个接口,需要让一个类扩展这个接口,即在类中实现接口中的所有抽象方法。
public interface USB {
void openDevice();
void closeDevice();
}
class Mouse implements USB{
public void openDevice() {
System.out.println("打开鼠标。");
}
public void closeDevice() {
System.out.println("关闭鼠标。");
}
}
4、接口的特性
(1)接口类型是一种引用类型,但是不能直接new接口的对象
(2)接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
(3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
(4)重写接口中方法时,不能使用默认的访问权限
(5)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
(6)接口中不能有静态代码块和构造方法
(7)如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
(8)接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
(9)jdk8中:接口中还可以包含default方法。
三、实现多个接口
在java中我们无法让一个子类继承多个父类,也就是说,多继承无法实现。但是,我们可以通过实现多个接口做到多继承的效果。
interface IFlying{
void fly();
}
interface IRunning{
void run();
}
interface ISwimming{
void swim();
}
class Duck implements IFlying, IRunning, ISwimming{
public void fly() {
System.out.println("鸭子在飞。");
}
public void run() {
System.out.println("鸭子在跑。");
}
public void swim() {
System.out.println("鸭子在游泳。");
}
}
四、接口间的继承
接口之间可以实现继承,关键字也是extends
。同时,接口之间可以实现多继承。
interface a{
}
interface b{
}
interface c extends a, b{
}