Proper syntax for super()? - java

When I use super() to use a superclass method, what is the proper way to return?
Let's say I have a class Hourly. It contains a constructor also called Hourly that has parameters "String name" and "double rate. The UML version looks like:
+Hourly(name:String, rate:double)
However, the "name" variable is a private attribute of the Employee class, of which the class hourly is related to via inheritance. By this I mean that the UML show a clear arrow (not a diamond) going from the class Hourly and pointing to the class Employee.
How would I write the constructor Hourly???
I have a basic skeleton of:
public Hourly(String name, double rate){
}
Please help me fill it in.
On a separate note, let's say that there was a return in a method. Say I wanted to return the double rate. What would be the proper syntax to return some that uses super() as I know I couldn't simply use:
return this.rate;

Your Employee surely has a name.
private String name;
public Employee(String name) {
this.name = name;
}
Following that, your Hourly must also have a name. Since an Hourly is-an Employee, you must set the name on it as well. That is accomplished like so.
public Hourly(String name, double rate) {
super(name);
this.rate = rate;
}

According to your comments, name is stored by the superclass; rate is not. So you should store rate in the Hourly class you're defining, while passing name to the super constructor, as follows:
public class Hourly {
private double rate;
public Hourly(String name, double rate) {
super(name);
this.rate = rate;
}
public double getRate() {
return rate;
}
}

If Hourly is sub class of Employee and if you want to parse the name to super class (Employee) then in your Hourly constructor call super(name);
public Hourly(String name, double rate){
super(name);
}

Since Hourly extends Employee:
class Hourly extends Employee {
private int rate;
public Hourly(String name, int rate) {
super(name); //assuming Employee has this constructor
this.rate = rate;
}
//this make sense if name is protected and doesn't have getter in base class
//ideally you would have this in base class itself
public String getName() {
return super.name; //for rate there is no sense in using super as it is not known to super class
}
}

Related

Constructor printing out NULL instead of object value

