9

Ken Arnold、James Gosling、David Holmes による「THE Java™ Programming Language, Fourth Edition」では、次のように述べられています。

パラグラフ:(4.3.2) 「同様に、インターフェイスが同じシグネチャを持つ複数のメソッドを継承する場合、またはクラスが同じシグネチャを持つメソッドを含む異なるインターフェイスを実装する場合、そのようなメソッドは1つだけです。このメソッドの実装最終的にはインターフェイスを実装するクラスによって定義され、あいまいさはありません. メソッドの署名が同じで戻り値の型が異なる場合、戻り値の型の 1 つが他のすべての型のサブタイプである必要があり、そうでない場合はコンパイル時エラーになります。実装では、共通のサブタイプを返すメソッドを定義する必要があります。」

上記の段落のポイントを正当化するサンプルコードを誰か教えてもらえますか?

私はコードを書き、言及されていることをテストしようとしましたが、サブインターフェースが基本インターフェースメソッドを隠しているため、サブインターフェースメソッドのみを実装できるコンパイル時エラーが発生しています。

前もって感謝します。-アルン

4

5 に答える 5

8
interface A {
    void method();
    Object returnMethod();
}
interface B {
    void method();
    B returnMethod();
}

class Impl implements A,B 
{
    void method() { }
    B returnMethod() { }
}

ご覧のとおり、と の両方をImpl.method()実装し、 whileは の子であるを返し、の契約も満たしています。後者は、 の戻り値の型の親ではない戻り値の型を必要とするでしょうか? そのような実装は には存在しないため、これはエラーになります。A.method()B.method()Impl.returnMethod()BObjectA.returnMethod()B.returnMethod()Impl

于 2009-05-18T13:01:42.197 に答える
2

次の 2 つのインターフェイスmethodA()は、パラメーター (none) と戻り値の型 (int) に関して同じように定義されています。下部の実装クラスは、この正確なシグネチャを持つ単一のメソッドを定義します。両方のインターフェースに準拠しているため、問題はありません。タイプ InterfaceA または InterfaceB の参照を介して行われた呼び出しは、この実装にディスパッチされます。

2 つ目は、 in の(またはそれ自体)methodB()の任意のサブタイプを返すものとして定義されています。のサブタイプである を返すと定義します。実装クラスは実際にメソッドを で実装するため、との両方の契約に準拠します。ここでも問題ありません。ただし、 a を返すように実装されているコメントアウトされたケースは機能しません。NumberNumberInterfaceAInterfaceBmethodB()IntegerNumberIntegerInterfaceAInterfaceBmethodB()DoubleInterfaceAInterfaceBInteger

InterfaceAとが(例ではコメントアウトされているInterfaceB) に対して (異なる) コントラクトを指定している場合、これは矛盾し、コンパイラ エラーが発生します。methodC()両方の署名 (戻り値の型のみが異なる) を実装することは、Java では許可されていません。

上記の規則は、メソッドにパラメーターを追加する場合にも当てはまります。簡単にするために、これを例から除外しました。

public interface InterfaceA {
    public int methodA();
    public Number methodB();
    // public int methodC(); // conflicting return type
}

public interface InterfaceB {
    public int methodA();
    public Integer methodB();
    // public String methodC(); // conflicting return type
}

public class ImplementationOfAandB implements InterfaceA, InterfaceB {
    public int methodA() {
        return 0;
    }
    public Integer methodB() {
        return null;
    }
    // This would NOT work:
    // public Double methodB() {
    //     return null;
    // }
}
于 2009-05-18T13:15:18.830 に答える
1
/**
 * This is what you have
 */
interface IXR {
        //bla-bla-bla
}

class CXR implements IXR {
        //concrete implementation of bla-bla-bla
}

interface IX {
        public IXR f();
} 

interface IYR {
        //some other bla-bla-bla
}

class CYR implements IYR {
        //concrete implementation of the some other bla-bla-bla
} 

interface IY {
        public IYR f();
}






/**
 * This is what you need to add
 */ 
interface IZR extends IXR, IYR {
        //EMPTY INTERFACE
}

class CZXR extends CXR implements IZR {
        //EMPTY CLASS
} 

class CZYR extends CYR implements IZR {
        //EMPTY CLASS
}

class CZ implements IX, IY
{
        public static boolean someCondition = true;

        public IXR implementationOf_X_f()
        {
                System.out.println("CXR");
                return new CZXR();
        }

        public IYR implementationOf_Y_f()
        {
                System.out.println("CYR");
                return new CZYR();
        }

        public IZR f() {
                if (someCondition) {
                        return (IZR) implementationOf_X_f();
                } else {
                        return (IZR) implementationOf_Y_f();
                }
        }

}






/**
 * This is the usage of the required class
 */
class program 
{ 
        public static void main(String[] x) {
                CZ o = new CZ();
                IZR r = o.f();
                if (CZ.someCondition) {
                        CXR xr = (CXR) r;
                        //bla-bla-bla
                } else {
                        CYR yr = (CYR) r;
                        //bla-bla-bla
                }
        }
} /**
 * This is what you have
 */
interface IXR {
        //bla-bla-bla
}

class CXR implements IXR {
        //concrete implementation of bla-bla-bla
}

interface IX {
        public IXR f();
} 

interface IYR {
        //some other bla-bla-bla
}

class CYR implements IYR {
        //concrete implementation of the some other bla-bla-bla
} 

interface IY {
        public IYR f();
}






/**
 * This is what you need to add
 */ 
interface IZR extends IXR, IYR {
        //EMPTY INTERFACE
}

class CZXR extends CXR implements IZR {
        //EMPTY CLASS
} 

class CZYR extends CYR implements IZR {
        //EMPTY CLASS
}

class CZ implements IX, IY
{
        public static boolean someCondition = true;

        public IXR implementationOf_X_f()
        {
                System.out.println("CXR");
                return new CZXR();
        }

        public IYR implementationOf_Y_f()
        {
                System.out.println("CYR");
                return new CZYR();
        }

        public IZR f() {
                if (someCondition) {
                        return (IZR) implementationOf_X_f();
                } else {
                        return (IZR) implementationOf_Y_f();
                }
        }

}






/**
 * This is the usage of the required class
 */
class program 
{ 
        public static void main(String[] x) {
                CZ o = new CZ();
                IZR r = o.f();
                if (CZ.someCondition) {
                        CXR xr = (CXR) r;
                        //bla-bla-bla
                } else {
                        CYR yr = (CYR) r;
                        //bla-bla-bla
                }
        }
}
于 2011-09-07T11:48:02.183 に答える
1
interface A
{
   void foo();
   //int bar(); <-- conflicts with B.bar() because of different return type
}

interface B
{
   void foo();
   //double bar(); <-- conflicts with A.bar() because of different return type
}

class C implements A, B
{
   void foo() // this implements A.foo() AND B.foo()
   {
      ...
   }
}
于 2009-05-18T13:01:10.420 に答える