在抽象类中调用构造函数

时间:2014-06-19 07:11:39

标签: java oop constructor abstract-class

是否可以在抽象类中调用构造函数?

我读到这个构造函数可以通过它的一个非抽象子类来调用。但我不理解这种说法。任何人都可以用一个例子来解释这个吗?

5 个答案:

答案 0 :(得分:6)

您可以在抽象类中定义构造函数,但不能构造该对象。但是,具体的子类可以(并且必须)调用抽象父类中定义的构造函数之一。

请考虑以下代码示例:

public abstract class Test {

    // abstract class constructor
    public Test() {
        System.out.println("foo");
    }

    // concrete sub class
    public static class SubTest extends Test {    
      // no constructor defined, but implicitly calls no-arg constructor 
      // from parent class
    }

    public static void main(String[] args) throws Exception {
        Test foo = new Test(); // Not allowed (compiler error)
        SubTest bar = new SubTest(); // allowed, prints "foo"
    }
}

答案 1 :(得分:2)

您不能使用类实例创建表达式调用抽象类构造函数,即

// Invalid
AbstractClass x = new AbstractClass(...);

但是,在构造对象时,您总是会遍历整个继承层次结构的构造函数。因此,子类中的构造函数可以使用super(...)调用其抽象超类的构造函数。例如:

public class Abstract {
    protected Abstract(int x) {
    }
}

public class Concrete {
    public Concrete(int x, int y) {
        super(x); // Call the superclass constructor
    }
}

由于抽象类的构造函数只能在子类构造函数中调用 (并且通过在同一个类中将一个链接到另一个),我通常会将它们protected ...制作它们{ {1}}没有用处。

如果未在具体的子类构造函数中指定publicsuper(...)调用,则通常的规则适用 - 它等同于构造函数开头的this(...)语句,调用超类中的无参数构造函数...所以必须 这样的构造函数。

答案 2 :(得分:0)

在这个示例Java程序中,我们有一个抽象类Servidor,它有一个参数构造函数,它接受name。 Subclass在创建Servidor的具体实例并覆盖抽象方法start()时为超类提供该名称。由于这个程序编译运行正常,你可以肯定地说抽象类可以在Java中有构造函数。

public class AbstractConstructorTest {

public static void main(String args[]) {
   Servidor Servidor = new Tomcat("Apache Tomcat");
   Servidor.start();
}

}

抽象类Servidor {     protected final String name;

public Servidor(String name){
    this.name = name;
}

public abstract boolean start();

}

类Tomcat扩展了Servidor {

public Tomcat(String name){
    super(name);
}

@Override
public boolean start() {
   System.out.println( this.name + " started successfully");
   return true;
}

}

输出: Apache Tomcat成功启动

答案 3 :(得分:0)

你显然可以这样做:

public class ConcreteClass extends AbstractClass {
    public ConcreteClass(){ // concrete class constructor
        super(); // abstract class constructor
    }
}

抽象类的构造函数只能在从它继承的具体类的构造函数中使用。

答案 4 :(得分:0)

抽象和具体类类似于Java中的泛化和专业化,可以使用继承来执行。让我用一个简单明了的例子来解释。假设我们有一个“DBConnector”类。它似乎是更通用的类,它的意义更少实例化类(你连接的DB,驱动程序因每个数据库权限而异)。因此,我们可以使DBConnector成为抽象的。这就是我们基本上无法实例化Abstract类的原因。 现在我们可以为每个数据库创建不同的具体类,扩展我们的具体类的行为,如“OracelDBConnector”,“MySQLDBConnector”等。当我们将抽象类的属性继承到具体类时,我们理想地使用抽象类初始化抽象类属性构造函数使用具体类构造函数使用super(参数列表)。

谢谢, JK