据我所知(如果我错了,请纠正),抽象类是不能被实例化的。你可以给它一个构造函数,但只是不能在该类上调用new。如果在子类中调用super,那么父类的构造函数将会运行(从而创建一个该类的对象?),那么为什么你实际上可以在抽象类的子类中调用super呢?
我相信这与我对构造函数制作对象的误解有关...
我相信这与我对构造函数制作对象的误解有关...
super(...)
并不会调用超类的构造函数来创建超类的对象,而是仅执行超类构造函数中定义的任何行为(无论是否为抽象)。这是在创建当前类的实例时发生的。 - Luiggi Mendoza在抽象类中调用构造函数只用于设置特定于该抽象类的属性-否则在抽象类的每个实现中设置这些属性将会很繁琐。该能力可消除样板代码。
在下面的示例中,可以看到如何基于车辆的其他属性计算汽车寿命。在每个Car
子类型的实现中执行此操作是过度的。
abstract class Car {
// Determine how many years a car will last based on other components
int lifeTimeInYears;
float price;
public Car(float price) {
// Assuming you could calculate the longevity based on price;
if (price > 50000) {
lifeTimeInYears = 15;
}
else {
lifeTimeInYears = 10;
}
}
public int getLifeTimeInYears() {
return lifeTimeInYears;
}
}
class SportsCar extends Car {
public SportsCar(float price) {
super(price);
}
}
class CommuterCar extends Car {
public CommuterCar(float price) {
super(price);
}
}
public class Test {
public static void main(String[] args) {
SportsCar sportsCar = new SportsCar(150000);
sportsCar.getLifeTimeInYears(); // Value is 15
CommuterCar commuterCar = new CommuterCar(15000);
commuterCar.getLifeTimeInYears(); // Value is 10
}
}
我会尝试以字节码的方式来解释,看看是否有帮助。
AbstractService.java
public abstract class AbstractService {
protected int id = 10;
public abstract void verify();
}
Service.java
public class Service extends AbstractService{
public static void main(String[] args) {
Service service = new Service();
service.verify();
}
public void verify() {
System.out.println("printing id = "+id);
}
}
public abstract class AbstractService {
protected int id;
public AbstractService() {
/* L4 */
0 aload_0; /* this */
1 invokespecial 1; /* java.lang.Object() */
/* L6 */
4 aload_0; /* this */
5 bipush 10;
7 putfield 2; /* .id */
10 return;
}
public abstract void verify();
}
public class Service extends com.sample.service.AbstractService {
public Service() {
/* L3 */
0 aload_0; /* this */
1 invokespecial 1; /* com.sample.service.AbstractService() */
4 return;
}
public static void main(java.lang.String[] args) {
/* L6 */
0 new 2;
3 dup;
4 invokespecial 3; /* com.sample.service.Service() */
7 astore_1; /* service */
/* L7 */
8 aload_1; /* service */
9 invokevirtual 4; /* void verify() */
/* L8 */
12 return;
}
public void verify() {
/* Skipping this as it's not needed */
}
}
Service service = new Service();
Service service = new Service();
0 new 2;
3 dup;
4 invokespecial 3; /* com.sample.service.Service() */