Java 抽象类
在面向对象概念中,所有对象都是通过类来描绘(实例化)的,但并非所有类都可以用来实例化对象的。类似于 TypeScript,java 中有抽象类
概念。
抽象类不能实例化为对象,但是类的其他功能依然在。
由于抽象类不能被实例化为对象,因此抽象类只能被继承然后使用。
定义抽象类
在 java 中同样使用abstract class
来定义抽象类。
抽象方法
abstract 关键字除了定义抽象类还可以定义抽象方法,声明抽象方法必须满足一下要求:
- 抽象方法的定义不需要方法体。
- 抽象类可以包含抽象方法,普通类不可以。
- 如果父类包含抽象方法,则子类继承父类的时候必须重写父类的抽象方法,或者自身声明为抽象类。
继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。
// 父类 抽象类
public abstract class AbstractTest {
public String name;
public int age;
private String secretKey = "SECRET_KEY";
public AbstractTest(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void say() {
System.out.println("name: " + name + " age:" + age + " secret key: " + secretKey);
}
public abstract String getInfo(String prop); // 定义抽象方法
}
//子类
public class AbstractChild extends AbstractTest {
public AbstractChild(String name, int age) {
super(name, age);
}
// 子类必须重写父类的抽象方法,否则编译器会报错
public String getInfo(String prop) {
switch (prop) {
case "name":
return this.name;
case "age":
return "age is " + this.age;
default:
return "nothing";
}
}
public static void main(String[] args) {
AbstractChild test = new AbstractChild("ABSTRACT_CHILD", 10);
test.say(); // name: Abstract-CHILD age:10 secret key: SECRET_KEY
test.setAge(20);
test.setName("ABSTRACT_CHILD_NEW_NAME");
test.say(); // name: ABSTRACT_CHILD_NEW_NAME age:20 secret key: SECRET_KEY
System.out.println(test.getInfo("name")); // ABSTRACT_CHILD_NEW_NAME
System.out.println(test.getInfo("age")); // age is 20
System.out.println(test.getInfo("")); // nothing
// System.out.println(test.secretKey); // 报错 secretKey是private属性 子类实例无法访问
// AbstractTest testAgain = new AbstractTest();// 报错 Cannot instantiate the type
// AbstractTest 因为抽象类无法被实例化
}
}
总结
- 抽象类不能被实例化,抽象类的非抽象类子类才可以被实例化。
- 抽象类不一定包含抽象方法,但是有抽象方法的类一定是抽象类。
- 抽象类中的抽象方法只做声明,不包含方法体(子类重写方法一定要满足重写的要求:比如方法名、参数以及返回值不能变)。
- 构造方法和类方法(static声明的方法,也叫静态方)不能声明为抽象方法。
- 抽象类的子类如果不是抽象类,就必须给出抽象类中的抽象方法的具体实现。