Java - 抽象
抽象方法:
如果一个方法, 不需要实现体(函数内容), 就可以声明抽象方法
抽象方法:
没有方法体的方法, java 中使用
abstract
关键字声明的方法
访问修饰符 abstract
返回值类型 方法名称
抽象方法必须写在抽象类中
抽象类:
被 abstract
关键字声明的类, 不能直接实力化
访问修饰符 abstract class
类名
抽象父类不写抽象方法, 则子类需要写, 但抽象子类可以不写, 留给子类以后的孙类解决
注意: 抽象类中不一定有抽象方法, 有抽象方法就肯定是抽象类
如果一个类继承了抽象类, 就必须实现抽象方法, 如果一定不实现, 则这个子类也声明为抽象类
抽象类不可以创建示例, 原因: 调用抽象方法没有意义
存在的意义是为了继承给子类, 通过多态调用子类对抽象方法的实现
抽象关键字 abstract 不可以和哪些关键字共存?
- final:
final
修饰的类是无法被继承的, 而abstract
修饰的类一定要有子类. final修饰的方法无法 被覆盖, 但是abstract
修饰的方法必须要被子类去实现的 - static: 静态修饰的方法属于类的, 它存在与静态区中, 和对象就没关系了. 而抽象方法没有 方法体, 使用类名调用它没有任何意义
- private: 私有的方法子类是无法继承到的, 也不存在覆盖, 而
abstract
和private
一起使用修饰方法,abstract
需要子类去实现这个方法, 而private修饰子类根本无法得到父类这个方法. 互相矛盾
接口:
接口本质是特殊的类, 特殊抽象类
接口中所有方法都是没有实现的(抽象方法)
接口中的所有成员都是静态常量
在 jdk8 之前: 接口中的所有属性方法, 默认都是 public
的, 即使没有用 public
修饰
java 中使用 interface
关键字来定义接口
接口无法示例化, 必须使用子类, 以多态的形式完成实现
java 中, 接口可以多实现多继承
接口的定义和实现:
public interface TestInterface {
public void say();
void play();
}
public class MyInterface implements TestInterface {
@Override
public void say() {
// 代码
}
@Override
public void play() {
// 代码
}
}
在jdk8中接口可以定义普通方法, 但也只能通过多态的方式访问, 用 default
关键字修饰
public interface Test {
void show();
public default void func() {
System.out.println("执行");
}
}
也可定义静态方法, 相当于把接口做了工具类
public interface Test {
void show();
public static void func2() {
System.out.println("执行");
}
}
接口多实现多继承:
interface A {
void show1();
}
interface B {
void show2();
}
// 接口多实现
class test implements A, B {
public void show1() {
}
public void show2() {
}
}
// 接口多继承
interface C extends A, B {
void show3();
}
default关键字:
在接口中可以使用 default
关键字来声明一个默认方法, 例如:
interface Test {
int size();
default isEmpty() {
return size() == 0;
}
}
实现了该接口的类都会继承这个默认方法, 就不需要再实现
default冲突:
一:
如果有两个接口定义了相同的 default
方法, 例如
interface Test1 {
default String getName() {
return null;
}
}
interface Test2 {
default String getName() {
return null;
}
}
如果此时有一个类同时实现上面接口就会产生冲突, 需要复盖冲突的方法
public class Main implements Test1, Test2 {
@Override
public String getName() {
return Test2.super.getName(); // 或者 return Test1.super.getName();
}
}
二:
一个接口中的 default
方法和另一个接口的抽象方法相同, 那么当一个类同时实现这两个接口时会实现抽象方法而放弃 default
方法
三:
一个父类的方法和另一个接口的抽象方法相同, 那么当一个类继承这个父类并实现这个接口时, 接口的默认方法会被忽略而只考虑超类, 这也称作类优先原则
接口与抽象类的区别
相同点:
- 都位于继承的顶端, 用于被其他实现或继承
- 都不能实例化
- 都包含抽象方法, 其子类都必须覆写这些抽象方法
区别:
- 抽象类为部分方法提供实现,避免子类重复实现这些方法, 提供代码重用性
- 接口只能包含抽象方法; 一个类只能继承一个直接父类(可能是抽象类), 却可以实现多个接口(接口弥补了Java的单继承)
二者的选用:
- 优先选用接口, 尽量少用抽象类
- 需要定义子类的行为, 又要为子类提供共性功能时才选用抽象类
标记接口:
只有接口的名字, 但是没有任何方法, 是标记给 JVM 用
接口注意事项:
- 不要让
default
方法与Object
类中任何一个方法相同
静态导包:
针对于静态方法, 导入成功可以直接使用静态方法而不需要通过 className.x
的形式访问
例如:
import static java.util.Arrays.sort;
class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 34, 1, 2, 5, 76, 4};
sort(arr);
}
}