具有额外属性的子类构造函数
Subclass constructor with extra attributes
如果我有一个 class 'Dog' 扩展另一个 class 'Animal' 并且 Animal class 有一个构造函数,它有几个属性,比如 latinName, latinFamily等等 我应该如何为狗创建构造函数?我是否应该包括在 Animal 中找到的所有属性,以及我想要在 Dog 中找到的所有额外属性,如下所示:
public Animal(String latinName){
this.latinName = latinName;
}
public Dog(String latinName, breed){
super(latinName);
this.breed = breed;
}
实际 classes 的属性比我在这里列出的要多得多,因此狗的构造函数变得相当长,让我怀疑这是要走的路还是有更简洁的方法?
如果 Dog extends Animal 那么是的,你会想继续使用 Animal 的参数(因为狗确实是一种动物)并且 可能 添加更多以区分狗和动物 objects。
所以一般来说,是的,您需要包括所有 parent classes 的参数。
还要考虑多个构造函数的参数列表可能更短的可能性。假设 Animal 有一个参数 String type
,它定义了 child class 是什么类型的动物,你不需要每次都为 Dog
传递它。
public Dog (String name){
super("Dog", name);
}
如果我对这一切有歧义,请告诉我,我会尽力澄清。
Should I include all attributes that are found in Animal...
那些对狗来说不是不变的,是的(一种或另一种方式;见下文)。但是例如,如果 Animal
有 latinFamily
,那么你不需要 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
的工作。
如果我有一个 class 'Dog' 扩展另一个 class 'Animal' 并且 Animal class 有一个构造函数,它有几个属性,比如 latinName, latinFamily等等 我应该如何为狗创建构造函数?我是否应该包括在 Animal 中找到的所有属性,以及我想要在 Dog 中找到的所有额外属性,如下所示:
public Animal(String latinName){
this.latinName = latinName;
}
public Dog(String latinName, breed){
super(latinName);
this.breed = breed;
}
实际 classes 的属性比我在这里列出的要多得多,因此狗的构造函数变得相当长,让我怀疑这是要走的路还是有更简洁的方法?
如果 Dog extends Animal 那么是的,你会想继续使用 Animal 的参数(因为狗确实是一种动物)并且 可能 添加更多以区分狗和动物 objects。
所以一般来说,是的,您需要包括所有 parent classes 的参数。
还要考虑多个构造函数的参数列表可能更短的可能性。假设 Animal 有一个参数 String type
,它定义了 child class 是什么类型的动物,你不需要每次都为 Dog
传递它。
public Dog (String name){
super("Dog", name);
}
如果我对这一切有歧义,请告诉我,我会尽力澄清。
Should I include all attributes that are found in Animal...
那些对狗来说不是不变的,是的(一种或另一种方式;见下文)。但是例如,如果 Animal
有 latinFamily
,那么你不需要 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
的工作。