代码之家  ›  专栏  ›  技术社区  ›  Szere Dyeri

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

  •  528
  • Szere Dyeri  · 技术社区  · 17 年前

    如果是的话,它可以如何使用,用于什么目的?

    21 回复  |  直到 9 年前
        1
  •  704
  •   rimsky    9 年前

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

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

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

        2
  •  171
  •   jfpoilpret    17 年前

    • 你想表演一些吗 初始化(到 子类的实例化 发生
    • 您已在中定义了最终字段 抽象类,但您没有 它本身在这种情况下,您必须 一个构造函数来初始化这些 领域

    请注意:

    • 构造函数(具有不同的 (论据)
    • 受保护的构造函数(使其 (无论如何,公开是没有意义的)
    • 您的子类构造函数可以 班甚至可能 不得不 (如果没有参数构造函数 (在抽象类中)

    在任何情况下,不要忘记,如果您没有定义构造函数,那么编译器将自动为您生成一个构造函数(这个构造函数是公共的,没有参数,并且不执行任何操作)。

        3
  •  73
  •   L. Cornelius Dol    17 年前

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

        4
  •  58
  •   Yoon5oo JBE    8 年前

    对 抽象类可以有构造函数

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

        5
  •  15
  •   MattC Holger    10 年前

    不仅如此,它总是这样。如果您没有指定一个,那么它有一个默认的无参数构造函数,就像其他任何类一样。事实上,所有类,包括嵌套类和匿名类,如果未指定一个构造函数,都将获得默认构造函数(对于匿名类,不可能指定一个,因此您将始终获得默认构造函数)。

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

        6
  •  7
  •   Yoon5oo JBE    8 年前

    抽象类可以有构造函数,但不能创建抽象类的对象,所以如何使用该构造函数?

    问题是,当您在子类中继承那个抽象类时,您可以通过子类中的super(value)方法将值传递给它的(abstract)构造函数,而不是继承构造函数。

        7
  •  6
  •   Jacob    13 年前

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

        8
  •  5
  •   Yoon5oo JBE    8 年前

    不生成对象

    是的,抽象类总是有一个构造函数。如果您没有定义自己的构造函数,编译器将为抽象类提供一个默认构造函数。 以上内容适用于所有类-嵌套类、抽象类、匿名类等。

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

    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");
    }
    }
    
        9
  •  4
  •   ROMANIA_engineer Alexey    11 年前

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

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

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

        10
  •  4
  •   Raj Baral Gaurav Panwar    8 年前

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

    This Article

        11
  •  2
  •   S.Lott    17 年前

    考虑一下:

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

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

        12
  •  2
  •   Brad Larson    13 年前

    正如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
       }
    }
    
        13
  •  2
  •   supercat    12 年前

    在具体类中,为具体类型Fnord声明构造函数实际上公开了两件事:

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

    • 一种方法,通过这种方法,一个实例 属于从Fnord派生的类型

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

        14
  •  2
  •   chamzz.dot    9 年前

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

        15
  •  1
  •   Kedar Parikh    11 年前

    是的,您当然可以添加一个,正如前面提到的抽象类变量的初始化一样。

        16
  •  1
  •   akhil_mittal    11 年前

    抽象类可以有构造函数,但不能实例化。但是抽象类中定义的构造函数可以用于实例化该抽象类的具体类。检查 JLS :

    如果试图使用类实例创建来创建抽象类的实例,则是编译时错误 表示 .

    抽象类的子类本身不是抽象的,可能是 实例化,从而执行

        17
  •  1
  •   Yoon5oo JBE    8 年前

    自从 抽象类 可以有所有访问修饰符的变量,它们必须初始化为默认值,所以构造函数是必需的。

    相反,一个 界面 只包含常量变量表示它们已初始化。所以接口不需要构造函数。

        18
  •  1
  •   Yoon5oo JBE    8 年前

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

        19
  •  1
  •   Yoon5oo JBE    8 年前

    是的,抽象类可以有构造函数。您可以在抽象类中重载任意数量的构造函数。这些contractor可用于初始化扩展抽象类的对象的初始状态。正如我们所知,我们不能创建抽象类的对象,因为对象是由“new”关键字创建的,而不是由构造函数创建的……它们只用于初始化子类对象的状态。

        20
  •  0
  •   karto    8 年前

    初始化字段

    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;
     }
    }
    
        21
  •  0
  •   sachit    7 年前

    包测试1;

    public AbstractClassConstructor() {
    
    }
    
        public static void main(String args[]) {
           Demo obj = new Test("Test of code has started");
           obj.test1();
        }
    

    }

    abstract class Demo{
        protected final String demoValue;
    
        public Demo(String testName){
            this.demoValue = testName;
        }
    
        public abstract boolean test1();
    }
    
    class Test extends Demo{
    
        public Test(String name){
            super(name);
        }
    
        @Override
        public boolean test1() {
           System.out.println( this.demoValue + " Demo test started");
           return true;
        }
    
    }
    
        22
  •  -5
  •   Sandeep    12 年前

    是的,它和其他的课一样。它可以有一个构造函数,在为基类创建对象后调用它。