首页 文章

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

提问于
浏览
515

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

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

21 回答

  • 2

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

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

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

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

  • 1

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

  • 13

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

    这是上面代码的输出,

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

    参考:enter link description here

  • 140

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

  • 1

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

  • 5

    如javafuns here所述,这是一个例子:

    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
       }
    }
    
  • 32

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

    • 你想在实际发生子类的实例化之前执行一些初始化(到抽象类的字段)

    • 您已经在抽象类中定义了最终字段,但是您没有在声明本身中初始化它们;在这种情况下,你必须有一个构造函数来初始化这些字段

    注意:

    • 你可以定义多个构造函数(使用不同的参数)

    • 你可以(应该?)定义所有受保护的构造函数(无论如何都将它们公开是没有意义的)

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

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

  • 5

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

  • 4

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

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

    • 一种方法,通过该方法,正在构造的Fnord派生的类型的实例可以请求初始化所有基类功能 .

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

  • 1

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

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

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

  • 1

    虽然有很多好的答案,但我想给我2美分 .

    构造函数 DOES NOT BUILD THE OBJECT . 它用于初始化对象 .

    是的,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");
    }
    }
    
  • 1

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

  • -5

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

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

  • 2

    类中构造函数的用途用于 initialize fields 但不用于"build objects" . 当您尝试创建抽象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;
     }
    }
    
  • 1

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

  • 0

    YesAbstract classes can have constructors

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

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

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

  • 1

    Yes, Abstract Classes can have constructors !

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

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

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

  • 3

    考虑一下:

    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;
        }
    }
    

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

  • 0

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

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

  • 52

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

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

    参考:This Article

  • 548

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

    如果尝试使用类实例创建表达式创建抽象类的实例,则这是编译时错误 . 可以实例化抽象类的子类,该子类本身不是抽象的,从而导致抽象类的构造函数的执行,并因此执行该实例变量的字段初始化器 . 类 .

相关问题