可以一个抽象的类有一个构造?
-
06-07-2019 - |
题
可以一个抽象的类有一个构造?
如果是这样,它可以如何使用和为什么目的?
解决方案
是的,抽象类可以有一个构造函数。考虑一下:
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
有一个构造函数,允许调用者指定值。
抽象构造函数将经常用于强制类约束或不变量,例如设置类所需的最小字段。
注意:由于父级中没有默认(或无参数)构造函数 抽象类,子类中使用的构造函数必须显式调用 父构造函数。
其他提示
你将定义一个构造在一个抽象的类如果你们在一些情况:
- 你想要执行一些 初始化(等领域的 抽象的类)之前 实例的一类实际上 需要的地方
- 你有定义最后一领域在 抽象的类,但你没有 初始化他们在《宣言》 本身;在这种情况下,您必须 一个构造,初始化这些 田
注意:
- 你可以限定多于一个 构造(不同 参数)
- 你可以(?) 定义所有你的 构造的保护(使得他们 公众是毫无意义无论如何)
- 你的子类的构造(s)可以 电话一个构造的抽象 类;它甚至可能 有来 叫它 (如果没有,没有-arg构造 在抽象的类)
在任何情况下,不要忘了,如果你没有定义的构造,然后编译器将会自动生成一个给你(这是一个公共的、没有争论,并且没有什么).
是的,它可以有一个构造函数,它的定义和行为就像任何其他类的构造函数一样。除了抽象类不能直接实例化,只能扩展,因此使用总是来自子类的构造函数。
是! 抽象类可以有构造函数!
是的,当我们将一个类定义为一个抽象类时,它无法实例化,但这并不意味着一个Abstract类不能有一个构造函数。每个抽象类都必须有一个具体的子类,它将实现该抽象类的抽象方法。
当我们创建任何子类的对象时,相应的继承树中的所有构造函数都是从上到下的方法调用的。同样的情况适用于抽象类。虽然我们不能创建抽象类的对象,但是当我们创建一个类的对象时,它是抽象类的具体和子类,抽象类的构造函数会被自动调用。因此,我们可以在抽象类中使用构造函数。
注意:非抽象类不能有抽象方法,但抽象类可以有非抽象方法。 Reason与构造函数类似,不同之处在于我们可以调用super()而不是自动调用。此外,没有什么比抽象构造函数更像是没有任何意义了。
它不仅可以,它始终如此。如果你没有指定一个,那么它就有一个默认的没有arg构造函数,就像任何其他类一样。实际上,ALL类(包括嵌套类和匿名类)将获得默认构造函数(如果未指定一个)(在匿名类的情况下,不可能指定一个,因此您将始终获得默认构造函数。)
具有构造函数的抽象类的一个很好的例子是日历课程。通过调用Calendar.getInstance()获得Calendar对象,但它也有受保护的构造函数。它的构造函数受到保护的原因是只有它的子类可以调用它们(或者同一个包中的类,但因为它是抽象的,所以不适用)。 GregorianCalendar 是一个扩展Calendar的类的示例。
是的,抽象类构造函数通常用于超级调用所有子类共有的初始化事件
抽象类可以有一个构造函数但是你不能创建一个抽象类的对象,那么你如何使用该构造函数呢?
事实是,当您在子类中继承该抽象类时,您可以通过子类中的super(value)方法将值传递给它的(abstract)构造函数,并且不会继承构造函数。
所以使用super你可以在抽象类的构造函数中传递值,据我所知它必须是你的方法或构造函数中的第一个语句。
虽然有很多好的答案,但我想给我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");
}
}
当然,抽象类可以有一个构造函数。通常,类构造函数用于初始化字段。因此,抽象类构造函数用于初始化抽象类的字段。如果要在子类的实例化之前初始化抽象类的某些字段,则可以为抽象类提供构造函数。抽象类构造函数也可用于执行与每个子类相关的代码。这可以防止代码重复。
我们不能创建抽象类的实例,但是我们可以创建从抽象类派生的类的实例。因此,当创建派生类的实例时,将自动调用父抽象类构造函数。
参考:这文章
考虑一下:
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;
}
}
超类是抽象的,并且有一个构造函数。
在一个具体的类宣言》的一个构造为一个具体的类型弗洛德有效地暴露了两件事:
一个手段,通过它的代码可以请求创建的一个实例弗洛德
一个手段,通过它的一个实例 的类型来自弗洛德 这是在建设可以要求所有基类要素进行初始化。
虽然或许应的一种手段这两种能力能够单独控制,对于每一具体类型的一个定义将使这两者。虽然第一能力是没有意义的,对于一个抽象的类,第二能力只是作为有意义的一个抽象的类,因为它将对任何其他的,因此其声明是必要和有用的。
// 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();
}
}
这是上述代码的输出,
调用基础构造函数 派生的构造函数被称为
的引用: 在此输入链接说明
如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());
}
}
所以我认为你得到了答案。
Abstract类虽然无法实例化,但可以有一个构造函数。但是,抽象类中定义的构造函数可用于实例化此抽象类的具体类。检查 JLS :
如果尝试使用类实例创建创建抽象类的实例,那么这是一个编译时错误 表达强>
抽象类的子类本身不是抽象的 实例化,导致执行构造函数 抽象类,因此,字段初始化程序的执行 例如该类的变量。
由于抽象类可以包含所有访问修饰符的变量,因此必须将它们初始化为默认值,因此构造函数是必需的。 在实例化子类时,将调用抽象类的构造函数并初始化变量。
相反,接口确实只包含常量变量意味着它们已经初始化。所以接口不需要构造函数。
为了实现构造函数链接,抽象类将具有构造函数。 编译器将Super()语句保留在子类构造函数中,该构造函数将调用超类构造函数。如果没有抽象类的构造函数,则违反了java规则,我们无法实现构造函数链接。
是的,抽象类可以有一个构造函数。您可以在Abstract类中重载所需数量的构造函数。这些承包商可用于初始化扩展抽象类的对象的初始状态。我们知道我们不能创建一个抽象类的对象,因为对象是由“new”创建的。关键字而不是构造函数......它们仅用于初始化子类Objects的状态。
是的,您肯定可以添加一个,如前面提到的Abstract类变量的初始化。 但是如果你没有明确地声明一个,它无论如何都有一个隐含的构造函数用于“构造函数链接”。上班。
类中构造函数的用途是用于初始化字段,但不用于“构建对象”。当您尝试创建抽象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;
}
}
是的......就像其他任何一个班级一样。它可以有一个构造函数,并在为基类创建对象后调用它。