具有额外属性的子类构造函数

时间:2015-03-03 09:51:32

标签: java inheritance constructor attributes subclass

如果我有一个类'Dog'扩展另一个类'Animal'并且Animal类有一个带有几个属性的构造函数,比如latinName,latinFamily等。我应该如何为狗创建构造函数?我应该包括在Animal中找到的所有属性,以及我想要在Dog中使用的所有额外属性,如下所示:

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

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

实际的类具有比我在这里列出的更多的属性,因此狗的构造函数变得相当长,并且让我怀疑这是否是要走的路或者是否有更简洁的方法?

2 个答案:

答案 0 :(得分:2)

  

我是否应该包含在Animal中找到的所有属性...

那些对狗不是不变的,是的(不管怎样;见下文)。但是,例如,如果AnimallatinFamily,那么您不需要Dog来拥有它,因为它总是"Canidae"。 E.g:

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

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

如果您发现构造函数的参数数量不合适,您可以考虑构建器模式:

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”等等)但没有半身{{1}的危险实例(因为部分构造的实例是不好的做法); Dog存储信息,然后Dog.Builder完成构建build的工作。

答案 1 :(得分:0)

如果Dog扩展Animal然后是,你会想继续使用Animal的参数(因为狗确实是动物)并且可能添加更多来区分狗和动物对象。

因此,总的来说,您需要包含所有父类的参数。

还要考虑多个构造函数的可能性,这些构造函数可能包含较短的参数列表。 Say Animal接受一个参数String type来定义子类的动物类型,你不应该每次都为Dog传递它。

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

如果我对这一切都不明确请告诉我,我会尽可能地清理它。