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

Sze*_*eri 585 java constructor abstract-class

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

如果是这样,它如何使用以及用于何种目的?

Mic*_*urd 621

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @Jonathon:为回答问题而增加复杂性并没有带来真正的好处.如果问题是关于范围的,那么,是的,将三种有用的可能性进行对比是有意义的. (80认同)
  • 你真的想让Product.Product()标记为公开吗? (34认同)
  • 我认为Jonathon试图说的是,抽象类上的公共构造函数没有任何意义,因为你不能直接实例化一个抽象类(只能通过一个本身未标记为抽象的派生类型实例化). (33认同)
  • 'TimesTwo'中的构造函数不是默认构造函数. (7认同)
  • 我认为澄清最后一句是很好的,说明这只是在这个例子中,如果没有显式声明,通常抽象类有默认构造函数 (2认同)
  • 与NOTE和Vic的注释类似,如果一个抽象类扩展了另一个没有默认构造函数的类,则抽象类必须具有一个构造函数,该构造函数将调用它正在扩展的类的非默认构造函数。 (2认同)

jfp*_*ret 153

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

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

注意:

  • 你可以定义多个构造函数(使用不同的参数)
  • 你可以(应该?)定义所有受保护的构造函数(无论如何都将它们公开是没有意义的)
  • 你的子类构造函数可以调用抽象类的一个构造函数; 它甚至可能需要调用它(如果抽象类中没有no-arg构造函数)

在任何情况下,不要忘记,如果你没有定义一个构造函数,那么编译器会自动为你生成一个(这个是公共的,没有参数,什么都不做).


Law*_*Dol 57

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


Ani*_*kur 38

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

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

当我们创建任何子类的对象时,相应的继承树中的所有构造函数都是从上到下的方法调用的.同样的情况适用于抽象类.虽然我们不能创建抽象类的对象,但是当我们创建一个类的对象时,它是抽象类的具体和子类,抽象类的构造函数会被自动调用.因此,我们可以在抽象类中使用构造函数.

注意:非抽象类不能有抽象方法,但抽象类可以有非抽象方法.Reason与构造函数类似,不同之处在于我们可以调用super()而不是自动调用.此外,没有什么比抽象构造函数更好,因为它完全没有意义.

  • 说明_...抽象类的构造函数是自动调用的... ...这只适用于抽象类的默认构造函数,其他函数必须通过super(args)显式调用. (9认同)
  • 可以自动调用非默认构造函数,前提是它们是无参数构造函数。所以它不仅适用于默认构造函数。 (2认同)

Mat*_*ttC 13

它不仅可以,它始终如此.如果你没有指定一个,那么它就有一个默认的没有arg构造函数,就像任何其他类一样.实际上,所有类(包括嵌套类和匿名类)都将获得默认构造函数(如果未指定一个)(在匿名类的情况下,无法指定一个,因此您将始终获得默认构造函数).

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


小智 6

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


小智 6

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

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

所以使用super你可以在抽象类的构造函数中传递值,据我所知,它必须是你的方法或构造函数中的第一个语句.


Raj*_*ral 6

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

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

参考:本文


Ket*_*n G 5

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

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

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()); 
    } 
}
Run Code Online (Sandbox Code Playgroud)

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


小智 5

尽管有很多好的答案,我还是要给我2美分。

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

是的,Abstract类始终具有构造函数。如果未定义自己的构造函数,则编译器将为Abstract类提供默认的构造函数。以上适用于所有类-嵌套,抽象,匿名等。

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在扩展抽象类之上时要小心,您必须从每个构造函数中显式调用super。任何构造函数的第一行都调用super()。如果您未显式调用super(),则Java将为您完成此操作。下面的代码将无法编译:

public class Imp extends Abs{

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

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

public class Imp extends Abs{

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