详解
在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。
public abstract class Person {
void eat(){
System.out.println("it is valid");
}
}
接口中的方法不能有具体实现,以下代码报错
public interface Person {
/**
* Interface abstract methods cannot have body
*/
void eat(){
System.out.println("it is valid");
}
}
抽象类中定义的方法默认不是public,接口中定义的方法默认是public,如我们用main方法测试一下
public abstract class Application {
/**
* JVM可以正确找到main方法
* @param args
*/
public static void main(String[] args) {
System.out.println("no problem");
}
}
下面代码无法正常运行
Error: Main method not found in class com.github.Application, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
public abstract class Application {
/**
* JVM可以正确找到main方法
* @param args
*/
static void main(String[] args) {
System.out.println("no problem");
}
}
可以直接运行(JDK8)
public interface Application {
/**
* JVM可以正确找到main方法
* @param args
*/
static void main(String[] args) {
System.out.println("no problem");
}
}
一个类可以继承一个抽象类(JAVA的单继承),但是可以实现多个接口
抽象类中的成员变量可以不初始化,接口中的成员变量必须初始化,默认为static
, final
public abstract class Person {
//no problem
int age;
}
报错,需要初始化
public interface Person {
//Variable 'age' might not have been initialized
int age;
}
接口中的变量没有必要写上static final
抽象类中可以定义构造函数,但是不能实例化,至于接口的话之前说过,是不能有方法具体的实现的,故不能有构造函数
public abstract class Person {
String name;
String age;
Person(String name, int age) {
}
}
速度比较
public abstract class AbstractClass {
public abstract void say();
}
public interface Interface {
void say();
}
public class SubClass implements Interface{
@Override
public void say() {
System.out.println("github/shellhub");
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
new SubClass().say();
}
System.out.println(System.currentTimeMillis() - startTime);
}
}
public class SubClass extends AbstractClass{
@Override
public void say() {
System.out.println("github/shellhub");
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
new SubClass().say();
}
System.out.println(System.currentTimeMillis() - startTime);
}
}
运行10次的时间比较
* 接口
18 35 22 30 37 31 30 46 32 40
* 抽象类
22 29 28 38 33 36 38 23 28 50
最终胜利:自己判断吧,这点测试结果说明不了什么问题,这个问题不能很片面,因为有很多因素,下面贴一个SO上的回答
总结
在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。
抽象类中定义的成员变量默认不是public,接口中定义的方法默认是public,
一个类可以继承一个抽象类(JAVA的单继承),但是可以实现多个接口 (WTF这是区别么)
抽象类中的成员变量可以不初始化,接口中的成员变量必须初始化,默认为static, final
抽象类中可以定义构造函数,但是不能实例化,接口不能定义构造函数
速度比较(待定)
如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。
想到在补充…