2

私の質問が奇妙に聞こえたらごめんなさい笑私は説明しようとします。Karakter、Karakters、Orc、Humanの4つのクラスがあります。OrcとHumanはどちらもKarakterを拡張します。Karaktersは、Karakterを含むArrayListです。

OrcとHumanの両方にpublicStringgetRace()というメソッドがあります。Karaktersでこのメソッドを使用したいですか?!! 私がこれをやろうとすると、オークとヒューマンがカラクターではなくカラクターを拡張するので失敗します!これを行う方法はありますか?何か抽象的なものを作ることについて何か聞いた:P

ありがとう

4

6 に答える 6

5

getRace()でメソッドを宣言しますKarakter(英語のスペルは「文字」ですが、ここにもそこにもありません)。

Karaktersタイプのオブジェクトを処理していることだけを知っているのでKarakter、両方の実装にgetRaceメソッドがあることを知ることはできません。基本クラスでメソッドを宣言すると、この問題が解決します。

次のようになります。

public abstract String getRace();

そして、Karakterクラスも作成する必要がありabstractます。

于 2009-11-12T16:57:48.053 に答える
3

電話をかけるとどうなると思いますKarakters.getRace()か?

KaraktersはArrayListgetRace(int position)なので、関心のある人の人種を見つけることができるように、メソッドを用意してみませんか。

配列の競合を取得することがどのように意味があるのか​​わかりません。

于 2009-11-12T16:58:07.133 に答える
2

これは本当に意味がありません。ArrayListがある場合は、getRace()各要素を呼び出すことができます。

class Karakters {
    ArrayList<Karakter> kars = new ArrayList<Karakter> ();
    public String getRace () {
        for (Karakter k: kars) {
            ... uh ... which one to return?
        }
        return null; // List is empty
    }
}
于 2009-11-12T16:58:21.673 に答える
1

OrcまたはHumanで定義されたgetRace()を呼び出すには、OrcまたはHumanのオブジェクトまたはその派生クラスの1つが必要です(メソッドがベースでプライベートでない場合)。もちろん、getRace()がpublic staticの場合は、クラス名を使用してどこからでも呼び出すことができます。

于 2009-11-12T16:57:28.270 に答える
1

実行時に具体的なタイプをテストしKarakter、適切なサブタイプにキャストできます。

for(Karakter k : karakters) {
   if (k instanceof Orc) {
       ((Ork)k).getRace();
   } else if (k instanceof Human) {
       ((Human)k).getRace();
   }
}

また、がを持っていることが理にかなっている場合は、メソッドをにプッシュできるように見えます。getRace()KarakterKaraktergetRace()

class/interface Karakter {
   abstract String getRace();
}

たとえば、をKarakter持たないgetRace()別のタイプがある場合、追加のインターフェイスを使用して抽象化することができます。Alien extends KaraktergetRace()

public interface IRacer {
    abstract String getRace();
}

public class Human extends Karakter implements IRacer { ... }
public class Orc extends Karakter implements IRacer { ... }

このようにして、次のことができます。

for(Karakter k : karakters) {
   if (k instanceof IRacer) {
       ((IRacer)k).getRace();
   }
}

class Karaktersまた、それはあなたの拡張のように見えますArrayList。しないでください。継承よりもコンポジションを優先し、常にジェネリックバージョンのを使用しArrayList<Karakter>ます。

于 2009-11-12T17:04:07.090 に答える
1

現在のクラスからアクセスできる限り、そのメソッドを実装するオブジェクトでメソッドを呼び出すことができます。特に、メソッドはパブリックであるため、適切なインスタンスがあるか、getRaceメソッドを呼び出す限り、どのクラスでもメソッドを呼び出すことができます。OrcHuman

私はあなたのこだわりはKarakter、オークや人間ではなく、sのリストを持っていることだと思います。したがってKarakters、その時点でオブジェクトがであることがわかるだけなので、クラス/インターフェイスKarakterで定義されたメソッドのみを呼び出すことができます。Karakter

1つの解決策は、クラスにもgetRaceメソッドを追加することです。Karakterこれがスーパークラスの値を返すことが意味をなさない場合は、スーパークラスを抽象化して(つまり、そのインスタンスを直接構築することはできず、そのサブクラスの1つしか構築できません)、メソッドを宣言できます。抽象化Karakter

public abstract class Karakter
{
    /*
     ...
     ... Same as before
     ...
     */

     public abstract String getRace();
}

これにより、サブクラスにの実装が強制されgetRace(とにかく、ここでは問題になりません)、オブジェクトの種類に関係なく、呼び出すgetRace()メソッドがあることを確認Karaktersできます。Karakter

これは、私があなたの意図を理解していることに基づいた、ソリューションへの1つのアプローチにすぎません。ただし、根本的な問題は、Karakterクラスがを定義していないため、そのタイプの参照でメソッドを直接getRace呼び出すことができないことです。

于 2009-11-12T17:14:40.577 に答える