Как вы переопределяете родительский конструктор в Java? - PullRequest
0 голосов
/ 23 сентября 2018

В настоящее время у меня есть класс, назовем его 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 голосов
/ 23 сентября 2018

Когда вы вызываете super, будет вызван конструктор родителя.Этого нельзя избежать: вот для чего super.

Если вы хотите вызывать разные println с один раз во время создания объекта, вам придется поставить println внеконструктор.Хорошим вариантом будет использование шаблона компоновщика или фабрики, переопределение toString в классах Person и Employee и вызов toString из компоновщика или фабрики.

0 голосов
/ 23 сентября 2018

Поскольку вы определили свой собственный конструктор 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());
    }
0 голосов
/ 23 сентября 2018

Как мне переопределить это утверждение, чтобы этого не происходило?

Вы не можете, если вы не можете отредактировать Person, чтобы предоставить конструктор, который не выполняет System.out.println звонок.Подкласс должен вызвать один из своих конструкторов суперкласса. ¹ Ваш класс Person имеет только один класс, который включает в себя вызов System.out.println, поэтому у Employee нет другого выбора, кроме как вызвать его.

Это одна из нескольких причин, по которой у конструкторов не должно быть побочных эффектов.Ни Person, ни Employee не должны звонить System.out.println.Это следует оставить в коде, используя класс или метод (а не конструктор).


¹ Если вы не сделаете это явно, компилятор вставит super() в начале вашегоконструктор.В вашем случае это будет ошибка компиляции, потому что Person не имеет конструктора с нулевыми параметрами.

...