抽象类和接口的区别
抽象类: 含有abstract修饰的class即为抽象类,abstract 类不能创建实例对象。含有abstract方法的类必须定义为abstract class,抽象类中的方法不一定全部要是抽象的,抽象类中的所有抽象方法必须要在子类中全部实现,如果不能实现全部的抽象方法,那么子类也必须用 abstract 修饰 抽象类中不能有抽象构造方法或抽象静态方法
为什么不能有抽象构造方法?
抽象类是可以拥有构造方法的。Java中没有抽象构造方法这一说。构造方法是用来初始化变量和通过new来创建对象的。抽象构造方法没有任何意义。
为什么不能有抽象静态方法?
静态方法和静态属性是属于类的,可以通过类直接调用,静态方法不能被重写(可以被继承)。而抽象的方法是需要被继承重写实现的,两者相矛盾。
静态方法不适用成员方法的 “左边编译,右边运行”(因为静态方法,可以通过类直接调用,不需要对象来进行调用,如果使用对象进行来进行调用是:左边编译,左边运行)
为什么抽象类不能直接实例化,却有构造方法?
构造方法是用来个成员变量进行初始化的,抽象类中的成员变量可以是任意的修饰符,而且可以有具体的方法实现,所以可能方法中的实现可以会用到成员变量。
为什么抽象类可以有构造方法?而接口不能有构造方法?
接口中的成员变量默认是用 public static final ,final 修饰的变量是不能被修改的,而且接口中的方法是不提供任何具体实现,所以接口中构造方法的存在没有意义
接口可以说是抽象类的一种特例
接口和抽象类的区别
- 抽象类可以有构造方法,接口中不能有构造方法。
- 抽象类中可以有普通成员变量,接口中没有普通成员变量(接口中的成员变量默认是 public static final 修饰)
- 抽象类中可以包含非抽象的普通方法和抽象方法,接口中的所有方法必须都是抽象的(接口中的方法默认采用 public abstract 修饰)
- 抽象类中的抽象方法的访问类型可以是任意类型,而接口中的方法访问类型只能是 public(默认public abstract)
- 抽象类中可以有静态方法,接口中不能包含静态方法
- 一个类可以实现多个接口,但是类只能单继承
Java8 中接口的变化
- 默认方法
- 静态方法
default 关键字的引入(虚拟扩展方法)
java8 中,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。
为什么java8引进了default关键字
在实现接口时,需要实现该接口的所有方法,在这个时候 default 关键字就能派上有用场了,通过 default 关键字定义的方法,继承该接口的类不需要再去实现该方法。
接口中的 default 修饰的方法也能被实现类重写
接口中的 default 方法能被重写,那么和抽象类中被重写的方法有什么区别呢?
很类似,但是抽象类不能被多继承,那么我们可以理解接口为可以被多继承的抽象类。
如果一个类继承了一个类和实现了一个接口,接口中有一个默认方法的方法名和父类中一个方法名想同,那么子类在调用时,调用的是哪个方法?
根据类优先原则,会调用继承类中的方法。
public interface AfterFatherTest {
public default void test(){
System.out.println("AfterFatherTest run ");
}
}
public class BeforeFatherTest {
public void test(){
System.out.println("BeforeFatherTest");
}
}
public class SonTest extends BeforeFatherTest implements AfterFatherTest {
}
public class DemoTest {
public static void main(String[] args) {
SonTest sonTest = new SonTest();
sonTest.test();
}
}
/**
* 执行结果
*
*/
BeforeFatherTest
如果一个类实现了两个接口,两个接口中有相同方法名的默认方法,会执行哪一个?
当实现的接口中有冲突的默认方法时,那么实现类必须重新实现这个方法。(强制定义)
public interface AfterAfterFatherTest {
public default void test(){
System.out.println("AfterAfterFatherTest run ");
}
}
SonTest的错误信息