抽象类可以有一个构造函数吗?
抽象类可以有一个构造函数吗?
如果是这样的话,怎么可以用来做什么用途呢?
是的,一个抽象类可以有一个构造函数。 考虑这个:
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
有一个构造函数,允许调用者指定值。
抽象构造函数经常被用来强制类的约束或不variables,比如设置类所需的最小字段。
注:由于父抽象类中没有默认(或无参数)构造函数,因此子类中使用的构造函数必须显式调用父构造函数。
如果您处于以下情况之一,则可以在抽象类中定义构造函数:
- 您希望在实际发生子类的实例化之前执行一些初始化(对抽象类的字段)
- 您已经在抽象类中定义了最终字段,但是您没有在声明中初始化它们; 在这种情况下,你必须有一个构造函数来初始化这些字段
注意:
- 你可以定义多个构造函数(使用不同的参数)
- 你可以(应该)定义所有的构造函数protected(公开是毫无意义的)
- 你的子类的构造函数可以调用抽象类的构造函数; 甚至可能需要调用它(如果抽象类中没有无参数构造函数)
无论如何,不要忘记,如果你没有定义一个构造函数,那么编译器会自动为你生成一个(这个是公共的,没有参数,什么都不做)。
是的,它可以有一个构造函数,它的定义和行为就像任何其他类的构造函数一样。 除了抽象类不能直接实例化,只能扩展,所以使用总是来自子类的构造函数。
是的 ! 抽象类可以有构造函数 !
是的,当我们定义一个类是一个抽象类,它不能实例化,但这并不意味着一个抽象类不能有一个构造函数。 每个抽象类必须有一个具体的子类,它将实现抽象类的抽象方法。
当我们创build任何子类的对象时,所有在相应的inheritance树中的构造函数都是从上到下的方法调用的。 同样的情况适用于抽象类。 虽然我们不能创build抽象类的对象,但是当我们创build抽象类的具体和子类的类的对象时,抽象类的构造函数会被自动调用。因此,我们可以在抽象类中有一个构造函数。
注意:非抽象类不能有抽象方法,但抽象类可以有非抽象方法。 原因与构造函数类似,区别在于自动调用我们可以调用super()。 也没有什么像抽象的构造函数,因为它根本没有意义。
它不仅可以,它总是这样做。 如果你没有指定一个,那么它有一个默认的无参数构造函数,就像任何其他类一样。 事实上,如果没有指定所有的类(包括嵌套类和匿名类),将会得到一个默认的构造函数(在匿名类的情况下,不可能指定一个,所以你总是会得到默认的构造函数)。
具有构造函数的抽象类的一个很好的例子就是Calendar类。 您通过调用Calendar.getInstance()来获取Calendar对象,但它也具有受保护的构造函数。 构造函数被保护的原因是只有它的子类可以调用它们(或者在同一个包中的类,但是因为它是抽象的,所以不适用)。 GregorianCalendar是延伸Calendar的类的一个例子。
是的,抽象类构造函数通常用于超级调用所有子类通用的初始化事件
一个抽象类可以有一个构造函数,但是你不能创build一个抽象类的对象,所以你如何使用这个构造函数呢?
事情是,当你在你的子类中inheritance这个抽象类时,你可以通过你的子类中的super(value)方法将值传递给它的(抽象的)构造函数,而不是你不inheritance构造函数。
所以使用超级,你可以在抽象类的构造函数中传递值,并且据我所知,它必须是你的方法或构造函数中的第一个语句。
考虑这个:
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; } }
超类是抽象的,并有一个构造函数。
在具体类中,具体typesFnord的构造函数的声明有效地暴露了两件事情:
-
代码可以请求创build一个Fnord实例的方法
-
从正在构build的Fnord中派生的types的实例可以请求初始化所有基类function的方法。
虽然也许应该有一种方法可以分别控制这两种能力,但对于每一种具体的types,一个定义将使这两种能力成为可能。 虽然第一种能力对于抽象类没有意义,但第二种能力对于抽象类来说也是有意义的,因此它的声明同样必要且有用。
当然,抽象类可以有一个构造函数。一般的类构造函数都是用来初始化字段的,所以抽象类的构造函数用来初始化抽象类的字段。 如果要在发生子类的实例化之前初始化抽象类的某些字段,则可以为抽象类提供构造函数。 抽象类构造函数也可以用来执行与每个子类相关的代码。 这可以防止代码重复。
我们不能创build抽象类的实例,但是我们可以创build从抽象类派生的类的实例。 所以,当派生类的实例被创build时,父类抽象类的构造函数被自动调用。
参考: 这篇文章
正如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 } }
是的,抽象类可以有构造函数!
这是一个在抽象类中使用构造函数的例子:
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()); } }
所以我想你已经得到了答案。
抽象类可以有一个构造函数,尽pipe它不能被实例化。 但是在抽象类中定义的构造函数可以用于这个抽象类的具体类的实例化。 检查JLS :
如果尝试使用类实例创buildexpression式创build抽象类的实例,则会出现编译时错误 。
抽象类的一个非抽象类的子类可能被实例化,导致抽象类的构造函数的执行,并因此执行该类的实例variables的字段初始值设定项。
为了实现构造器链接,抽象类将有构造器。 编译器将Super()语句保存在子类constructer中,它将调用超类的构造函数。如果抽象类没有构造函数,那么违反了java规则,我们不能实现构造函数链。
是的,你可以添加一个,正如已经提到的初始化Abstract类variables。 但是,如果你不显式声明一个,它反正有一个“构造函数链”隐式构造函数工作。
是的抽象类可以有一个构造函数。您可以在抽象类中重载任意多的构造函数。这些构造函数可以用来初始化扩展抽象类的对象的初始状态。 正如我们所知,我们不能创build一个抽象类的对象,因为对象是由“新”关键字创build的,而不是由构造函数创build的…他们只是初始化子类对象的状态。
虽然有很多好的答案,但是我想给我2分钱。
构造函数不构build对象 。 它用于初始化对象。
是的,一个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"); } }
是的。 并且在创build一个inheritance类的实例时调用抽象类的构造函数。 例如,以下是有效的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(); } }
这是上面代码的输出,
基础构造函数调用派生构造函数调用
参考: 在这里input链接描述
是的,就像其他class级一样。 它可以有一个构造函数,并且在为基类创build对象之后被调用。