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

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

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

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

21个解决方案

546 votes

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

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有一个允许调用者指定值的构造函数。

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

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

Michael Rutherfurd answered 2019-01-24T22:20:42Z

139 votes

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

你想表演一些初始化(到的字段)抽象类)之前实际上实例化了一个子类发生了

你已经定义了最终的字段抽象类,但你没有在声明中初始化它们本身; 在这种情况下,你必须有用于初始化这些的构造函数领域

注意:

你可以定义多个构造函数(具有不同的参数)

你可以(应该?)定义你的所有构造者受到保护(制造它们无论如何,公众毫无意义)

你的子类构造函数可以调用一个抽象的构造函数类; 它甚至可能需要调用它(如果没有no-arg构造函数在抽象类中)

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

jfpoilpret answered 2019-01-24T22:21:45Z

52 votes

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

Lawrence Dol answered 2019-01-24T22:22:07Z

32 votes

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

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

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

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

Aniket Thakur answered 2019-01-24T22:22:49Z

13 votes

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

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

MattC answered 2019-01-24T22:23:18Z

5 votes

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

Jacob answered 2019-01-24T22:23:40Z

5 votes

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

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

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

Alok answered 2019-01-24T22:24:15Z

4 votes

虽然有很多好的答案,但我想给我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);

}

}

在扩展上面的抽象类时要小心,你必须从每个构造函数显式调用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");

}

}

Harshil answered 2019-01-24T22:25:10Z

3 votes

考虑一下:

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;

}

}

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

S.Lott answered 2019-01-24T22:25:33Z

3 votes

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

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

参考:本文

Raj Baral answered 2019-01-24T22:26:09Z

2 votes

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

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

从正在构造的Fnord派生的类型的实例可以请求初始化所有基类功能的方法。

虽然应该有一种方法可以分别控制这两种能力,但对于每种具体类型,一种定义都可以实现这两种能力。 虽然第一种能力对于抽象类没有意义,但第二种能力对于抽象类来说和其他任何能力一样有意义,因此它的声明同样必要且有用。

supercat answered 2019-01-24T22:26:50Z

1 votes

正如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

}

}

jaideep answered 2019-01-24T22:27:12Z

1 votes

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

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

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());

}

}

所以我认为你得到了答案。

Ketan G answered 2019-01-24T22:27:46Z

1 votes

尽管抽象类无法实例化,但它可以有一个构造函数。 但是,抽象类中定义的构造函数可用于实例化此抽象类的具体类。 检查JLS:

如果尝试使用类实例创建创建抽象类的实例,则这是编译时错误   表达。

抽象类的子类本身不是抽象的可能是   实例化,导致执行构造函数   抽象类,因此,字段初始化程序的执行   例如该类的变量。

i_am_zero answered 2019-01-24T22:28:22Z

1 votes

是的。 当创建继承类的实例时,将调用抽象类的构造函数。 例如,以下是有效的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();

}

}

这是上面代码的输出,

基础构造函数调用派生的构造函数被调用

引用:在此输入链接描述

chamzz.dot answered 2019-01-24T22:29:03Z

1 votes

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

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

Arun Raaj answered 2019-01-24T22:29:31Z

1 votes

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

Anilkumar K S answered 2019-01-24T22:29:53Z

1 votes

是的,抽象类可以有一个构造函数。 您可以在Abstract类中重载所需数量的构造函数。 这些承包商可用于初始化扩展抽象类的对象的初始状态。 我们知道我们不能创建一个抽象类的对象,因为对象是由“new”关键字创建的,而不是由构造函数创建的...它们仅用于初始化子类Objects的状态。

Shubham Soni answered 2019-01-24T22:30:16Z

0 votes

是的,你肯定可以添加一个,如前面提到的初始化Abstract类变量。但是,如果你没有明确声明一个,它无论如何都有一个隐含的构造函数“构造函数链接”工作。

Kedar Parikh answered 2019-01-24T22:30:38Z

0 votes

类中构造函数的用途是用于初始化字段,而不是用于“构建对象”。 当您尝试创建抽象SuperClass的新实例时,编译器将给您一个错误。 但是,我们可以继承一个抽象类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;

}

}

karto answered 2019-01-24T22:31:00Z

-5 votes

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

Sandeep answered 2019-01-24T22:31:22Z


版权声明:本文为weixin_39640417原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。