抽象类-超级构造函数(Java)
我有一个非常简单的问题: 假设我有一个抽象类,它代表酒吧里的一个人抽象类-超级构造函数(Java),java,class,abstract,Java,Class,Abstract,我有一个非常简单的问题: 假设我有一个抽象类,它代表酒吧里的一个人 public class Person { protected String firstName; protected String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }
public class Person {
protected String firstName;
protected String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
我还有两个扩展个人的课程,比如说一个是调酒师的课程,另一个是顾客的课程
在客户类中,我还需要一个int作为字段表示他的年龄。在调酒师课上,我们没有
另外,对于customer类,我需要一个方法isAdult()
我现在有两个问题:
1) 当我得到消息“隐式超级构造函数Passenger()未定义。必须显式调用另一个构造函数”时,这不起作用。
这到底是什么意思?
2) 对于isAdult()方法,我觉得最好的方法是在抽象类Person中实现它,如下所示:
public abstract boolean isAdult();
public boolean isAdult() {
return (this instanceof Bartender || age > 18);
}
然后为调酒师提供“始终真实”服务,并为顾客提供年龄检查服务
另一种方法是直接从类人员实现,如下所示:
public abstract boolean isAdult();
public boolean isAdult() {
return (this instanceof Bartender || age > 18);
}
这种方法有效吗?哪种方法更好?Person使用构造函数定义了一个参数,没有默认的无参数构造函数。由于子类的超级构造函数必须始终在子构造函数中调用,并且Person没有默认构造函数,因此必须在子构造函数中显式调用它:
public Bartender(String firstName, String lastName) {
super(firstName, lastName);
// don't do this:
// this.firstName = firstName;
// this.lastName = lastName;
}
及
关于
isAdult()
,您可以在Customer类中使用此方法,而不在Bartender中使用。或者,如果super必须有此方法,那么如果有人在调酒师上调用它,您可以抛出异常,因为不应该这样调用它。对于您的第一个问题,请注意:当您创建一个类时,它会自动为您创建该类的默认构造函数。如果您创建另一个构造函数,您必须自己创建一个默认构造函数(这里的“默认”没有参数),因为Java认为您知道自己现在在做什么。因此,只需将其添加到Person
类:
public Person(){}
关于你的第一个问题,请看满是鳗鱼答案的气垫船;对于第二个问题,我认为您应该只给
Person
一个“age”属性(每个人都有一个age),逻辑isadalt
实现。如果调酒师
真的是人
,应该有年龄。因此,我认为你首先不应该假设调酒师是成年人。在调用Person#isadalt
的任何逻辑中,假设Person
是调酒师答案1:Java实际上总是调用超类的构造函数。例如:
class Super{
}
class Base extends Super{
public Base(){
//super() will always be called implicitly if a defaultconstructor is provided by Super
//do something else
}
}
这样做是因为基类的结构由基类的结构和超类的结构组成。如果不通过调用超类的构造函数初始化超类的结构,则可能会发生错误。由于Person不提供defaultconstructor,但无论如何都需要初始化,因此必须使用两个参数显式调用超级构造函数
答复2:
这两种方法都可以很好地工作,但我(以及我希望的其他所有人)强烈建议在派生类中单独实现它,以保持所有内容的可扩展性、干净性、可读性以及其他数千种原因。问题的第二部分:
在超类中抽象isAdult(),在子类中提供特定的实现。如果有几个子类具有类似的实现,那么您可以考虑将该实现放在父类中,并适当地重写。
父类永远不应该知道它们的子类,因此要避免让父类检查子类的实例