2016-12-15 10 views
3

私はOOPのものをカバーしようとしていますが、私はここで取り残しました。私はCompanyクラスの従業員[0] .setBonus(50)の部分にエラーが発生します。従業員クラスのボーナスメソッドを定義する以外の方法はありませんか?または、すべてのオブジェクトを1つの配列に保持するにはどうしてですか?私はボーナスメソッドを定義しましたが、別のものがありました。私はEmpoyeeクラスのgetBonusメソッドで何を返さなければなりませんか?Javaのスーパークラスの型の配列にサブクラスオブジェクトを作成する


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

私は混乱しています。

+0

可能な重複(http://stackoverflow.com/questions/10021603/calling-a-subclass-method-from-superclass) – shmosel

答えて

2

また、すべてのオブジェクトを1つの配列に保持する方法はありますか?

あなたはそれが書くためにあなたを強制することができます:良い習慣ではありません

if (employees[0] instanceof Manager){ 
    ((Manager) employees[0]).setBonus(50); 
} 

機能的には、ボーナスがManagerインスタンスのみを所有するプロパティである場合、Employeeインスタンスはそれを設定または取得しようとすべきではありません。

employees[0].setBonus(50); 

コンパイラは、具体的なインスタンスを知らない:あなたはない

。表示されるのはEmployeeのみです。 この非常に単純なコードでは、最初の従業員はマネージャですが、実際のアプリケーションでは配列は複数回変更される可能性があります。どのインデックスがマネージャであるかを覚えようとすると、エラーが発生しやすくなります。あるマネージャまたは複数のマネージャでマネージャ固有のメソッドを呼び出す必要がある場合は、どの変数がマネージャであるかを確認する必要があります。だからマネージャーとして彼らを宣言するのがもっと自然な方法だと思う。

はあなたの問題を解決するために、2つの配列がより興味深いようだ:管理者のための従業員用と別:
private static Employee[] employees; 

private static Manager[] managers; 

今すぐあなたが行うことができます:

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

あなたの抽象化が間違っています。コンパイラはコンパイル時間ので利用可能な情報しか持っていません。

あなたはの従業員というオブジェクトを配列しています。 の実行時間のコードが、その配列にManagerオブジェクトを配置することは重要ではありません!コンパイラはそれを知らない。彼は従業員がいることだけを知っています。

そして、従業員クラスはなしメソッドsetBonus()を持っています。したがって、あなたはそのメソッドを呼び出すことはできません!

たとえば、ボーナスをマネージャのコンストラクタのパラメータにすることが考えられます。全体と思うが、このようになります。

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

注:あなたががあなたのスーパークラスのフィールドを使用することは避けるべき

  • 。それらはプライベートそのクラスの実装の詳細です。子供のクラスはではなく、が気になるはずです。代わりに、スーパークラスからメソッドを呼び出すことができます。
  • 一方、フィールドを作成するために努力する必要があります最終。それは多くのことをはるかに簡単にします。
  • をオーバーライドする場合メソッド... @Overrideアノテーションを使用してください!

最後に、コンストラクタがの "テストデータ"を作成するためのの不良です。つまり、主な方法は、その従業員の配列を作成する場所です。次ににあなたの会社のコンストラクタに渡してください。あなたは、 "ビジネスロジック"を明確に区別するために、主に存在するものから、のテストに "ビジネスロジック"を指定します。

2

本当にこのようにしたい場合は、employee [0]をマネージャーとしてキャストすることができますが、知っておくといい解決法ではありません。例えば:[スーパークラスからサブクラスのメソッドを呼び出す]の

Company company= new Company(); 
    Manager manager = Manager.class.cast(employees[0]); 
    manager.setBonus(50); 
    System.out.println(manager.getBonus()); 
関連する問題