Class constructors not initializing values correctly [duplicate] - java

This question already has answers here:
What are java object fields initialized with?
(6 answers)
Closed 7 years ago.
I have a main java file and an employee class. For the employee class I have 3 methods - a getName method which returns an employee name, a getSalary method which returns a salary, and a raiseSalary which raises the salary by a certain percent.
In my Main.java file, I made a constructor to initialize the values of the employee class, and when I attempt to printout these values, I get null and 0
/**
* This class tests the Employee object.
*
*/
public class Main {
/**
* Create an employee and test that the proper name has been created. Test
* the initial salary amount and then give the employee a raise. Then check
* to make sure the salary matches the raised salary.
*
public static void main(String[] args) {
Employee harry = new Employee("Hi", 1000.00);
System.out.println("Employee name:" + harry.getName());
System.out.println("Salaray: "+ harry.getSalary());
harry.raiseSalary(10); // Harry gets a 10% raise.
}
}
/*** This class implements an employee which is a person with a name and a salary.
*
*/
public class Employee {
private String employeeName;
private double currentSalary;
public Employee(String employeeName, double currentSalary) {
}
// Accessors that are obvious and have no side effects don't have to have
// any documentation unless you are creating a library to be used by other
// people.
public String getName() {
return employeeName;
}
public double getSalary() {
return currentSalary;
}
/**
* Raise the salary by the amount specified by the explicit argument.
*
*/
public void raiseSalary(double byPercent) {
currentSalary = getSalary() * byPercent;
}
}

The parameters in your constructor do not point to the same objects created outsides it's scope... to fix simply
public Employee(String employeeName, double currentSalary) {
this.employeeName = employeeName;
this.currentSalary = currentSalary;
}
Adding a "this" before a variable name simply tell the code to point at the variable outside the scope

Related

It shows an error when executing the inheritance constructors "actual and formal argument lists differ in length" [duplicate]

I have 2 subclasses: Staff, Student
they belong to superclass Person.
Here is the code(tasks) which is given by my teacher:
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
}
class Student extends Person
{
private String SID; // student ID number
/**
* Create a student with no parameters.
*/
Student()
{
//task.
}
}
public class Staff extends Person
{
private String roomNumber;
/**
* Construct a staff member with field values and no pamaeters.
*/
public Staff()
{
//task
}
}
I don't know what can I type in order to create an object without parameter.
It always appears an error like: constructor Person in class Person cannot be applied to given types; required: java.lang.String,int;
I have checked online that there are 2 ways to solve the problem:
add a default value in the superclass: Person()//without parameter.
In the subclass Student:
Student()
{
Person astudent = new Student() //I guess.
}
add a super() in the subclass:
Student()
{
super("xxx")//I guess.
}
I don't know what to do. I an a starter in learning BlueJ.
Hope anyone can help me. Thank you very much.
Since your superclass Person doesn't have a default constructor, in your subclasses (Student and Staff), you must call the superclass constructor as the first statement.
You should define your sub-class constructors like this:
Student() {
super("a_string_value", an_int_value);// You have to pass String and int values to superclass
}
Staff() {
super("a_string_value", an_int_value); // You have to pass String and int values to super class
}
the first thing a constructor will do, is call the constructor (with same arguments) of the super class.
Person does not have a no-argument constructor, so, you must change your code in one of next two ways:
Student(String name, int yearOfBirth)
{
//task.
}
or
Student()
{
super("", 0);
//task.
}
and the same goes for Staff
Add super(NAME_IN_STRING_TYPE,YEAR_OF_BIRTH_IN_INT_TYPE); as a first statement in your subclasse's constructor like
Student constructor
Student()
{
super("name", 1970); // String,int arguments passed
//task.
}
Staff constructor
Staff()
{
super("name", 1970); // String,int arguments passed
//task.
}
This is needed since there is no default no-arg constructor in the base class. You have to explicitly define a no-arg constructor in base class or you need to instruct the compiler to call the custom constructor of the base class.
Note : Compiler will not add default no-arg constructor in a class if it has a user defined constructor. It will add the default no-arg constructor only when there is no constructor defined in the class.
Try this:
Student(String name, int yearOfBirth) {
super(name, yearOfBirth);
// task...
}
Reason: you dont have a default constructor at your superclass. So you have to call super() at the first position in your subclass constructor.
To construct instance of Student you need to do actions neccesary to construct Person first. There is only one way to construct Person - two-arg constructor. That means you have to change Student like:
public Student() {
super("someName", 1950); //first values came to my mind
}
Although you should be aware that Student should behave exactly like Person if treated as Person, i.e. have age and name. So actually I'd recommend to change Student constructor to include name and age there.
If you want to create an object of child class (ie Staff and Student) without passing parameters then you can create an additional constructor without parameters in the parent class (ie Person class) as below.
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
// additional constructor without parameter
Person(){
// add your code here
}
}
now below code will work without any error.
Staff stf = new Staff();
Student std = new Student();
for constructor no param you should have two constructors like
public class Student {
Student(String name , int dateOfBirth)
{
super(name,dateOfBirth)
}
Student()
{
//task.
}
}
also same for other class
student should not extend person.
bcoz, if we create obj for student, person’s constructor will be called automatically.

