简体   繁体   English

在数组中创建子类对象,在java中使用哪种类型的超类

[英]Creating subclass object in an array which type of superclass in java

I'm trying to cover OOP stuffs but I stuck here. 我试图覆盖OOP的东西,但我卡在这里。 I get error in Company class, employees[0].setBonus(50) part. 我在公司类中遇到错误,员工[0] .setBonus(50)部分。 Isn't there any other way to solve it except defining Bonus methods in Employee class? 除了在Employee类中定义Bonus方法之外,没有其他方法可以解决它吗? 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? 我定义了奖励方法,但还有另一件事,我必须在Empoyee类'getBonus方法中返回什么?


   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. 我糊涂了。

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. 从功能上讲,如果奖金是仅拥有Manager实例的属性,则Employee实例不应尝试设置或获取它。

When you do : 当你这样做时:

 employees[0].setBonus(50);

the compiler doesn't know the concrete instance. 编译器不知道具体的实例。 It sees only Employee . 它只看到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());    
    }

If you really want do it this way, you can cast employee[0] as manager, but You must know is not nice solution. 如果你真的想这样做,你可以将员工[0]作为经理,但你必须知道这不是一个好的解决方案。 Eg: 例如:

    Company company= new Company();
    Manager manager = Manager.class.cast(employees[0]);
    manager.setBonus(50);
    System.out.println(manager.getBonus());

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. 那里有一组Employee对象。 It doesn't matter that your code at run time will put a Manager object into that array! 运行时的代码将Manager对象放入该数组并不重要! The compiler doesn't know that. 编译器不知道这一点。 He only knows that there is an Employee. 他只知道有一个员工。

And the Employee class has no method setBonus() . 而Employee类没有方法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; 一种可能的解决方案是例如将奖金作为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: 笔记:

  • You should avoid to use fields of your super class; 你应该避免使用超类的字段; those are private implementation details of that class. 这些是该类的私有实现细节。 Child classes should not care about them. 儿童类应该关心他们。 Instead, you could call the method from the super class. 相反,您可以从超类中调用该方法。
  • On the other hand, you should strive for making your fields final . 另一方面,你应该努力使你的领域最终 That makes a lot of things much easier. 这使得很多事情变得更容易。
  • When overriding methods ... use the @Override annotation! 覆盖方法时......使用@Override注释!

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. 然后你只需传递给你的Company构造函数。 You want to clearly separate your "real business logic" from that stuff that mainly exists to test that "business logic". 您希望将“真实业务逻辑”与主要用于测试 “业务逻辑”的内容明确区分开来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM