Конструктор подкласса с дополнительными атрибутами

Если у меня есть класс «Собака», который расширяет другой класс «Животное», а класс «Животное» имеет конструктор с несколькими атрибутами, такими как latinName, latinFamily и т. д. Как мне создать конструктор для собаки? Должен ли я включать все атрибуты, которые есть в Animal, и все дополнительные атрибуты, которые мне нужны в Dog, вот так:

public Animal(String latinName){
    this.latinName = latinName;
}

public Dog(String latinName, breed){
    super(latinName);
    this.breed = breed;
}

Фактические классы имеют гораздо больше атрибутов, чем я перечислил здесь, поэтому конструктор для собаки становится довольно длинным, и я сомневался, был ли это правильный путь или есть более аккуратный способ?


person User892313    schedule 03.03.2015    source источник
comment
Да, это способ продолжить. Вы можете инкапсулировать параметры в карту или в класс-оболочку для удобочитаемости, если хотите.   -  person Paco Abato    schedule 03.03.2015
comment
Вы правы, включите все атрибуты, которые есть в классе Animal, и все дополнительные атрибуты, которые вам нужны в классе Dog. Просто исправьте свой код с типом данных в параметрах. нравится public Dog(String latinName, DataTypeOfBreed breed)   -  person Ravi Chhatrala    schedule 03.03.2015


Ответы (2)


Должен ли я включать все атрибуты, которые находятся в Animal...

Те, что не инвариантны для собак, да (так или иначе; см. ниже). Но, например, если у Animal есть latinFamily, то для этого вам не нужно Dog, так как это всегда будет "Canidae". Например.:

public Animal(String latinFamily){
    this.latinFamily = latinFamily;
}

public Dog(String breed){
    super("Canidae");
    this.breed = breed;
}

Если вы считаете количество аргументов конструктора громоздким, вы можете рассмотреть шаблон Builder:

public class Dog {

    public Dog(String a, String b, String c) {
        super("Canidae");
        // ...
    }

    public static class Builder {
        private String a;
        private String b;
        private String c;

        public Builder() {
            this.a = null;
            this.b = null;
            this.c = null;
        }

        public Builder withA(String a) {
            this.a = a;
            return this;
        }

        public Builder withB(String b) {
            this.b = b;
            return this;
        }

        public Builder withC(String c) {
            this.c = c;
            return this;
        }

        public Dog build() {
            if (this.a == null || this.b == null || this.c == null) {
                throw new InvalidStateException();
            }

            return new Dog(this.a, this.b, this.c);
        }
    }
}

Применение:

Dog dog = Dog.Builder()
            .withA("value for a")
            .withB("value for b")
            .withC("value for c")
            .build();

Это упрощает понимание того, какой аргумент есть какой, в отличие от длинной строки аргументов конструктора. Вы получаете преимущества ясности (вы знаете, что withA указывает информацию «a», withB указывает «b» и т. д.), но без опасности иметь наполовину созданный экземпляр Dog (поскольку частично построенные экземпляры — плохая практика). ; Dog.Builder сохраняет информацию, а затем build выполняет работу по созданию Dog.

person T.J. Crowder    schedule 03.03.2015
comment
Интересный шаблон построения как альтернатива длинным спискам аргументов. - person Juxhin; 03.03.2015

Если Dog расширяет Animal, то да, вам следует продолжить использование аргументов Animal (поскольку собака действительно является животным) и возможно добавить больше, чтобы различать объекты dog и animal.

Итак, в общем, да, вам нужно будет включить все аргументы родительских классов.

Также рассмотрите возможность использования нескольких конструкторов с, возможно, более коротким списком аргументов. Say Animal принимает аргумент String type, который определяет, к какому типу животных относится дочерний класс, вам не нужно передавать его каждый раз для Dog.

public Dog (String name){
   super("Dog", name);
}

Если я двусмыслен со всем этим, пожалуйста, скажите, я постараюсь прояснить это, насколько смогу.

person Juxhin    schedule 03.03.2015