我正在编写一个简单的程序,其中我有一个由子类Person
和Customer
继承的超类Employee
(它们继承了变量ID
, name
和surname
)。
public class Person {
int id;
String name;
String surname;
public Person() {}
public Person(int i, String n, String s) {
id = i;
name = n;
surname = s;
}
}
public class Employee extends Person implements Serializable {
String username;
String password;
String date;
int hpw;
int recordSold;
float hourPay;
public Employee() {}
public Employee(String u, String n, String s, String p, int i, int h, String d, int rSold, float hPay) {
username = u;
super.name = n;
super.surname = s;
password = p;
super.id = i;
hpw = h;
date = d;
recordSold = rSold;
hourPay = hPay;
}
}
但问题出在这里:当我尝试通过我的主类获取变量ID
,name
和surname
时,它们无法返回(0,null,null)。为什么是这样?我的子类中的get-Methods应该返回超级变量,但它们不是。感谢您的时间和耐心。
public String getName() {
return super.name;
}
更新: 好的,所以我在Employee类构造函数中整理了super(id,name,surname)。我还删除了员工类中的所有getter和setter,因为那些是从Person超类继承的(如果我错了,请纠正我?)
人超类:
public class Person {
private int id;
private String name;
private String surname;
public Person () {
}
public Person(int i, String n, String s) {
this.id = i;
this.name = n;
this.surname = s;
}
public void setID(int i) {
this.id = i;
}
public void setName(String n) {
this.name = n;
}
public void setSurname(String s) {
this.surname = s;
}
public int getID() {
return id;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
}
员工子类:
import java.io.*;
public class Employee extends Person implements Serializable {
protected String username;
protected String password;
protected String date;
protected int hpw;
protected int recordSold;
protected float hourPay;
public Employee() {
super();
}
public Employee(int i, String u, String n, String s, String p, int h, String d, int r, float hP) {
super(i,n,s);
username = u;
password = p;
date = d;
hpw = h;
recordSold = r;
hourPay = hP;
}
public void setUser(String u) {
username = u;
}
public void setPassword(String p) {
password = p;
}
public void setHWeek (int h) {
hpw = h;
}
public void setDate (String d) {
date = d;
}
public void setRSold (int r) {
recordSold = r;
}
public void setHPay (float p) {
hourPay = p;
}
public String getUser() {
return username;
}
public String getPassword() {
return password;
}
public int getHWeek() {
return hpw;
}
public String getDate() {
return date;
}
public int getRSold() {
return recordSold;
}
public float getHPay() {
return hourPay;
}
但是,当我运行主程序时,ID,名称和姓氏变量仍然为空,超类不会返回它们。我错过了什么吗?感谢
答案 0 :(得分:0)
您的代码应如下所示:
public class Person {
private int id;
private String name;
private String surname;
public Person (int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public int getId() {
return id;
}
... //similarly for getName() and getSurname()
}
public class Employee extends Person {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee (int id, String name, String surname, String username, String password, String date, int hpw, int recordSold, float hourPay) {
super(id, name, surname);
this.username = username;
... //similarly for other parameters.
}
}
重要的一点是super(id, name, surname)
。
lionc声称我没有回答这个问题,这是真的。我这样做是因为the original poster似乎是Java的新手,因此可能会问“错误”的问题。我应该在原来的回复中强调这一点。鉴于我的答案目前被评为最佳,我相信我做出了正确的决定。
答案 1 :(得分:0)
继承仅适用于变量的 NOT 方法。在直接访问超类变量的子类中实现方法也是不好的做法。您最好在超类中实现访问方法。由于继承,这些方法将在子类中很好地提供。
另一件事是实例变量的可见性。您正在使用“包范围”的默认可见性。因此,如果您的子类不在同一个包中,则它们无法访问这些变量。如果您使用“私有”或“受保护”的可见性,则访问变量会更安全。
另一点是您正在初始化对象不正确。调用子类构造函数也必须调用超类构造函数,因为您的Employee对象依赖于Person对象提供的功能。存在对这一原则的更科学的描述:
Barbara Liskov - Liskov替代原则
public class Person {
private int id;
private String name;
private String surname;
public Person() {}
public Person(int i, String n, String s) {
id = i;
name = n;
surname = s;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public int getSurname() {
return this.surname;
}
}
为超类实例变量添加访问方法,并将可见性设置为private。
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee() {}
public Employee(String u, String n, String s, String p, int i, int h, String d, int rSold, float hPay) {
super(id, name, surname);
this.username = u;
this.password = p;
this.hpw = h;
this.date = d;
this.recordSold = rSold;
this.hourPay = hPay;
}
}
调用超类构造函数来初始化超类。
答案 2 :(得分:-1)
您可以在两个类中定义这些属性,以便在子类中覆盖它们。而且,您的Employee构造函数不是它应该的方式。您应该将调整后的超级构造函数作为您的第一个语句。
public class Person {
protected int id;
protected String name;
protected String surname;
public Person(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
}
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee(String username, String name, String surname, String pswd, int id,
int hpw, String date, int rSold, float hPay) {
super(id,name,surname);
this.username = username;
this.password = pswd;
this.hpw = hpw;
this.date = date;
this.recordSold = rSold;
this.hourPay = hPay;
}
}
在您的构造函数中,我认为最佳做法是为您的参数指定相同的名称作为属性名称,以便通过this
初始化和区分它们。有些人也使用相同的名称,只是他们在类的所有成员的开头添加_
。无论如何,不要使用像#34; s"," n"当它们所代表的变量具有特殊含义(姓氏,名称)时。保留这些名称,例如局部变量,没有任何特定的语义(n将是一个整数,s将是一个String ...)。
答案 3 :(得分:-1)
您尚未初始化这些变量,这就是为什么它会为这些变量返回默认值。在java中,以下是变量的默认值。
int -> 0
String -> null (because String is Object in Java)
答案 4 :(得分:-1)
在您的示例中,您不需要使用super
来访问超类中定义的属性,因为您正在使用它们的包可见性(并且两者似乎都在同一个包中)。
但是,这不是编写Java代码的正确方法。
您应该为属性定义可见性。在大多数情况下,建议使用private
可见性并定义getter和setter方法以访问它们:
public class Person {
private int id;
private String name;
private String surname;
public Person() {}
public Person(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// And so on...
}
在子类中,您只需调用getId()
或setId(...)
即可访问Id属性。无需致电super.getId()
。由于Employee
扩展了Person
,因此它可以访问所有公共受保护的(如果它们在同一个包中,则为包)属性和方法。
这意味着在您当前的代码中,您只需编写name = n
而不是super.name = n
。
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee() {}
public Employee(String username, String name, String surname, String password, int id, int hpw, String date, int rSold, float hPay) {
super(id, name, surname);
this.username = username;
this.password = password;
this.hpw = hpw;
this.date = date;
this.recordSold = rSold;
this.hourPay = hPay;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
// And so on...
}
现在要使用这些类,您可以编写如下代码:
Employee e = new Employee("user3149152", "Ulrich", "Ser", "passwd", 1234, 0, "2014/08/13", 0, 0);
System.out.println("Employee " + e.getName() + ' ' + e.getSurname() + " has for id " + e.getId() + '.');
作为参考,此代码甚至可以与您当前的代码一起使用。 它打印:
Employee Ulrich Ser has for id 1234.