Reputation: 427
I'm trying to cover OOP stuffs but I stuck here. I get error in Company class, employees[0].setBonus(50) part. Isn't there any other way to solve it except defining Bonus methods in Employee class? Or is there anyway to keep all objects in one array? I defined bonus methods but there was another thing, what I have to return in Empoyee class' getBonus method?
public class Company
{
private static Employee[] employees;
public Company()
{
employees= new Employee[]{new Manager("Sapo",10000),new Employee("James",5000),new Employee("Jessie",5001)};
}
public static void main(String[] args)
{
Company company= new Company();
employees[0].setBonus(50);
System.out.println(employees[0].getBonus());
}
}
public class Employee extends Person
{
int salary;
public Employee(String name,int salary) {
super(name);
setSalary(salary);
// TODO Auto-generated constructor stub
}
public void setSalary(int salary)
{
this.salary= salary;
}
public int getSalary()
{
return salary;
}
}
public class Manager extends Employee
{
private int bonus;
public Manager(String name, int salary) {
super(name, maas);
}
public void setBonus(int bns)
{
bonus=bns;
}
public int getBonus()
{
return bonus;
}
public int getSalary()
{
return salary+bonus;
}
}
I'm confused.
Upvotes: 3
Views: 1765
Reputation: 1740
If you really want do it this way, you can cast employee[0] as manager, but You must know is not nice solution. E.g:
Company company= new Company();
Manager manager = Manager.class.cast(employees[0]);
manager.setBonus(50);
System.out.println(manager.getBonus());
Upvotes: 3
Reputation: 131346
Or is there anyway to keep all objects in one array?
You could but it would force you to write :
if ( employees[0] instanceof Manager){
((Manager) employees[0]).setBonus(50);
}
which is not a good practice.
Functionally, if a bonus is a property which owns only the Manager
instances, an Employee
instance should not try to set or get it.
When you do :
employees[0].setBonus(50);
the compiler doesn't know the concrete instance. It sees only Employee
.
In this very simple code, we see straight that the first employee is a manager but in a real application the array may be modified multiple times. Trying to remember at which indexes are the managers is error prone. If you need to call a manager specific method on a or several managers you should be sure about knowing which variables are managers. So declaring them as manager seems the more natural way.
To solve your problem, two arrays seems more interesting : one for employees and another for managers :
private static Employee[] employees;
private static Manager[] managers;
Now you can do :
public Company()
{
employees= new Employee[]{new Employee("James",5000),new Employee("Jessie",5001)};
managers= new Employee[]{new Manager("Sapo",10000)};
}
public static void main(String[] args){
Company company= new Company();
managers[0].setBonus(50);
System.out.println(managers[0].getBonus());
}
Upvotes: 2
Reputation: 140427
Your abstraction is wrong. You see, the compiler only has that information that is available at compile time.
You have an array of Employee objects there. It doesn't matter that your code at run time will put a Manager object into that array! The compiler doesn't know that. He only knows that there is an Employee.
And the Employee class has no method setBonus()
. Thus you can't call that method!
One possible solution would be for example to make the bonus a parameter to the constructor of Manager; the whole think could look like this:
public class Manager extends Employee {
private final int bonus;
public Manager(String name, int salary, int bonus) {
super(name, salary);
this.bonus = bonus;
}
@Override
int getSalary() {
return super.getSalary() + bonus;
}
Notes:
Finally: a constructor is a bad place to create your "test data". In other words: your main method is to place to create that array of employees; and then you just pass that into your Company constructor. You want to clearly separate your "real business logic" from that stuff that mainly exists to test that "business logic".
Upvotes: 1