[英]Inheritance super variables
我正在编写一个简单的程序,其中有一个超类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,名称和姓氏变量仍然为空,超类不会返回它们。 我想念什么吗? 谢谢
您的代码应如下所示:
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声称我没有回答这个问题,这是真的。 我这样做是因为原始张贴者似乎不是Java新手,因此可能会问“错误”的问题。 我应该在最初的答复中强调这一点。 鉴于我的答案目前被标记为最好,我相信我做出了正确的决定。
继承仅适用于方法, 不适用于变量。 在子类中实现直接访问超类变量的方法也是不好的做法。 您最好在超类中实现访问方法。 由于继承,这些方法也将在子类中可用。
另一件事是实例变量的可见性。 您正在使用默认可见性,即“程序包范围”。 因此,如果您的子类不在同一包中,则它们将无法访问这些变量。 如果使用“私有”或“受保护”可见性,则访问变量要安全得多。
另一点是您没有正确初始化对象。 调用子类构造函数也必须调用超类构造函数,因为Employee对象依赖于Person对象提供的功能。 对此原理存在更科学的描述:
芭芭拉·利斯科夫(Barbara 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;
}
}
为超类实例变量添加访问方法,并将可见性设置为私有。
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;
}
}
调用超类构造函数以初始化超类。
您可以在两个类中定义这些属性,以便在子类中覆盖它们。 而且,您的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
。 有些人也使用相同的名称,只是他们在类的所有成员的开头添加了_
。 在任何情况下,当它们表示的变量具有特殊含义(姓,名)时,请勿使用无意义的名称,例如“ s”,“ n”等。 保留这些名称,例如,不带任何特定语义的局部变量(n将是整数,s将是String ...)。
您尚未初始化这些变量,这就是为什么它要为这些变量返回默认值。 在Java中,以下是变量的默认值。
int -> 0
String -> null (because String is Object in Java)
在您的示例中,您不需要tu use 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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.