抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
- 一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类;一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
- 继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。
- 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象(多态)。
(假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义)
- 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
抽象类的成员
抽象类和普通类一样,可以有成员变量(属性),可以有成员方法,可以有构造方法,与普通类唯一区别就是可能存在抽象的成员方法。
- 成员变量:可以是变量、也可以是常量
- 构造方法:有构造方法,但是不能实例化。用于子类访问父类数据的初始化
- 成员方法:可以有抽象方法,限定子类必须完成某些动作。也可以有非抽象方法 提高代码服用性
接口
接口(Interface),在 JAVA 编程语言中是一个抽象类型,是抽象方法的集合。接口通常以 interface 来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口内部的成员变量
- 成员变量:只能是常量,默认修饰符 public static final
- 构造方法:没有,因为接口主要是扩展功能的,而没有具体存在
- 成员方法:只能是抽象方法,默认修饰符 public abstract
JDK8 以后接口的成员:
(default,default是在java8中引入的关键字,也可称为Virtual extension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。可以有方法体了)
- 含有默认方法和静态方法
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
静态方法:使用 static 修饰,供接口直接调用。 - 含有私有方法和私有静态方法
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。
接口实现
- 必须重写接口中所有抽象方法。
- 默认方法(default),可以继承,可以重写,二选一,但是只能通过实现类的对象来调用。
- 接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。
- 静态方法的使用,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用。
- 私有方法:只有默认方法可以调用。
私有静态方法:默认方法和静态方法可以调用。
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。 - 接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次。
- 一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。
public interface InterfaceDemo {
void method1();
public static void method2() {
System.out.println("method2");
}
}
public class Test implements InterfaceDemo {
@Override
public void method1() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
//Test.method2();//报错
InterfaceDemo.method2();
}
}
- 当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法。
public interface A {
public default void methodA() {
System.out.println("method A");
}
}
public class D {
public void methodA() {
System.out.println("method D");
}
}
public class C extends D implements A {
}
public class Test {
public static void main(String[] args) {
C c = new C();
c.methodA();//输出:method D
}
}