我是Java新手,所以请原谅我的无知。
从父类隐式地为类属性设置值与使用构造函数和调用super
之间有什么有意义的区别吗?
我认为我没有正确地解释我的意思,所以这里有一个具体的例子
public class Parent {
protected String name;
}
public class Child extends Parent{
public Child() {
this.name = "Child";
}
}
字符串
相对于
public class Parent {
protected String name;
public Parent(String name) {
this.name = name;
}
}
public class Child extends Parent{
public Child() {
super("Child");
}
}
型
这段代码本质上做了同样的事情。如果setter/getter存在于父类或子类中,它们的工作方式与您期望的工作方式差不多。
3条答案
按热度按时间58wvjzkj1#
在您的两个示例中,通过
new Child();
创建Child
对象将导致子对象的String name
字段设置为"Child"
。构造函数链接通常是为了使代码更易于维护并避免重复代码。例如,我们假设
String name
属性不是使用固定值,而是必须传递到构造函数中的参数。我们还想禁止String name
属性的null
值,并在用户试图通过将null
传递到构造函数中来创建Object时抛出错误。如果没有构造函数链和调用
super(name)
,你最终会得到这样的代码:字符串
而如果你使用构造函数链接,你就不必写重复的代码,因为你可以把所有的逻辑都放在总是被调用的父构造函数中:
型
ctrmrzij2#
正如你正确提到的,这段代码做同样的事情。然而,在这种特定情况下,使用
public Parent(String name)
有一些相互关联的优点:String name
标记为final,在这种情况下实际上意味着什么。Parent
类定义了name
,所以它不应该依赖于Child
类是如何实现的,或者它是否存在。inn6fuwd3#
这个问题很抽象,所以我的答案也很抽象:)
正如您所指出的,对于这个特定的实现,这并不重要,从技术上讲,您正在做同样的事情。但是,您可能对如何分配字段有一些逻辑(尽管,我个人反对构造函数中的任何逻辑,除了字段分配)。例如,你可能想“清理”你的
name
,通过替换尾随的空格等等。或者检查名称是否有效或不为空,那么将它放在父类中将是有益的,这样任何子类都不会混淆逻辑。这意味着您的第二个示例更适合这种情况。它可能是相反的,当你需要在孩子身上做一些特殊的清理,而不是在父母身上,那么第一个例子更好。这是从实际的Angular 。我个人认为第二个例子更好,因为它通常使代码更简单。我通常甚至试图避免setter,并使字段
final
,甚至可能是私有的。换句话说,如果这个name
字段属于Parent
,那么让parent分配它,不要试图干预。然后,每次当你看到name
是错误的,或者你需要以某种方式改变你如何分配名称的逻辑,你知道一个唯一的地方这样做。也许明天你会决定引入两个额外的字段firstName
和lastName
,逻辑将是这样的:用空格分隔姓名并指定名字和姓氏。如果使用第一个示例,则需要重复此逻辑。在第二个示例中,您只需要挂钩到Parent
的构造函数。