一、抽象类
1、定义:抽象类主要用于抽取相关 Java 类的共用方法实现或者是共同成员变量,然后通过继承的方式达到代码复用的目的。
2、特性
- 与一般类不同的是,抽象类不能实例化。
- 用abstract关键字修饰class。
- 对属性的操作和一般类一样,无任何区别。
- 至于方法,可以有一个或者多个抽象方法,用abstract修饰,且抽象方法不可以有方法体。也可以没有抽象方法。
如下代码就是一个简单的抽象类:
public abstract class Human {
private int age;
abstract void likeDoSomething() ;
void walk() {
System.out.println("I can walk");
}
}
再来看看反编译后的结果,唯一的区别就是自动生成了一个无参的构造方法(所有类都是如此)。
public abstract class com.yxz.abstractAndInterfacedemo.Human {
public com.yxz.abstractAndInterfacedemo.Human();
abstract void likeDoSomething();
void walk();
}
3、用法
Java类继承抽象类使用 extends 关键词,且必须实现所有的抽象方法,例如定义一个Doctor类继承Human:
public class Doctor extends Human {
@Override
void likeDoSomething() {
System.out.println("I like read books");
}
}
反编译后的结果:
public class com.yxz.abstractAndInterfacedemo.Doctor extends com.yxz.abstractAndInterfacedemo.Human {
public com.yxz.abstractAndInterfacedemo.Doctor();
void likeDoSomething();
}
最后通过一个测试类进行测试:
public class AbstractTest {
public static void main(String[] args) {
Human human = new Doctor();
human.likeDoSomething();//输出结果为:I like read books
}
}
从这里可以看出,抽象类和子类可以实现多态的效果。
二、接口
1、定义:接口是对行为的抽象,利用接口可以达到 API 定义和实现分离的目的。
2、特性
- 不能实例化。
- 所有属性在定义时必须赋值,如:int i = 1;且在编译后会自动加上前缀public static final,保证其是公共的静态常量。
- 方法包括两种:静态方法和非静态方法。前者可以有方法体且编译后会自动加上前缀public;后者不可以且编译后会自动加上前缀public abstract。
- 所有属性和方法的权限修饰符都只能用public。
下面通过一段源码和反编译结果进行验证:
public interface MyInterface {
int val = 1;
static void method1() {
System.out.println("我是接口的静态方法method1");
}
void method2();
}
反编译后的结果
public interface com.yxz.abstractAndInterfacedemo.MyInterface {
public static final int val;
public static void method1();
public abstract void method2();
}
接着通过一个类来进行实现:
public class MyImpl implements MyInterface {
@Override
public void method2() {
System.out.println("我是实现了接口的方法method2");
}
}
反编译后的结果:
public class com.yxz.abstractAndInterfacedemo.MyImpl implements com.yxz.abstractAndInterfacedemo.MyInterface {
public com.yxz.abstractAndInterfacedemo.MyImpl();
public void method2();
}
由于method2是一个抽象方法,从上面抽象部分得知,必须要对其进行实现。
最后通过一个测试类进行测试:
public class ImplTest {
public static void main(String[] args) {
MyInterface.method1();//输出结果:我是接口的静态方法method1
MyInterface myInterface = new MyImpl();
myInterface.method2();//输出结果:我是实现了接口的方法method2
}
}
三、总结
只所以说接口是特殊的抽象类,可以理解为是由于接口中除了静态方法,其余方法都是加了abstract的抽象方法。