I created a new class "Lecturer" which extends another class "Person", i wanted to make 2 constructors for Lecturer and one would accept a name and a stipend (just a constant to say how much pay is), the other just accepts the name and uses the default stipend set in the code. i included appropriate getters and setters. I then wrote a writeOutput method to print an output similar to this
Name: (name) which gets the name and prints it
Stipend: (stipend) same process ^
heres what i have so far
Lecturer.java
public class Lecturer extends Person{
private static String name;
static double stipend;
public Lecturer(String name) {
super(name);
}
public Lecturer(String name, double stipend) {
super(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public static void writeOutput() {
System.out.println("Name: " + name);
System.out.println("Stipend: " + stipend);
}
}
Person.java
public class Person {
/** Every Person has a name */
private String name;
/** Person requires a name */
public Person(String n) {
this.name = n;
}
/** return this Person's name */
public String getName() {
return this.name;
}
/** Change this Person's name */
public void setName(String nn) {
this.name = nn;
}
Main file (Inheritance.java)
Lines 41-53
Lecturer l1 = new Lecturer("Zachary");
Lecturer l2 = new Lecturer("Wilhelmina", 11017.00);
l1.writeOutput();
l2.writeOutput();
pause();
l1.setName("Zack");
l1.setStipend(10800.00);
l1.writeOutput();
pause();
System.out.printf("%s's stipend is $%,4.2f.\n",
l1.getName(), l1.getStipend());
System.out.printf("%s's stipend is $%,4.2f.\n",
l2.getName(), l2.getStipend());
This is the output
Name: null
Stipend: 0.0
Name: null
Stipend: 0.0
press enter...
Name: Zack
Stipend: 10800.0
The 2nd part works as it should but the first one isnt and i tried to change the code but nothing is working properly.
In Lecturer you are declaring another name variable. This variable is separate from the name variable declared in Person. The call to the superclass constructor is setting the name variable in Person, not in Lecturer. But you don't need the second variable; remove it. You can access the name in Person via the getName method you've already declared. This means that you also don't need to re-declare getName and setName in Lecturer, so the Lecturer class can inherit them.
Also, in Lecturer, the two variables you've declared shouldn't be static. Per the above reasoning, name shouldn't even be there, but even if it should be there, it shouldn't be static. The variable stipend should be there, but it shouldn't be static. When you declare a member variable static, then there is only one variable for the entire class, no matter how many instances you create, which doesn't sound like what you want.
Your constructors should initialize stipend.
You have a static variable inside Lecturer which has the same name as the inherited one from Person and your getter is referring to that static one - are you sure you want these static variables? For completeness if you really want to keep the static one and the inherited one with the same name then change your getter to read return this.name; which will return the inherited name instance variable.... But that method can be inherited from Person class...
There are two name fields in your program , one is private static String name; in Lecturer.java and another is private String name; in person.java .
The thing is that you are just calling Lecturer javs's name field but not setting it.
Fixed the project based on rgettman answer.
Lecturer class should look like this:
public class Lecturer extends Person {
double stipend = 9144;
public Lecturer(String n) {
super(n);
}
public Lecturer(String n, double stipend) {
super(n);
this.stipend = stipend;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public void writeOutput() {
System.out.println("Name: " + this.getName());
System.out.println("Stipend: " + getStipend());
}
}

Omit Parent class attributes in java

I have two java class:
class Employee{
private name;
private annualSalary;
public Employee(String name, double annualSalary){
}
}
and
class HourlyEmployee extends Employee{
public HourlyEmployee(String name, double annualSalary, double hourlySalary){
super(salary, annualSalary);
this.hourly = hourlySalary;
}
}
Is there a way I can get rid of the annualSalary from the inherited class understanding that the annualSalary = hourlySalary * 200? by default when the HourlyEmployee class is created. The value for annualSalary will be empty or set to hourlySalary * 200.
Remove annualSalary and pass hourlySalary * 200 to super-class constructor.
public class HourlyEmployee extends Employee {
private double hourlySalary;
public HourlyEmployee(String name, double hourlySalary) {
super(name, hourlySalary * 200);
this.hourlySalary = hourlySalary;
}
}
Your class structure is wrong because not all employees get an annual salary. Get rid of annualSalary from Employee and create two subclasses: HourlyEmployee that has an hourly salary and a SalariedEmployee that has an annual salary. If needed, introduce an abstract method getAnnualSalary in Employee (and make Employee abstract) and implement it differently in the two subclasses.
abstract class Employee {
private String name;
public Employee(String name) { ... }
public abstract double getAnnualSalary();
}
class SalariedEmployee extends Employee {
private double annualSalary;
public SalariedEmployee(String name, double annualSalary) {
super(name);
this.annualSalary = annualSalary;
}
#Override
public double getAnnualSalary() { return annualSalary; }
}
class HourlyEmployee extends Employee {
private double hourlySalary;
public HourlyEmployee(String name, double hourlySalary) {
super(name);
this.hourlySalary = hourlySalary;
}
#Override
public double getAnnualSalary() { return 200 * hourlySalary; }
}
You might also want to explore using interfaces to define employee behavior, rather than using a base class.
Needing to omit parent class attributes is a code smell called refused bequest. If an hourly employee does not have a yearly salary, the class that represents an hourly employee should not inherit from the class that represents a salaried employee.
The solution is extracting the parts they have in common to a separate class, or several different classes, depending on the case. In your current contrived example there's nothing the two classes have in common, and I see no point in using inheritance to begin with.

Should protected fields in an Abstract super class be accessed using super or this in sub-classes?

Suppose I have the following Abstract class.
public abstract class Account {
protected String Id;
protected double balance;
public Account(String Id, double balance) {
this.Id = Id;
this.balance = balance;
}
}
And the following subclass
public class CheckingAccount {
public CheckingAccount(String Id, double balance) {
super(Id, balance)
if(super.balance > 10_000) this.balance += 200;
}
}
Both 'this' and 'super' are allowed in the context of the subclass when accessing a protected member. Is it better to use one over the other? 'super' makes it explicit where that field comes from. I understand I can just use balance without specifying the implicit parameter but I was just curious in terms of how this is utilized in practice if one wanted to specify the implicit parameter.
Since CheckingAccount inherits protected field balance from Account so it DOES NOT matter using super or this keyword to access the field balance in CheckingAccount class. However, I prefer 'this'.
If there is a protected method in Account class (base class) and there is a its overridden method in CheckingAccount class, you will have to carefully use super or this in this case because they are not the same body implementation!
I'd argue you shouldn't use any protected fields, to enforce encapsulation. Provide a protected void addToBalance(double value) method would be the cleaner way.
I was just curious in terms of how this is utilized in practice if one wanted to specify the implicit parameter
For somewhat academic reasons, here's where it makes a difference:
public abstract class Account {
protected String Id;
protected double balance;
public Account(String Id, double balance) {
this.Id = Id;
this.balance = balance;
}
}
public class CheckingAccount {
// overwrite existing field
protected double balance;
public CheckingAccount(String Id, double balance) {
super(Id, balance);
this.balance = balance;
if(super.balance > 10_000) this.balance += 200;
}
}

Passing a Class type within a constructor of another class?

Do forgive me if the title is not correct, I thought this very question has to with "Polymorphism" but didn't want to complicate the title.
I am learning Java and following "Java: Learn to Program", As I am going along, I am applying the knowledge and creating my own scenarios to see
how "Polymorphism" is applied. I would appreciate it if someone can help me understand how to do this task. I have three classes:
Abstract Employee
Manager (Subclass of Employee)
Restaurant
Employee class and Manager class are pretty straight forward. I am trying to create a restaurant and every restaurant has a manager. My question is:
Should I pass "Manager" type as constructor arguments of "Restaurant" class or instantiate the "Manager" object in the constructor?
public abstract class Employee{
private String _empName;
private double _empSalary;
public Employee( string name, double salary){
_empName = name;
_empSalary = salary;
}
public void setEmpName( String name ){
_empName = name;
}
public String getEmpName(){
return _empName;
}
public void setEmpSalary( double salary ){
_empSalary = salary;
}
public double getEmpSalary(){
return _empSalary;
}
}//CLASS
public class Manager{
private double _yrsOfExp;
public Manager( String name, double salary, double experience ){
super(name, salary);
_yrsOfExp = experience;
}
public void setManagerExperience( double years ){
_yrsOfExp = years;
}
public double getManagerExperience(){
return _yrsOfExp;
}
}//CLASS
This is where I need help, I am declaring the constructor with "MANAGER TYPE". Should I be declaring the instance of "Manager" with the construction instead of
passing "Manager type" with the constructor, please?
public class Restaurant{
private Manager _manager;
private String _location;
//CONSTRUCTOR 1
//SHOULD I PURSUE IT THIS WAY OR
public Restaurant( Manager manager, String location){
_manager = manager;
_location = location;
}
//CONSTRUCTOR 2
//SHOULD I DO IT THIS WAY?
public Restaurant( String name, double salary, double experience, String location){
super(name, salary, experience);
_location = location;
}
public String toString(){
String str = "";
return str;
}
}//CLASS
This is partly a matter of taste and of what else you're going to do with the objects.
If you may ever want to refer to Managers independently, then they want to be their own object rather than properties of the Restaurant.
Since a Restaurant is not itself a Manager, I would suggest that it shouldn't take a Manager's properties in its constructor, and should instead have a Manager assigned to it (either in the constructor or in a setManager() call).
Among other things, that will make much more sense if one Manager is ever in charge of two Restaurants.

Creating Objects that Extend from one Class to put in array list

I'm trying to write a payroll program that simply receives input, does some calculations and displays the output for EACH employee.
I have two types of employees, hourly and salary. I created a class for each type that extends to an abstract employee class:
public abstract class Employee{
private String name;
private String type;
private int hours;
private double rate;
}
public class SalaryEmployee extends Employee{
public SalaryEmployee(String type, String name, int hours, double rate){
this.type = type;
this.name = name;
this.hours = hours;
this.rate = rate;
}
public void print(){
}
}
In my main method, when I try to create my objects using the code below:
Employee employee;
if(type.equals("hourly"))
{
employee = new HourlyEmployee(type, name, hours, rate);
}
else
{
employee = new SalaryEmployee(type, name, hours, rate);
}
I get the following error when I try to compile:
Lab3.java:53: not a statement
SalaryEmployee employee = new SalaryEmployee(type, name, hours, rate);
^
Lab3.java:53: ';' expected
SalaryEmployee employee = new SalaryEmployee(type, name, hours, rate);
^
2 errors
Any idea what is happening here? I've looked around for messing semi colons or braces, but haven't found anything yet.
Thanks for looking.
It is illegal to declare a variable in an if that does not use braces. It looks like what you meant to write is something like this:
Employee employee;
if(type.equals("hourly"))
employee = new HourlyEmployee(type, name, hours, rate);
else
employee = new SalaryEmployee(type, name, hours, rate);
Most coding conventions support always using braces after an if or else.
The only error I can see is that your SalaryEmployee class cannot access the base class variables because they are private. You should make them protected.
Although, the error you are getting would be different.. If you are still getting the error after changing, your error is probably lying elsewhere.

Categories