0

私の理解では、Java のすべてのクラスは Object スーパークラスの子です。したがって、コンパイラが次のコードのエラーを表示するのはなぜですか。

public class ClassA {
   public ClassA(){}
   public String exampleMethod(String str){
      //manipulate string
      return str;
   }
}

public class ClassB {
   public ClassB(){}
   public String exampleMethod(String str){
      //manipulate string
      return str;
   }
}

public class Manager {
   public Manager(){
      execute(new ClassA());
      execute(new ClassB());
   }
   public void execute(Object o){
      o.exampleMethod("test");
   }
}

ClassA が Object の子である場合、'o' 変数からメソッドを呼び出せないのはなぜですか? ClassA と ClassB をスーパークラスの下に置くことができることはわかっていますが、これが失敗する理由を知りたいです。

4

4 に答える 4

5

Objectクラスはメソッドを定義していないためexampleMethod、エラーが発生します。コードを実行するには、少なくとも oClassAまたはClassBクラスのダウンキャストを行う必要があります。

public void execute(Object o) {
    //this makes the code compiles
    ((ClassA)o).exampleMethod("test");
}

それでも、このダウンキャストを行う前に、oパラメーターがClassAorインスタンスであることを確認する必要があります。そうしないと、例外に遭遇する可能性があります。これは、次を使用して実現できます。ClassBClassCastExceptioninstanceof

public void execute(Object o) {
    //this makes the code compiles
    //and assures that you won't have a ClassCastException
    if (o instanceof ClassA) {
        ((A)o).exampleMethod("test");
    }
    if (o instanceof ClassB) {
        ((B)o).exampleMethod("test");
    }
}

それでも、これはかなり不器用です。ClassAandClassBクラスは同じシグネチャ (同じ名前、同じパラメーター、同じ戻り値の型) を持つメソッドを共有するため、このメソッドと make およびクラスを持つインターフェイスを使用して、それClassAClassB実装できます。例えば:

interface IExample {
    String exampleMethod(String str);
}
public class ClassA implements IExample {
    //current implementation...
}
public class ClassB implements IExample {
    //current implementation...
}

次に、クラスのコードを次のように短縮できます。Manager

public void execute(Object o) {
    if (o instanceof IExample) {
        ((IExample)o).exampleMethod("test");
    }
}

またはさらに良い:

public void execute(IExample o) {
    o.exampleMethod("test");
}

ClassAこのようにして、またはのインスタンスClassBをメソッドに渡すことができexecute、各クラスが に与えた実装に応じて動作しexampleMethodます。

于 2013-06-17T06:29:29.827 に答える
1

実際、いくつかの緩い型付き言語では、あなたのアプローチはうまくいきます。execute()Java では、メソッドを次のように変更する必要があります。

public class Manager {
    ...
    public void execute(Object o){
            if (o instanceof ClassA) {
                ((ClassA) o).exampleMethod("test");
            } else if (o instanceof ClassB) {
                ((ClassB) o).exampleMethod("test");
            }
    }
}
于 2013-06-17T06:35:59.227 に答える
0

Objectクラスには と呼ばれるメソッドがないため、アプローチは失敗しますexampleMethod()

メソッドにegを与えるとどうなりますNumberか?

于 2013-06-17T06:30:08.093 に答える
0

オブジェクトを A/B にキャストしない限り。参照は Object クラスのままで、 Object クラスには exampleMethod(String str) というメソッドは含まれません。したがって、exampleMethod を実装したクラスにキャストする必要があります。次のようなことができます:

public void execute(Object o) {

    if (o instanceof A) {
        ((A)o).exampleMethod("test");
    }
    if (o instanceof B) {
        ((B)o).exampleMethod("test");
    }
}
于 2013-06-17T06:33:10.593 に答える