繁体   English   中英

Java:抽象类构造函数和this()

[英]Java: Abstract class constructors and this()

有人可以指出我的误解吗?

我有两个类,一个抽象类,一个具体类,如下所示:

public abstract class Abstract
{
    protected static int ORDER = 1;

    public static void main (String[] args)
    {
        Concrete c = new Concrete("Hello");
    }

    public Abstract()
    {
        Class c = this.getClass();
        System.out.println(ORDER++ + ": Class = " 
            + c.getSimpleName() 
            + "; Abstract's no-arg constructor called.");
    }

    public Abstract(String arg)
    {
        this();
        Class c = this.getClass();
        System.out.println(ORDER++ + ": Class = " 
            + c.getSimpleName() 
            + "; Abstract's 1-arg constructor called.");
    }
}

public class Concrete extends Abstract
{
   public Concrete()
   {
      super();
      Class c = this.getClass();
      System.out.println(ORDER++ + ": Class = " 
          + c.getSimpleName() 
          + "; Concrete's no-arg constructor called.");
   }

   public Concrete(String arg)
   {
      super(arg);
      Class c = this.getClass();
      System.out.println(ORDER++ + ": Class = " 
          + c.getSimpleName() 
          + "; Concrete's 1-arg constructor called.");
   }
}

运行此命令时,将得到以下输出:

1)等级=混凝土; 抽象的no-arg构造函数称为。
2)等级=混凝土; 抽象的1-arg构造函数称为。
3)等级=混凝土; 具体的1-arg构造函数称为。

我的问题是这样的:为什么从Abstract的String arg构造函数中调用this()不会在Concrete上调用此no-arg构造函数? 或者,也许更有意义的是,是否有任何方法可以使Abstract的String arg构造函数在Concrete上调用no-arg构造函数,从而允许“适当”的构造方法链接?

否-构造函数链接总是向侧面(相同类型)或向上(至父类型)。

不要忘记呼叫在编译时得到解决-和Abstract不知道其它类会从中得到,或者他们将有什么构造函数。

可以Abstract构造函数中调用一个虚拟方法,并在Concrete重写该方法...但是我敦促您要这样做。 特别是,针对Concrete的构造函数主体尚未执行,变量初始化器也不会执行-因此,它将无法对Concrete特定的状态做任何事情。 在某些非常特殊的情况下,这是正确的做法,但这种情况很少见,应谨慎处理。

您实际上想做什么? 通常,我发现最好有许多“侧向”链导致一个具有“向上”链的构造函数。

您应该知道子类始终对父类隐藏。 您不能像在子类中那样直接调用子类的方法或构造函数。

这就是它的简单方式(如Jon Skeet所详述)。

您可以将init块添加到Concrete中:

{
  Class c = this.getClass();
  System.out.println(ORDER++ + ": Class = " 
  + c.getSimpleName() 
   + "; Concrete's init block called.");
}

与默认构造函数相比,inizializer块始终被调用:

1: Class = Concrete; Abstract's no-arg constructor called.
2: Class = Concrete; Abstract's 1-arg constructor called.
3: Class = Concrete; Concrete's init block called.
4: Class = Concrete; Concrete's 1-arg constructor called.

这里是其重点放在什么需要抽象类的,以及它如何works.May这将帮助你。

处理此问题的最佳方法通常是让一个类的所有构造函数最终都使用一个通用的构造函数,即:

public Abstract() {
  this(null);
}
public Abstract(String arg) {
  // do all Abstract init here
}

public Concrete() {
  this(null);
}
public Concrete(String arg) {
  super(arg);
  // do all Concrete init here
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM