简体   繁体   English

在抽象类中调用构造函数

[英]Call constructor in an abstract class

Is it possible to call a constructor in a abstract class? 是否可以在抽象类中调用构造函数?

I read that this constructor can be called through one of its non-abstract subclasses. 我读到这个构造函数可以通过它的一个非抽象子类来调用。 But I don't understand that statement. 但我不明白这个说法。 Can anybody explain this with an example? 有人可以用一个例子来解释这个吗?

You can define a constructor in an abstract class, but you can't construct that object. 您可以在抽象类中定义构造函数,但不能构造该对象。 However, concrete sub-classes can (and must) call one of the constructors defined in the abstract parent class. 但是,具体的子类可以(并且必须)调用抽象父类中定义的构造函数之一。

Consider the following code example: 请考虑以下代码示例:

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"
    }
}

You can't call an abstract class constructor with a class instance creation expression, ie 您不能使用类实例创建表达式调用抽象类构造函数,即

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

However, in constructing an object you always go through the constructors of the whole inheritance hierarchy. 但是,在构造对象时,您始终会遍历整个继承层次结构的构造函数。 So a constructor from a subclass can call the constructor of its abstract superclass using super(...) . 因此,子类中的构造函数可以使用super(...)调用其抽象超类的构造函数。 For example: 例如:

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

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

As constructors of abstract classes can only be called within subclass constructors (and by chaining one to another within the same class), I typically make them protected ... making them public would serve no purpose. 由于抽象类的构造函数只能在子类构造函数中调用(并且通过在同一个类中将一个链接到另一个),我通常会使它们protected ......将它们public将不起作用。

The normal rules apply if you don't specify a super(...) or this(...) call in a concrete subclass constructor - it's equivalent to a super(); 如果您没有在具体的子类构造函数中指定super(...)this(...)调用,则适用常规规则 - 它等效于super(); statement at the start of a constructor, calling a parameterless constructor in the superclass... so there'd have to be such a constructor. 声明在构造函数开始,调用父类参数的构造函数...所以就得这样一个构造函数。

In this example Java program, we have an abstract class Servidor, which has one parametric constructor, which accepts name. 在这个示例Java程序中,我们有一个抽象类Servidor,它有一个参数构造函数,它接受name。 Subclass provides that name to superclass while creating concrete instance of Servidor and overriding abstract method start(). Subclass在创建Servidor的具体实例并覆盖抽象方法start()时为超类提供该名称。 Since this program compile and run fine you can definitely say abstract class can have constructors in Java. 由于这个程序编译运行正常,你可以肯定地说抽象类可以在Java中有构造函数。

public class AbstractConstructorTest { 公共类AbstractConstructorTest {

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

} }

abstract class Servidor{ protected final String name; 抽象类Servidor {protected final String name;

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

public abstract boolean start();

} }

class Tomcat extends Servidor{ class Tomcat扩展Servidor {

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

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

} }

Output: Apache Tomcat started successfully 输出:Apache Tomcat成功启动

You can obviously do something like: 你显然可以这样做:

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

A constructor of an abstract class can be used only inside constructors of concrete classes inheriting from it. 抽象类的构造函数只能在从其继承的具体类的构造函数中使用。

Abstract and Concrete classes are something like Generalization and Specialization in Java and can be executed using inheritance. 抽象和具体类类似于Java中的泛化和专业化,可以使用继承来执行。 Let me explain with a plain and simple example. 让我用一个简单明了的例子来解释。 Say we have a class "DBConnector". 假设我们有一个“DBConnector”类。 It seems to be more generalized class and its meaning less to instantiate the class (which DB you are connecting to, driver vary for each DB right). 它似乎是更通用的类,它的意义更少实例化类(你连接的DB,驱动程序因每个数据库权限而异)。 Hence we can make DBConnector as abstract. 因此,我们可以使DBConnector成为抽象的。 That is the reason why we cannot basically instantiate Abstract classes. 这就是我们基本上无法实例化Abstract类的原因。 Now we can create different concrete classes for each database extending the behavior of our concrete class like "OracelDBConnector", "MySQLDBConnector" etc., As we inherit the properties of abstract class into concrete class, we initialize the abstract class properties ideally using abstract class constructor using concrete class constructor using super(parameter list). 现在我们可以为每个数据库创建不同的具体类,扩展我们的具体类的行为,如“OracelDBConnector”,“MySQLDBConnector”等。当我们将抽象类的属性继承到具体类时,我们理想地使用抽象类初始化抽象类属性构造函数使用具体类构造函数使用super(参数列表)。

Thanks, JK 谢谢,JK

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM