Logan
Logan

Reputation: 277

Inheritance super variables

I'm writing a simple program in which I have a super class Person inherited by the sub-classes Customer and Employee (they inherit the variables ID, name and 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;
    }
}

However the problem is here: when I try to get the variables ID, name and surname through my main class, they fail to return (0,null,null). Why is this? I have get-Methods in my sub-classes which should return the super variables, but they are not. Thanks for your time and patience.

public String getName() {
    return super.name;
}

UPDATE: ok so I sorted out the super(id,name,surname) in the Employee class constructor. I also removed all the getters and setters in the employee class since those are inherited from the Person superclass (correct me if I'm wrong?..)

Person superclass:

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

}

Employee subclass:

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

however, when I run the main program the ID, name and surname variables are still null, they are not being returned by the superclass. Am I missing something please? Thanks

Upvotes: 0

Views: 1564

Answers (5)

user2768
user2768

Reputation: 824

Your code should look something like this:

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

The important bit is super(id, name, surname).

EDIT

lionc claims that I did not answer the question, which is true. I did this because the original poster seems to be new to Java and, hence, might be asking the "wrong" question. I should have highlighted this in my original response. Given that my answer is currently marked as the best, I believe that I made the right decision.

Upvotes: 0

Raphaël
Raphaël

Reputation: 3726

In your example, you don't need tu use super to access the attributes defined in the super class since you are using package visibility for them (and both seems to be in the same package).

However, this is NOT the proper way to write Java code.

You should define a visibility for your attributes. In most case, it is recommended to use private visibility and to define getter and setter methods to access them:

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

In sub-classes, you just have to call getId() or setId(...) to access the Id attribute. No need to call super.getId(). Since Employee extends Person, it has access to all of its public, protected (and package if they are in the same package) attributes and method.

This means that in your current code, you can simply write name = n instead of 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...
}

Now to use these classes, you can write code like:

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() + '.'); 

For reference, this code works even with your current code. It prints:

Employee Ulrich Ser has for id 1234.

Upvotes: -1

Chip
Chip

Reputation: 380

Inheritance only works for methods NOT for variables. It is also bad practice to implement methods in subclasses that access super class variables directly. You'd better implement access methods in your superclass. Due to inheritance, those methods will be available in the sub-classes ass well.

Another thing is the visibility of you instance varibles. You are using the default visibility which is "package-wide". So if your sub-classes are not in the same package, they can't access those variables. If you use "private" or "protected" visibility you are much safer accessing the variables.

Another point is that you are initializing the objects not correctly. Calling the sub-class constructor has to call the super-class constructor as well because your Employee object relies on the functionality that your Person object provides. A more scientific description of this principle exists:

Barbara Liskov - Liskov substitution principle

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

Add access methods for super class instance variables and set visibility to 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;
    }
}

Call the super class constructor for initialization of the super class.

Upvotes: 0

Dici
Dici

Reputation: 25950

You define those attributes in both of your classes so you override them in the subclass. Moreover, your Employee constructor is not the way it should. You should call the adapted super-constructor as your first statement.

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

In your constructors, I consider a best practice to give the same name to your parameters as the name of your attributes to initialize and differenciate them thanks to this. Some people also use the same names except that they add a _ at the beginning of all the members of the class. In any case, don't use such meaningless names as "s", "n" etc when the variables they represent have a special meaning (surname, name). Keep those names for example for local variables without any particular semantic (n would be an integer, s would be a String...).

Upvotes: -1

hcl
hcl

Reputation: 64

You haven't initialized those variables, that's why it is returning default value for those variables. In java following are default values for variables.

int -> 0
String -> null (because  String is Object in Java)

Upvotes: -1

Related Questions