接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。—— 《Java编程思想》
抽象类和接口定义
抽象类: 抽象类用abstract关键字修饰。类中的方法不必是抽象的。
public abstract class MyAbstractClass {
}
接口: 接口用interface关键字修饰,比抽象类更加抽象是极度抽象的类。类中的方法只能是抽象的,不包含任何具体的实现。
public interface MyInterface {
}
抽象类和接口区别
抽象类和接口的区别可以概括成以下几点:
1)接口不能有构造方法,抽象类可以有;
2)接口不能有静态方法,抽象类可以有;
3)接口不能有方法体,抽象类可以有;
4)在接口中凡是变量必须是public static final,而在抽象类中没有要求。
问题 1:抽象类不能实例化也有构造方法?
回答 1:抽象类会被其子类继承,其中的抽象方法也需要在子类中实现。任何子类都必须调用从Object开始的所有父亲的构造方法,才算完成初始化工作,所以抽象类有构造方法,平时隐式调用无参构造方法
问题一验证:
public abstract class MyAbstractClass {
/**和普通类一样,可以有构造函数**/
int a;
public MyAbstractClass(){
}
public MyAbstractClass(int a){
this.a = a;
}
}
问题 2:接口没有构造方法?
回答 2:接口中添加构造方法会报错:Interfaces cannot have constructors , 申明接口时将 class 用 interface 来代替,且实现接口不是使用继承的关键字 extends 而是使用 implements,已经说明接口和类是不一样的。构造方法对一个对象的变量进行初始化操作的,接口只有public static final类型的变量,该类型的变量是常量,是只读的。
问题二验证
public interface MyInterface {
/**
* 报错:Interfaces cannot have constructors
*/
// public MyInterface(){
//
// }
}
问题 3:接口不能有方法体,抽象类可以有?
回答 3:抽象类包含一个或多个抽象方法,也就是说抽象类中可以有非抽象的方法,也可以不包含抽象方法;接口的中的所有方法必须都是抽象的。
问题三验证
public abstract class MyAbstractClass {
public abstract void add();
/**
* 抽象类可以有实现的方法
*/
public void subtract() {
System.out.println("减少");
}
public abstract void multiply();
public abstract void divide();
}
public interface MyInterface {
/**
* 报错:Abstract methods do not specify a body
*/
// public abstract void add(){;
//
// }
}
问题 4:抽象类和接口中有没有静态方法?
回答 4:抽象类可以有静态方法。抽象类不能有抽象的静态方法,但是可以有实现的静态方法,每个继承此抽象类的子类,都有相同的功能,所以要把这个功能定义成静态的函数。由于静态方法需在类加载时加载,没有实现则无法加载,所以必须要实现。接口中的方法都是抽象的,不能进行实现,所以接口没有静态方法。
public abstract class MyAbstractClass {
/**
* 抽象类可以有静态方法,但是该静态方法必须实现
* 未实现报错:This method requires a body instead of a semicolon
*/
public static void multiply(){;
}
}
问题 5:抽象类和接口的实现?
回答 5:抽象类的子类使用 extends 继承抽象类,一个类只能继承一个抽象类。抽象类中具有多个抽象方法时,其子类可以只实现部分抽象方法,但此时子类也必须用 abstract 关键字修饰。接口使用 implements 关键字实现,一个类可以实现多个接口,接口之间用逗号分隔。
首先来看三段代码如下:
代码一:
public abstract class MyAbstractClass {
public abstract void add();
/**
* 抽象类可以有实现的方法
*/
public void subtract() {
System.out.println("减法");
}
/**
* 抽象类可以有静态方法,但是该静态方法必须实现
*/
public static void multiply(){
System.out.println("乘法");
}
public abstract void divide();
}
代码二:
public class SonAbstract extends MyAbstractClass {
@Override
public void add() {
}
@Override
public void divide() {
}
}
代码三:
public abstract class SonAbstract extends MyAbstractClass {
/**
* 部分实现 MyAbstractClass
* 报错:The type SonAbstract must implement the inherited abstract method MyAbstractClass.add()
* 此时用abstract定义SonAbstract为抽象类,不在报错
*/
// @Override
// public void add() {
//
// }
@Override
public void divide() {
}
}
其中代码一MyAbstractClass是父类,其中包含四个方法:
1. add()和divide()是抽象方法,需要在子类中实现,也就是代码二和代码三中实现
2. subtract()是普通方法,已经在父类中实现,子类中可以调用父类方法,也可以覆盖
3. multiply()是静态方法,在类加载时加载,已经在前面说明过了
代码二和代码三的区别在于,代码三部分实现了父类的抽象方法,代码二实现了全部的父类方法。因此代码三需要声明成一个抽象类,也就是说:一个类继承一个抽象的父类,且只实现了父类的部分方法,则该类必须是一个抽象类。
面试题
最后来两道面试题自测一下:
第一题
第二题
解释都在文章中
开学大四了,正在艰辛地找实习,准备一下面试题,总结一下知识点,也能查漏补缺。