抽象类(Abstract Class)
在Java编程思想(第四版)中,这样定义抽象类的:包含抽象方法的类为抽象类,但是实际上如果一个类是抽象类,也可以没有抽象方法(一般不会这样子,没有什么意义)。
- 如果继承了抽象类,则需要实现抽象类中未实现的抽象方法,如果没有抽象方法没有全部实现的话,则该类也必须是抽象方法,否则编译无法通过而报错
- 抽象方法不能使用private修饰符,也==不宜==使用默认修饰符(default),如果使用默认修饰符(即缺省),那么其他的包即使继承了该抽象类,也无法重写该抽象方法
抽象类方法默认权限修饰符为public- JDK 1.8以前,抽象类的方法默认访问权限为 protected
- JDK 1.8时,抽象类的方法默认访问权限变为 default
- 抽象类不能创建对象
- 抽象类不一定包含抽象方法
- 抽象类中,可以有构造方法,是供子类创建对象时候使用的,子类的构造方法中,第一行默认调用了super(),即访问父类的构造方法
- 抽象方法权限修饰符必须为public或protected
抽象类总结:
如果不带修饰符,那么就是包内访问。这种情况下,不一定能保证对子类可见。如果子类和父类不在一个包下面,子类是无法访问(无法覆盖)父类的抽象方法。因此,abstract方法的访问权限==不应该==是包内访问。
所以对于abstract方法,不能使用private修饰符(导致编译出错),不能使用default修饰符(编译正常,但是不合理,后患无穷),可以使用public和protected,大多数情况下都是使用public。
接口(Interface)
接口定义:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9)
如果一个抽象类没有字段,所有方法全部都是抽象方法,就可以把该抽象类改写为接口
public interface 接口名称 {
// 抽象方法
// 默认方法 JDK8
// 静态方法 JDK8
// 私有方法 JDK9
}
-
接口不能创建对象,但是可以被实现(implements)
-
Java中,一个类只能继承一个类,而一个类可以实现多个接口,不同接口名用逗号隔开
class Student implements Person, Child { // 实现了两个interface接口 ... }
-
接口之间可以相互继承,用extends继承接口
/** * Description: 这个接口是父接口 */ public interface InterfaceBase { /** * 测试函数 */ public int test1(); } /** * Description:定义子接口 */ public interface InterfaceSub extends InterfaceBase { /** * 子接口扩充新方法 */ public int test2(); }
-
接口中的变量会被隐式地指定为
public static final
变量(并且只能是public static final
变量,用private修饰会报编译错误) -
接口的修饰符有public、abstract、default(JDK8)、static(JDK8)
-
如果只写
返回值类型 方法名称();
那么默认使用修饰符public abstract
-
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
- 默认方法不能够重写Object 基类中的方法,但却可以重载Object基类中的方法
- example:toString、equals、 hashCode 不能在接口中被覆盖,可以被重载
-
静态方法:使用 static 修饰,供接口直接调用。在实现类中可以直接调用接口的default方法,通过
接口名.方法名
调用static方法/** * 测试接口 */ public interface InterfaceTest { /** * 定义了接口的static方法 */ public static void test() { System.out.println("这是接口的静态方法!"); } } public class Test { public static void main(Sting[] args) { //直接通过 接口名.方法名() 直接调用 InterfaceTest.test(); } }
得到的结果是:
这是接口的静态方法