如何在Java中覆盖父构造函数?

时间:2018-09-22 23:20:04

标签: java inheritance override super

我目前有一个类,我们称它为Person,它具有类似的构造函数。

public class Person
{
    private String name;

    public Person(String name)
    {
        this.name = name;
        System.out.println("This person is: "+getName());
    }

    public String getName()
    {
        return this.name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}

然后,我们使用更特定类型的Person(在这种情况下为Employee)继承该类。

public class Employee extends Person
{
    private int id;

    public Employee(String name, int id)
    {
        super(name);
        this.id = id;
        System.out.println("This person is: "+getName()+", identified by #"+getId());
    }

    public int getId()
    {
        return this.name;
    }

    public void setId(int id)
    {
        this.id = id;
    }
}

我想使它在创建对象时让Employee打印自己的语句,但是相反,它既打印Person的打印语句,也打印Employee的打印语句。如何覆盖此语句以防止发生这种情况?有没有更好的方法可以打印到控制台上以防止这种情况发生?

3 个答案:

答案 0 :(得分:5)

  

如何覆盖此语句以防止这种情况发生?

除非您可以编辑Person来提供不执行System.out.println调用的构造函数,否则您不能这样做。子类必须调用其超类构造函数之一。¹您的Person类只有一个,其中包括System.out.println调用,因此Employee别无选择,只能进行以下操作:叫它。

这是构造函数不应产生副作用的几个原因之一。 PersonEmployee都不应该呼叫System.out.println。应该留给使用类或方法(而不是构造函数)的代码。


¹如果您未明确进行操作,则编译器将在构造函数的开头插入super()。在您的情况下,这将是编译错误,因为Person没有零参数构造函数。

答案 1 :(得分:1)

调用super时,将调用父级的构造函数。无法避免:super就是这个目的。

如果要在对象创建时一次调用不同的println,则必须将println放在构造函数之外。一个好的选择是使用构建器或工厂模式,在toStringPerson类中覆盖Employee,然后从构建器或工厂调用toString

答案 2 :(得分:0)

由于定义了自己的Person构造函数,因此该类没有可用的no-arg构造函数供您使用。但是,如果将其添加回去,则可以使子类具有自己的行为

 public class Person {
    protected String name;

    public Person() {} 

    public Person(String name) {
        this.name = name;
        System.out.println("This person is: "+getName());
    }

然后无需自己添加超级调用

public class Employee extends Person {
    private int id;

    public Employee(String name, int id) {
        this.name = name;
        this.id = id;
        System.out.println("This person is: "+getName()+", identified by #"+getId());
    }