Can anyone help me with "tostring" method in java?

Im doing an OOP assignment.. It has four classes Person, student and employee both extends person and instructor that extends employee. .
I have done Almost everything i could but i cant print out values using tostring method and Cant fill the array.I have used getter setter and all the constructor and methods are there still cant get any output. heres the person class and all the remain three classes have been made. plus the main file
abstract class Person
{
protected int Id;//"protected"Only child can use this
protected String Name;
public Person() {}
public Person(int id,String name)
{
this.Id=id;
this.Name=name;
}
public int getId()
{
return this.Id;
}
public void setId(int id)
{
this.Id=id;
}
public String getName()
{
return Name;
}
public void setName(String name)
{
this.Name=name;
}
public String toString()
{
return Id + Name + " is a student ";
}
public static int getMaxID()
{
return 0;
}
////////////////////////////////////////////////////////////////////////////////
public class Employee extends Person
{
protected double Salary;
protected String employeeName;
public Employee() {}
public Employee(double salary)
{
this.Salary=salary;
}
public Employee(String employeename)
{
this.employeeName=employeename;
}
public String getemployeeName()
{
return employeeName;
}
public void setemployeeName(String employeename)
{
this.employeeName=employeename;
}
public double getSalary()
{
return this.Salary;
}
public void setSalary(double salary)
{
this.Salary=salary;
}
public String toString()
{
return employeeName + " is an instructor earning a salary of " + Salary;
}
}
////////////////////////////////////////////////////////////////////////////////
public class Student extends Person
{
protected int teacherID;
protected String teacherName;
protected String studentName;
public Student() {}
public Student(int teacherid,String teachername)
{
this.teacherID=teacherid;
this.teacherName=teachername;
}
public Student(String studentname)
{
this.studentName=studentname;
}
public Student(String teachername, String studentname, Person[] person_array)
{
this.teacherName=teachername;
this.studentName=studentname;
}
public int getteacherID()
{
return this.teacherID;
}
public void setteacherID(int teacherid)
{
this.teacherID=teacherid;
}
public String getteacherName()
{
return teacherName;
}
public void setteacherName(String teachername)
{
this.teacherName=teachername;
}
public String toString()
{
return studentName + " is a student ";
}
}
////////////////////////////////////////////////////////////////////////////////
public class Instructor extends Employee
{
int[] studentID=new int[10];
protected String instructorName;
public Instructor(String instructorname)
{
this.instructorName=instructorname;
}
public Instructor(String instructorname, double salary)
{
this.instructorName=instructorname;
this.Salary=salary;
}
public double getSalary()
{
return Salary;
}
public void setSalary(int salary)
{
this.Salary=salary;
}
public String getinstructorName()
{
return instructorName;
}
public void setinstructorName(String instructorname)
{
this.instructorName=instructorname;
}
static void findStudents(Person[] person_array)
{
}
public String toString()
{
return instructorName + " is an instructor earning a salary of " + Salary;
}
}
////////////////////////////////////////////////////////////////////////////////
//CIS 459.23 Lab 2
//Due Oct 30 (Sunday)
//OSU wants you write some classes for their Personnel Record System. To make it simple,
//consider only 4 classes: Person, Employee, Instructor and Student. The following figure
//illustrates the relationship between these 4 classes. The Person class is the parent class of the
//Employee class and the Student class. The Employee class is the parent class of the Instructor
//class.
//The following are the tasks you need to complete for each of these classes.
// Create appropriate fields for each class. Necessary fields are listed. Add your own fields if
//needed. Some fields need to have appropriate constraint. Use your own way to make sure
//that these constraints are satisfied.
//o Person
//ID: int, starting from 1 and should be unique
//Name: String
//o Employee
//Salary: double and should not be negative
//o Student (For simplicity, assume that a student has at most 1 teacher)
//TeacherID: int. It’s his/her instructor's ID. 0 if no instructor is given
//TeacherName: String
//o Instructor:
// StudentIDArray: int array. An array of students’ IDs of this instructor. Set the
// array size to be 10, initially all 0s, assuming an instructor won’t have more than
// 10 students.
// All the above fields are private and only accessible through the access methods.
// A “toString()” method for each class to print out all the available information about the
// current object. In Person class “toString()” is declared as abstract.
// A static “findStudents(Person[] personArray)” method in the Instructor class to fill an
// instructor object’s students ID array, and the corresponding students’ TeacherID fields. See
// the test program for better understanding.
// Person should be declared as abstract class.
// Provide multiple constructors/methods if needed. Check the test.java program to see what
// constructors/methods are necessary and what actions they should do.
// If a class can use the parent class method and constructor, use “super” to call it to reduce the
// redundant code.
// Make sure this test.java program can work with your class.
// sample output. From this sample output, you’ll know what information you should print out
// for a specific object.
// NOTE: the sample output is not the unique output format of the test program. The real output
// format depends on how you design the toString() methods in each class. But make sure that your
// program will print out as much information about each object’s fields as possible, including the
// Person
// Instructor
// Employee Student
// inherited fields and the fields defined in its own class.
// HINT:
// o There is NO main method in any of these 4 classes
// o To make sure ID is unique across the objects, declare a static “LAST_ID” in the Person
// class.
// o Read descriptions in test.java VERY CAREFULLY for better
// understanding!
// Submit your Person.java, Emloyee.java, Student.java and Instructor.java files
// Appendix 1: Test Program
/*
* Lab 2 Program to test the Person, Employee, Student, and Instructor classes.
*/
public class Lab2_Test
{
public static void main(String[ ] args)
{
// uncommenting the following line should produce a compile error.
// This is for testing of an abstract class.
// Person p = new Person("George");
final int MAX_HEADCOUNT = 20;
Person[] person_array = new Person[MAX_HEADCOUNT];
// A student named Peter
person_array[0] = new Student("Peter");
// An instructor named Peter
person_array[1] = new Instructor("Peter");
// An instructor named Sandy and her salary
person_array[2] = new Instructor("Sandy", 25000);
// A janitor named Bob
person_array[3] = new Employee("Janitor Bob");
// A student named Tom and his instructor is Peter.
// The constructor needs to do three things:
// 1: sets this student’s “TeacherName” field to be “Peter”,
// 2: finds out the ID of the 1st instructor
// who exists in the person_array so far and named "Peter",
// and assign it to this student's “TeacherID” field.
// Set it to be 0 if no instructor named Peter is found in the person_array so far
// 3: records this student’s ID in the instructor’s StudentArray if such an instructor is found
// right after executing the following statement
// person_array[4].TeacherID = 2
// person_array[4].TeacherName = “Peter”
// person_array[1].StudentArray[0] = 5
person_array[4] = new Student("Tom", "Peter", person_array);
// A student named Maggie and her instructor is Susan
// right after executing the following statement
// person_array[5].TeacherID = 0
// person_array[5].TeacherName = “Susan”
person_array[5] = new Student("Maggie", "Susan", person_array);
// An instructor named Susan and her salary
person_array[6] = new Instructor("Susan", 40000);
// After all objects are created,
// instructors need to fill their students arrays,
// and some students need to fill their TeacherIDs now,
// since there may exist cases that when a Student object is created with instructor’s name,
// the corresponding Instructor object hasn’t been created and is not in the person_array.
// For example, person_array[6] is created after person_array[5].
// You need to record person_array[5]’s ID in person_array[6]’s studentArray field,
// and record person_array[6]’s ID in person_array[5]’s TeacherID field.
// Note: if there are more than one Instructor objects
// having the same names as a Student object’s TeacherName,
// it’ll always be the first one’s ID assigned to the Student object’s TeacherID
Instructor.findStudents(person_array);
System.out.println("ID and name of all personnel in the array");
for (int i = 0; i < Person.getMaxID(); i++)
{
System.out.println(person_array[i].getId() + ":" + person_array[i].toString());
}
}
You are trying to print using this:
for (int i = 0; i < Person.getMaxID(); i++)
{
System.out.println(person_array[i].getId() + ":" + person_array[i].toString());
}
But, the getMaxID() method in your Person class returns a hardcoded 0, so this loop will never iterate, and your print statement will never be reached.
EDIT: it makes no sense to even check for a maxId. Check against the length of the array:
for (int i = 0; i < person_array.length; i++)
{
System.out.println(person_array[i].getId() + ":" + person_array[i].toString());
}

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

Java ArrayList StackOverFlowError

This is my first time asking a question so please be patient. I am working on a school assignment and have been battling a stackoverflow error that I do not know enough about to get to the bottom of. The errors are indicated by ~~~:
The sections of code from the stack trace are as follows:
public class Employee extends StaffMember {
public static final int DEFAULT_SIN = 123456789;
public static final double MINIMUM_WAGE = 400.00;
protected int socialInsuranceNumber = DEFAULT_SIN;;
protected double payRate = MINIMUM_WAGE;
/**
*
*/
public Employee() {
super();
}
/**
* #param name
* #param streetAddress
* #param phone
* #param socialInsuranceNumber
* #param payRate
*/
public Employee(String name, String address, String phone, int socialInsuranceNumber, double payRate) {
~~~ super(name, address, phone);
this.socialInsuranceNumber = socialInsuranceNumber;
this.payRate = payRate;
}
public abstract class StaffMember extends Staff {
public static final String DEFAULT_NAME = "Default Name";
public static final String DEFAULT_ADDRESS = "Default Address";
public static final String DEFAULT_PHONE = "Default Phone";
protected String name;
protected String address;
protected String phone;
/**
* default constructor
*/
public StaffMember() {
super();
}
/**
*
* #param name
* #param address
* #param phone
* abstract class can not be instantiated therefore should not
* have constructors
*/
~~~ public StaffMember(String name, String address, String phone) {
super();
this.name = name;
this.address = address;
this.phone = phone;
}
public class Staff {
public ArrayList<StaffMember> staffList;
/**
* Constructor for objects of type Staff.
*/
public Staff() {
staffList = new ArrayList<StaffMember>(6);
~~~ staffList.add(new Executive("Hilary", "203 Whitewater Line", "871-0469", 123456789, 5000, 0));
staffList.add(new Employee("Thomas", "1000 Robson Street", "604-0000", 010203040, 1500));
staffList.add(new Hourly("Condoleeza", "678 Fifth Ave.", "905-0690", 958473625, 18.50, 0));
staffList.add(new Volunteer("Kimberly", "1200 West Point Grey Road", "514-8374"));
staffList.add(new Volunteer("Jean", "321 Shawinigate Lane", "613-7282"));
}
public class Executive extends Employee {
private double bonus;
/**
* Default Constructor
*/
public Executive() {
super();
}
/**
* #param name
* #param address
* #param phone
* #param socialInsuranceNumber
* #param payRate
*/
public Executive(String name, String address, String phone, int socialInsuranceNumber, double payRate, double bonus) {
super(name, address, phone, socialInsuranceNumber, payRate);
this.awardBonus(bonus);
}
There is a Circular chain of constructor invocations.
Your base class constructor Staff() is instantiating child classes which in turn invoke self constructor leading to infinite chain causing stackOverFlow error.
Also, it doesn't seem correct for StaffMember to extend Staff . As staff is the entire staff consisting of all the employees and StaffMember represents a single employee. There is no is A relationship between the two.
You should remove the extends Staff from StaffMember and the code should also work fine then.
The constructor of your class A calls the constructor of class B. The constructor of class B calls the constructor of class A. You have an infinite recursion call, that's why you end up having a StackOverflowError. You are going into an circular call of constructors.
Java supports having circular dependencies between classes, the problem here is only related to constructors calling each others.
You are having a circular instantiation of objects which is causing your stack to overflow.
In your Staff constructor you are instantiating many classes, such as Executive and Employee. Your Executive class extends the Employee class and your Employee class extends your StaffMember class.
When you do that, the constructor of Staff will be called again implicitly (by calling super() from Executive, then Employee and then StaffMember) and repeat the entire process, thus consuming all your memory.
Getting rid of your class that extends Staff would probably solve your problem (probably the problematic one is the extends from StaffMember which is the last on the chain of invocations).

Proper syntax for super()?

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

Categories