Конструктор на подклас с допълнителни атрибути

Ако имам клас „Куче“, който разширява друг клас „Животно“ и класът Животно има конструктор с няколко атрибута като 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 class. Просто коригирайте кода си с тип данни в параметрите. като 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 (защото кучето наистина е животно) и евентуално да добавите още, за да разграничите кучешки и животински обекти.

Така че като цяло, да, ще трябва да включите всички аргументи на родителските класове.

Също така разгледайте възможността за множество конструктори с възможно по-кратък списък от аргументи. Кажете, че Animal приема аргумент String type, който определя какъв тип животно е дъщерният клас, не трябва да го предавате всеки път за Dog.

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

Ако съм двусмислен с всичко това, моля, кажете, ще се опитам да го изясня, доколкото мога.

person Juxhin    schedule 03.03.2015