2

クラスのインスタンスを作成してこれを配列リストに追加しようとすると、子で定義されたメソッドを呼び出すことができません。

これを機能させるにはどうすればよいですか?

リストクラス

import java.util.*;
public class List {
  private ArrayList<Person> persons;
  public List(){
    persons = new ArrayList<Person>();
  }
  public void addAssistant(){
    Person person = new Assistant();
    persons.add(person);
    if(person instanceof Assistant){
      person.assist();
    }
  }
}

人物クラス

public class Person {
  public Person(){}
}

アシスタントクラス

public class Assistant extends Person {
  public Assistant(){}
  public void assist(){
     System.out.println("I am assisting!");
  }
}

コンパイラ:行:person.assist(); ListクラスのaddAssistant()メソッド内。

コンパイラエラー:コンパイラがシンボルを見つけることができません-メソッドassist()。

4

6 に答える 6

8

明示的なキャストが必要です。

if(person instanceof Assistant){
  ((Assistant)person).assist();
}

ただし、このタイプのロジックは一般的に推奨されるべきではないと思います。

于 2012-12-20T14:49:28.967 に答える
1

私はそれをこのようにコーディングします

public void addAssistant(){
    Assistant assistant = new Assistant();
    assistant.add(person);
    assistant.assist();
}

最近作成したオブジェクトが実際にはアシスタントであるという知識から自分自身を抽象化しても意味がありません。

具体的なタイプから自分自身を抽象化することは、2つのコード間の結合を減らす良い方法であり、ポリモーフィズムのような素晴らしいことを行うために必要です...しかし、この特定の例では、アシスタントにすでに緊密に結合されていることを示しています(実際、2行上でインスタンス化しています)。

これを実装する別の可能な方法は、ポリモーフィズムを使用することです。これは、Personのインターフェイスにassist()メソッドを追加することで実行できます。

public class Person {
  public Person(){}

  public void assist() {
     //I'm a just a person who doesn't assist anywhere
  }
}

そうすることで、あなたはあなたがしようとしていたことをすることができるようになります:

public void addAssistant(){
    Person person = new Assistant();
    persons.add(person);
    person.assist();     
}

ただし、これはお勧めしません。主な理由は、Personインターフェイスに正しく配置されていない責任を課し始めるためです。それはすべて設計の問題であり、特定の問題に対してより良い(そしてもちろん最も快適な)解決策を選択する必要があります。

幸運のクラウディオ

于 2012-12-20T15:23:03.557 に答える
1

Person次のようにキャストする必要がありますAssistant

if(person instanceof Assistant){
  ((Assistant)person).assist();
}

ただし、このタイプのキャストは、アプリケーション設計に欠陥があることを示していると思います。

補足:

具体的な実装ではなく、インターフェイスを使用する必要があります。したがって、これを置き換える必要があります:

private ArrayList<Person> persons;

これとともに:

private List<Person> persons;

Persons に特定の作業を実行させたい場合、およびAssistants の作業が支援している場合は、抽象メソッドを作成することでこれを回避できますPerson

public abstract void doYourWork();

そして、あなたはそれを実装することができますAssistant:

@Override
public void doYourWork(){
    // doing something
}

この場合、Personオブジェクトを明示的にキャストする必要はありません。

Person に具体的な実装がない場合は、代わりにインターフェイスにすることができます。

于 2012-12-20T14:50:19.497 に答える
1

サブクラス メソッドを使用するにはキャストを作成する必要があります

if(person instanceof Assistant){
  ((Assistant)person).assist();
}
于 2012-12-20T14:50:40.777 に答える
1

Person クラスにはアシスト メソッドが定義されていないため、明示的に Assistant クラスにキャストする必要があります。

if(person instanceof Assistant){
  ((Assistant)person).assist();
}
于 2012-12-20T14:51:59.233 に答える
0

言語が設計された方法Javaでは、これはコンパイルされません (同様に理解したように)。すべてのアシスタントは人ですが、すべての人がアシスタントであるとは限りません。明示的なキャストを使用すると、達成したいことを実行できます(NPEが彼の回答で述べたように)。

于 2012-12-20T14:51:00.783 に答える