抽象类可以有构造函数吗?

发布于 2024-07-08 00:15:14 字数 48 浏览 8 评论 0原文

抽象类可以有构造函数吗?

如果可以,如何使用以及用于什么目的?

Can an abstract class have a constructor?

If so, how can it be used and for what purposes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

幸福不弃 2024-07-15 00:15:14

是的,抽象类可以有构造函数。 考虑一下:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

超类 Product 是抽象的并且有一个构造函数。 具体类 TimesTwo 有一个构造函数,仅对值 2 进行硬编码。具体类 TimesWhat 有一个构造函数,允许调用者指定值。

抽象构造函数经常用于强制执行类约束或不变量,例如设置类所需的最小字段。

注意:由于父级中没有默认(或无参数)构造函数
抽象类,子类中使用的构造函数必须显式调用
父构造函数。

Yes, an abstract class can have a constructor. Consider this:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.

Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.

NOTE: As there is no default (or no-arg) constructor in the parent
abstract class, the constructor used in subclass must explicitly call
the parent constructor.

温柔戏命师 2024-07-15 00:15:14

如果您处于以下情况之一,您可以在抽象类中定义构造函数:

  • 您想要执行一些操作
    初始化(到的字段
    抽象类)之前
    实际上子类的实例化
    您已
  • 在中定义了最终字段
    抽象类,但你没有
    在声明中初始化它们
    本身; 在这种情况下,你必须有
    一个构造函数来初始化这些
    fields

注意:

  • 你可以定义多个
    构造函数(具有不同的
    参数)
  • 你可以(应该?)定义你所有的
    构造函数受保护(使它们
    public 无论如何都是毫无意义的)
  • 你的子类构造函数可以
    调用抽象的一个构造函数
    班级; 它甚至可能必须调用它
    (如果没有无参数构造函数
    在抽象类中)

无论如何,不​​要忘记,如果你没有定义构造函数,那么编译器会自动为你生成一个构造函数(这个是公共的,没有参数,并且不执行任何操作)。

You would define a constructor in an abstract class if you are in one of these situations:

  • you want to perform some
    initialization (to fields of the
    abstract class) before the
    instantiation of a subclass actually
    takes place
  • you have defined final fields in the
    abstract class but you did not
    initialize them in the declaration
    itself; in this case, you MUST have
    a constructor to initialize these
    fields

Note that:

  • you may define more than one
    constructor (with different
    arguments)
  • you can (should?) define all your
    constructors protected (making them
    public is pointless anyway)
  • your subclass constructor(s) can
    call one constructor of the abstract
    class; it may even have to call it
    (if there is no no-arg constructor
    in the abstract class)

In any case, don't forget that if you don't define a constructor, then the compiler will automatically generate one for you (this one is public, has no argument, and does nothing).

烟花肆意 2024-07-15 00:15:14

是的,它可以有一个构造函数,并且它的定义和行为就像任何其他类的构造函数一样。 除了抽象类不能直接实例化,只能扩展之外,因此使用总是来自子类的构造函数。

Yes it can have a constructor and it is defined and behaves just like any other class's constructor. Except that abstract classes can't be directly instantiated, only extended, so the use is therefore always from a subclass's constructor.

守不住的情 2024-07-15 00:15:14

是的抽象类可以有构造函数

是的,当我们将一个类定义为抽象类时,它不能被实例化,但这并不意味着抽象类不能有构造函数。 每个抽象类必须有一个具体的子类,该子类将实现该抽象类的抽象方法。

当我们创建任何子类的对象时,相应继承树中的所有构造函数都会以自上而下的方式调用。 同样的情况也适用于抽象类。 虽然我们不能创建抽象类的对象,但是当我们创建具体类的对象并且是抽象类的子类时,会自动调用抽象类的构造函数。 因此我们可以在抽象类中拥有一个构造函数。

注意:非抽象类不能有抽象方法,但抽象类可以有非抽象方法。 Reason 与构造函数类似,区别在于我们可以调用 super(),而不是自动调用。 此外,没有什么比抽象构造函数更好的了,因为它根本没有意义。

Yes! Abstract classes can have constructors!

Yes, when we define a class to be an Abstract Class it cannot be instantiated but that does not mean an Abstract class cannot have a constructor. Each abstract class must have a concrete subclass which will implement the abstract methods of that abstract class.

