继承超级变量

时间:2014-08-13 07:54:13

标签: java variables inheritance super

我正在编写一个简单的程序,其中我有一个由子类PersonCustomer继承的超类Employee(它们继承了变量IDnamesurname)。

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;
    }
}

但问题出在这里:当我尝试通过我的主类获取变量IDnamesurname时,它们无法返回(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,名称和姓氏变量仍然为空,超类不会返回它们。我错过了什么吗?感谢

5 个答案:

答案 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.