【问题标题】:What is the use of creating a constructor for an abstract class in Java?在 Java 中为抽象类创建构造函数有什么用?
【发布时间】:2010-01-20 23:14:07
【问题描述】:

我想知道抽象类的构造函数有什么用途;由于我们不实例化抽象类,为什么我们需要这样的构造函数?

【问题讨论】:

    标签: java constructor abstract-class


    【解决方案1】:

    有时,您需要对所有继承类都需要设置的实例变量进行一些通用初始化。扩展抽象类时确实会实例化一个抽象类,并且该具体类具有一个构造函数,该构造函数将向抽象类的构造函数提供参数。

    【讨论】:

    • 一个例子是 javax.swing.AbstractAction
    【解决方案2】:

    它们仍然可以被从该类继承的类的构造函数调用,从而使代码重构成为在抽象类中具有构造函数的一个很好的用途。

    【讨论】:

      【解决方案3】:

      如果您在抽象类中有未初始化的最终字段,则需要在构造函数中对其进行初始化。

      例如

      abstract class A {
          final int x;
      }
      

      如果没有分配给x 的构造函数,将无法编译。

      【讨论】:

        【解决方案4】:

        如果你的类没有声明构造函数,javac 会为你创建一个无参数、什么都不做的构造函数。然后,当您的子类被初始化时,它将调用生成的无操作构造函数,并且生活很好。

        但是,如果你的类声明了任何构造函数,javac 不会为你创建一个。在这种情况下,子类构造函数需要显式调用父类的构造函数。否则,您将无法初始化父类的成员,如上述答案所述。

        【讨论】:

          【解决方案5】:

          子类使用抽象类的构造函数(使用 super(params) 从子类构造函数调用)。

          您应该将这些构造函数设为protected 以明确这一点。

          【讨论】:

            【解决方案6】:

            您不实例化抽象类,但在实例化子类时会调用构造函数。

            用途可能是初始化公共属性,即。

            import java.util.List;
            import java.util.ArrayList;
            abstract class BaseClass {
                protected List list; // visible from subclasses
            
                public BaseClass() {
                    System.out.println("to abstract...");
                    // common initialization to all subclasses
                    list = new ArrayList();
                    list.add("a");
                    list.add("a");
                    list.add("a");
                }
            }
            
            class ConcreteClass extends BaseClass {
                public ConcreteClass(){
                    // The list is initialized already
                    System.out.println("now it is concrete and the list is: = "+ this.list );
            
            
                }
            }
            
            class TestAbstractClass {
                public static void main( String [] args ) {
                    BaseClass instance = new ConcreteClass();
                }
            
            }
            

            输出

            $ java TestAbstractClass
            to abstract...
            now it is concrete and the list is: = [a, a, a]
            

            【讨论】:

              【解决方案7】:

              重复删除常见知识/行为。

              例如一辆汽车:你所有的汽车都将由一个车身、四个轮子和一个发动机构成。因此,您可以通过调用 Body()、Wheel(int x)、Engine() 等函数在抽象 Car 类的构造函数中完成这部分构造。每个特定的汽车类都有自己的 Body()、Wheel() 和 Engine() 实现——但它们都将执行相同的步骤来构造汽车,因此无需在每个步骤中重复这些步骤类。在这种情况下,您在祖先中实现该常见行为。

              【讨论】:

                【解决方案8】:

                我同意,构造函数是在假设存在实例的情况下创建的。如果您有很多通用代码,您可以考虑创建一个构造函数,但最好将其放入 init() 方法中。

                【讨论】:

                • 这是一个糟糕的建议,然后每个继承类都需要记住调用 super.init() 并且它很快就会变得一团糟,这是非标准且非常糟糕的建议。
                猜你喜欢
                • 1970-01-01
                • 2014-04-23
                • 2018-09-10
                • 2012-12-25
                • 2017-06-04
                • 2011-03-11
                • 2013-11-25
                相关资源
                最近更新 更多