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

Posted

技术标签:

【中文标题】具有额外属性的子类构造函数【英文标题】:Subclass constructor with extra attributes 【发布时间】:2015-03-03 09:51:32 【问题描述】:

如果我有一个扩展另一个类“Animal”的类“Dog”,并且 Animal 类有一个具有多个属性的构造函数,例如 latinName、latinFamily 等。我应该如何为狗创建构造函数?我是否应该包括在 Animal 中找到的所有属性,以及我想要在 Dog 中的所有额外属性,如下所示:

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


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

实际的类比我在这里列出的属性要多得多,因此狗的构造函数变得相当长,让我怀疑这是要走的路还是有更好的方法?

【问题讨论】:

是的,这是继续的方式。您可以根据需要将参数封装在映射或包装类中以提高可读性。 你是对的,包括在 Animal 中找到的所有属性,以及在 Dog 类中你想要的所有额外属性。只需使用参数中的数据类型更正您的代码。喜欢public Dog(String latinName, DataTypeOfBreed breed) 【参考方案1】:

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

那些对于狗来说不是一成不变的,是的(一种或另一种方式;见下文)。但是例如,如果AnimallatinFamily,那么你不需要Dog 来拥有它,因为它总是"Canidae"。例如:

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

【讨论】:

有趣的构建器模式作为长参数列表的替代方案。【参考方案2】:

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

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

还要考虑多个构造函数的可能性,这些构造函数的参数列表可能更短。假设 Animal 接受一个参数 String type,它定义了子类是什么类型的动物,你不应该每次都为 Dog 传递它。

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

如果我对这一切有歧义,请告诉我,我会尽量澄清。

【讨论】:

以上是关于具有额外属性的子类构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C#中子类构造函数中如何调用父类构造函数

继承:继承后子类构造函数具有隐式super

子类可以继承父类的啥

子类可以继承父类的啥

父类,子类,静态属性,静态代码块,构造代码块,构造函数,执行顺序

具有包含另一个类的对象的数组的子类的构造函数