When we create an object of any subclass all the constructors in the corresponding inheritance tree are invoked in the top to bottom approach. The same case applies to abstract classes. Though we cannot create an object of an abstract class, when we create an object of a class which is concrete and subclass of the abstract class, the constructor of the abstract class is automatically invoked. Hence we can have a constructor in abstract classes.

Note: A non-abstract class cannot have abstract methods but an abstract class can have a non-abstract method. Reason is similar to that of constructors, difference being instead of getting invoked automatically we can call super(). Also, there is nothing like an abstract constructor as it makes no sense at all.

噩梦成真你也成魔 2024-07-15 00:15:14

不仅可以,而且总是如此。 如果您没有指定,那么它有一个默认的无参数构造函数,就像任何其他类一样。 事实上,如果未指定,所有类(包括嵌套类和匿名类)都会获得默认构造函数(对于匿名类,不可能指定一个,因此您将始终获得默认构造函数)。

具有构造函数的抽象类的一个很好的例子是 Calendar 类。 您可以通过调用 Calendar.getInstance() 来获取 Calendar 对象,但它也有受保护的构造函数。 它的构造函数受到保护的原因是只有它的子类可以调用它们(或同一包中的类,但由于它是抽象的,因此不适用)。 GregorianCalendar 是一个扩展 Calendar 的类的示例。

Not only can it, it always does. If you do not specify one then it has a default no arg constructor, just like any other class. In fact, ALL classes, including nested and anonymous classes, will get a default constructor if one is not specified (in the case of anonymous classes it is impossible to specify one, so you will always get the default constructor).

A good example of an abstract class having a constructor is the Calendar class. You get a Calendar object by calling Calendar.getInstance(), but it also has constructors which are protected. The reason its constructors are protected is so that only its subclasses can call them (or classes in the same package, but since it's abstract, that doesn't apply). GregorianCalendar is an example of a class that extends Calendar.

意犹 2024-07-15 00:15:14

虽然有很多好的答案,但我还是想给出我的2分钱。

构造函数不构建对象。 它用于初始化一个对象。

是的,抽象类总是有一个构造函数。 如果没有定义自己的构造函数,编译器会给抽象类一个默认的构造函数。
上述适用于所有类 - 嵌套类、抽象类、匿名类等。

抽象类(与接口不同)可以具有需要初始化的非最终非静态字段。 您可以在抽象类中编写自己的构造函数来执行此操作。 但是,在这种情况下,不会有任何默认构造函数。

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

在扩展上面的抽象类时要小心,你必须从每个构造函数中显式调用 super。 任何构造函数的第一行都会调用 super()。 如果你没有显式调用 super(),Java 会为你做这件事。
下面的代码将无法编译:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

您必须像下面的示例一样使用它:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}

Although there are many good answers, I would like to give my 2 cents.

Constructor DOES NOT BUILD THE OBJECT. It is used to initialize an object.

Yes, an Abstract class always has a constructor. If you do not define your own constructor, the compiler will give a default constructor to the Abstract class.
Above holds true for all classes - nested, abstract, anonymous, etc.

An abstract class (unlike interface) can have non-final non-static fields which need initialization. You can write your own constructor in the abstract class to do that. But, in that case, there won't be any default constructor.

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

Be careful while extending above abstract class, you have to explicitly call super from each constructor. The first line of any constructor calls to super(). if you do not explicitly call super(), Java will do that for you.
Below code will not compile:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

You have to use it like below example:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}
醉南桥 2024-07-15 00:15:14

抽象类可以有构造函数,但不能创建抽象类的对象,那么如何使用该构造函数呢?

问题是,当您在子类中继承该抽象类时,您可以通过子类中的 super(value) 方法将值传递给其(抽象的)构造函数,并且您不会继承构造函数。

因此,使用 super 您可以在抽象类的构造函数中传递值,据我记得它必须是方法或构造函数中的第一个语句。

An abstract class can have a constructor BUT you can not create an object of abstract class so how do you use that constructor?

