Java 抽象类中的构造函数?

Java 抽象类中的构造函数?,java,Java,为什么抽象类可以有构造函数? 既然我们不能创建它的对象,为什么我们需要抽象类中的构造函数?在某些情况下,我们需要初始化抽象类中的字段。如果它是空构造函数,则由子类中的构造函数隐式完成,否则我们使用super(parameters)。带有参数的构造函数强制子类指定一些参数(不一定来自它自己的参数) 总而言之,这意味着构造函数由子类构造函数使用,而不是从“外部”使用。子类可以实例化,并且可以从其构造函数调用抽象类的构造函数。例如: abstract class Foo { public Foo(

为什么抽象类可以有构造函数?
既然我们不能创建它的对象,为什么我们需要抽象类中的构造函数?

在某些情况下,我们需要初始化抽象类中的字段。如果它是空构造函数,则由子类中的构造函数隐式完成,否则我们使用
super(parameters)
。带有参数的构造函数强制子类指定一些参数(不一定来自它自己的参数)


总而言之,这意味着构造函数由子类构造函数使用,而不是从“外部”使用。

子类可以实例化,并且可以从其构造函数调用抽象类的构造函数。例如:

abstract class Foo
{
  public Foo()
  {
    // Do Stuff
  }
}

class Bar extends Foo
{
  public Bar()
  {
    super();
  }
}

abstract class Person {
   private String name;
   public Person(String name) {
      this.name = name;
   }
}

class SoccerPlayer extends Person {
   public SoccerPlayer(String name) {
     super(name);
   }
}
Person p = new SoccerPlayer("Ronaldo");

您仍然需要能够创建一个子类,该子类必须调用其父类的构造函数及其父类等


真正的问题是,为什么可以公开抽象类构造函数

想象一个抽象类,比如派生类的蓝图,最多有1或2个方法必须在派生类中实现。
在抽象类(包括构造函数)中实现尽可能多的抽象类是有意义的。

因为继承abstract类的类可以调用此构造函数

abstract class Foo {

    private int number;

    public Foo(int i) {
        this.number = i;
    }
}

class Bar extends Foo {

    public Bar() {
        super(1);
    }

}

抽象构造函数强制从类继承的类实现(或调用)构造函数。这意味着您可以确保抽象类的构造函数中的任何操作都将被执行。

通过向抽象类添加构造函数,您可以强制子类调用super以初始化某些字段。例如:

abstract class Foo
{
  public Foo()
  {
    // Do Stuff
  }
}

class Bar extends Foo
{
  public Bar()
  {
    super();
  }
}

abstract class Person {
   private String name;
   public Person(String name) {
      this.name = name;
   }
}

class SoccerPlayer extends Person {
   public SoccerPlayer(String name) {
     super(name);
   }
}
Person p = new SoccerPlayer("Ronaldo");

抽象类表示更顶层的对象,在某些情况下,这些顶层对象需要在业务透视图创建对象时设置值。缺少设置此值可能会导致业务对象失败。抽象类中支持构造函数在构建类时强制设置值(否则可能会忘记)。比如说,

public abstract class AccountHolder 
{
}

    public abstract class Account
    {
         private AccountHolder holder;

    public Account(AccountHolder holder)
    {
    this.holder = holder;
    }
    }

    public class FixedDeposit extends Account
    {
    public FixedDeposit (AccountHolder holder)
    {
    super(holder)
    }
    }

在这里,我们无法想象没有持有人的帐户,因此在创建对象时设置持有人对业务至关重要。在基础级别设置它可以确保在添加新类型的子类时强制设置它。因此,它是确保“为扩展而打开,为修改而关闭”的可靠原则之一。

基类中的构造函数可用于进行构造函数链接,因此您可以初始化基类字段。在这个构造函数中,您可以放置一些业务逻辑来验证参数

承包商链接示例:

public abstract class Person
{
    protected readonly string Name;

    protected Person(string name)
    {
        //Do some validations or regex on the name for example so you know all person names match your business rules
        Name = name;
    }
}

public class Employee : Person
{
    private decimal _salary;

    public Employee(string name, decimal salary)
        : base(name)
    {
         _salary = salary;
    }
}

@忽必烈·汗:对不起,您不能在堆栈溢出时问这样的问题,因为您的“问题似乎是主观的,可能会被关闭?”;)+1为明确example@marcosbeirigo
强制子类调用super
——是否还需要添加一个私有的无参数构造函数来实现强制子类使用参数调用抽象超类构造函数的目标?