Thing is when you inherit that abstract class in your subclass you can pass values to its(abstract's) constructor through super(value) method in your subclass and no you don't inherit a constructor.

so using super you can pass values in a constructor of the abstract class and as far as I remember it has to be the first statement in your method or constructor.

围归者 2024-07-15 00:15:14

当然,抽象类可以有构造函数。一般类构造函数用于初始化字段。因此,抽象类构造函数用于初始化抽象类的字段。 如果您想在子类实例化之前初始化抽象类的某些字段,则可以为抽象类提供构造函数。 抽象类构造函数还可用于执行与每个子类相关的代码。 这可以防止代码重复。

我们不能创建抽象类的实例,但是我们可以创建从抽象类派生的类的实例。 因此,当创建派生类的实例时,会自动调用父抽象类的构造函数。

参考:本文

Of Course, abstract class can have a constructor.Generally class constructor is used to initialise fields.So, an abstract class constructor is used to initialise fields of the abstract class. You would provide a constructor for an abstract class if you want to initialise certain fields of the abstract class before the instantiation of a child-class takes place. An abstract class constructor can also be used to execute code that is relevant for every child class. This prevents code duplication.

We cannot create an instance of an abstract class,But we can create instances of classes those are derived from the abstract class. So, when an instance of derived class is created, the parent abstract class constructor is automatically called.

Reference :This Article

烟柳画桥 2024-07-15 00:15:14

是的,可以,抽象类构造函数通常用于所有子类共有的初始化事件的超级调用

Yes it can, abstract classes constructors are generally used for super calls for initialization events common to all the subclasses

单挑你×的.吻 2024-07-15 00:15:14

是的,抽象类可以有构造函数!

这是一个在抽象类中使用构造函数的示例:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

所以我想你已经找到答案了。

Yes, Abstract Classes can have constructors !

Here is an example using constructor in abstract class:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

So I think you got the answer.

简美 2024-07-15 00:15:14

正如 javafuns 此处所述,这是一个示例:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}

As described by javafuns here, this is an example:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}
醉生梦死 2024-07-15 00:15:14

在具体类中,具体类型 Fnord 的构造函数的声明有效地公开了两件事:

  • 代码可以请求创建 Fnord 实例的方法

  • A 表示正在构造的 Fnord 派生类型的实例可以请求初始化所有基类功能。

虽然也许应该有一种方法可以单独控制这两种能力,但对于每种具体类型,一个定义将同时启用这两种能力。 尽管第一个能力对于抽象类没有意义,但第二个能力对于抽象类和任何其他类一样有意义,因此它的声明同样必要和有用。

In a concrete class, declaration of a constructor for a concrete type Fnord effectively exposes two things:

  • A means by which code can request the creation of an instance of Fnord

  • A means by which an instance of a type derived from Fnord which is under construction can request that all base-class features be initialized.

While there should perhaps be a means by which these two abilities could be controlled separately, for every concrete type one definition will enable both. Although the first ability is not meaningful for an abstract class, the second ability is just as meaningful for an abstract class as it would be for any other, and thus its declaration is just as necessary and useful.

寒江雪… 2024-07-15 00:15:14

抽象类可以有构造函数,但不能实例化。 但是抽象类中定义的构造函数可以用于该抽象类的具体类的实例化。 检查 JLS

如果尝试使用类实例创建来创建抽象类的实例,则会出现编译时错误
表达

抽象类的子类本身不是抽象的,可能是
实例化,导致执行构造函数
抽象类以及字段初始值设定项的执行
例如该类的实例变量。

Abstract class can have a constructor though it cannot be instantiated. But the constructor defined in an abstract class can be used for instantiation of concrete class of this abstract class. Check JLS:

It is a compile-time error if an attempt is made to create an instance of an abstract class using a class instance creation
expression
.

A subclass of an abstract class that is not itself abstract may be
instantiated, resulting in the execution of a constructor for the
abstract class and, therefore, the execution of the field initializers
for instance variables of that class.

情泪▽动烟 2024-07-15 00:15:14

是的。 当创建继承类的实例时,将调用抽象类的构造函数。 例如,以下是一个有效的 Java 程序。

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

这是上面代码的输出,

Base Constructor Called
派生构造函数调用

参考:
在此处输入链接说明

yes it is. And a constructor of abstract class is called when an instance of a inherited class is created. For example, the following is a valid Java program.

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

This is the output of the above code,

Base Constructor Called
Derived Constructor Called

references:
enter link description here

凉城凉梦凉人心 2024-07-15 00:15:14

是的,抽象类可以有构造函数。 您可以在抽象类中重载任意数量的构造函数。 这些承包商可用于初始化扩展抽象类的对象的初始状态。 众所周知,我们无法创建抽象类的对象,因为对象是由“new”关键字创建的,而不是由构造函数创建的……它们仅用于初始化子类对象的状态。

Yes, an Abstract Class can have a Constructor. You Can Overload as many Constructor as you want in an Abstract Class. These Contractors Can be used to Initialized the initial state of the Objects Extending the Abstract Class. As we know we can't make an object of an Abstract Class because Objects are Created by the "new" keywords and not by the constructors...they are there for only initializing the state of the subclass Objects.

臻嫒无言 2024-07-15 00:15:14

考虑一下:

abstract class Product { 
    int value;
    public Product( int val ) {
        value= val;
    }
    abstract public int multiply();
}

class TimesTwo extends Product {
    public int mutiply() {
       return value * 2;
    }
}

超类是抽象的并且有一个构造函数。

Consider this:

abstract class Product { 
    int value;
    public Product( int val ) {
        value= val;
    }
    abstract public int multiply();
}

class TimesTwo extends Product {
    public int mutiply() {
       return value * 2;
    }
}

The superclass is abstract and has a constructor.

桃扇骨 2024-07-15 00:15:14

是的,您当然可以添加一个,正如在抽象类变量的初始化中已经提到的那样。
但是,如果您没有显式声明一个,它无论如何都有一个隐式构造函数供“构造函数链接”工作。

Yes surely you can add one, as already mentioned for initialization of Abstract class variables.
BUT if you dont explicitly declare one, it anyways has an implicit constructor for "Constructor Chaining" to work.

旧时模样 2024-07-15 00:15:14

由于抽象类可以拥有所有访问修饰符的变量,因此必须将它们初始化为默认值,因此构造函数是必要的。
当实例化子类时,将调用抽象类的构造函数并初始化变量。

相反,接口确实只包含常量变量,这意味着它们已经初始化。 所以接口不需要构造函数。

Since an abstract class can have variables of all access modifiers, they have to be initialized to default values, so constructor is necessary.
As you instantiate the child class, a constructor of an abstract class is invoked and variables are initialized.

On the contrary, an interface does contain only constant variables means they are already initialized. So interface doesn't need a constructor.

半窗疏影 2024-07-15 00:15:14

为了实现构造函数链,抽象类将有一个构造函数。
编译器将 Super() 语句保留在子类构造函数中,该语句将调用超类构造函数。 如果抽象类没有构造函数,那么就违反了 java 规则,并且我们无法实现构造函数链接。

In order to achieve constructor chaining, the abstract class will have a constructor.
The compiler keeps Super() statement inside the subclass constructor, which will call the superclass constructor. If there were no constructors for abstract classes then java rules are violated and we can't achieve constructor chaining.

A君 2024-07-15 00:15:14

类中构造函数的用途是用于初始化字段,而不是“构建对象”。 当您尝试创建抽象超类的新实例时,编译器会给您一个错误。 但是,我们可以继承一个抽象类 Employee 并通过设置其变量来使用其构造函数,请参见下面的示例

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}

The purpose of the constructor in a class is used to initialize fields but not to "build objects". When you try to create a new instance of an abstract SuperClass, the compiler will give you an error. However, we can inherit an abstract class Employee and make use of its constructor by setting its variables See example below

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}
把人绕傻吧 2024-07-15 00:15:14
package Test1;

public class AbstractClassConstructor {

    public AbstractClassConstructor() {
        
    }

    public static void main(String args[]) {
       Demo obj = new Test("Test of code has started");
       obj.test1();
    }
}

abstract class Demo{
    protected final String demoValue;
       
    public Demo(String testName){
        this.demoValue = testName;
    }
       
    public abstract boolean test1();
}

class Test extends Demo{
       
    public Test(String name){
        super(name);
    }

    @Override
    public boolean test1() {
       System.out.println( this.demoValue + " Demo test started");
       return true;
    }
   
}
package Test1;

public class AbstractClassConstructor {

    public AbstractClassConstructor() {
        
    }

    public static void main(String args[]) {
       Demo obj = new Test("Test of code has started");
       obj.test1();
    }
}

abstract class Demo{
    protected final String demoValue;
       
    public Demo(String testName){
        this.demoValue = testName;
    }
       
    public abstract boolean test1();
}

class Test extends Demo{
       
    public Test(String name){
        super(name);
    }

    @Override
    public boolean test1() {
       System.out.println( this.demoValue + " Demo test started");
       return true;
    }
   
}
热血少△年 2024-07-15 00:15:14

是的..它就像任何其他课程一样。 它可以有一个构造函数,并在为基类创建对象后调用它。

Yes..It is like any other class. It can have a constructor and it is called after creating object for the base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文