上記のタイプを考えると、anExpressionOfTypeSubClassOrIClass.implementedMethod()
使用する必要があります。式のType (それが提供するビュー)には、使用するメソッドが含まれている必要があることに注意してください。この場合、SuperClass 型の式は、宣言されたimplementedMethod
メンバーがないため、ここでは使用できません。
アプローチの 1 つ (おそらく推奨されるアプローチ) は、抽象メソッドを使用することです。抽象メソッドはポリモーフィズムに厳密には必要ありませんが、サブクラスが実装を提供する必要があるこのようなシナリオを説明しています。(抽象メソッドは、サブクラスでオーバーライドされることを期待しているが必須ではない空のメソッドに置き換えることができますがabstract
、設計された目的のために使用しないのはなぜですか?)
abstract class SuperClass implements IClass {
// Don't implement this, but declare it abstract
// so that we can conform to IClass as well
public abstract void implementedMethod();
public void method () {
// Now this object (which conforms to IClass) has implementedMethod
// which will be implemented by a concrete subclass.
implementedMethod();
}
}
これには、SuperClass を直接インスタンス化できない (結局のところ抽象的である) という「否定的な」側面があり、SuperClass は期待される署名を実装する (または、示されているように、abstract を介してデリゲートする) 必要があります。この場合、SuperClass とすべてのサブクラスを IClass として表示できることが保証されるため、厳密には必須ではありませんが、SuperClass に IClass を実装することも選択しました。
または、式のタイプはオブジェクトの単なるビューであり、オブジェクトの実際の具体的なタイプと必ずしも同じではないことに注意してください。次のコードを使用すると型安全性が失われるため、使用しないことをお勧めしますが、重要な点を示していると思います。
class SuperClass {
public void method () {
// We try to cast and NARROW the type to a
// specific "view". This can fail which is one
// reason why it's not usually appropriate.
((IClass)this).implementedMethod();
}
}
class SubClass extends SuperClass implements IClass {
// ..
}
class BrokenSubClass extends SuperClass () {
}
// OK! Although it is the SAME OBJECT, the SuperClass
// method can "view" the current instance (this) as an IClass
// because SubClass implements IClass. This view must be
// explicitly request through a cast because SuperClass itself
// does not implement IClass or have a suitable method to override.
(new SubClass()).method();
// BAD! ClassCastException, BrokenSubClass cannot be "viewed" as IClass!
// But we didn't know until runtime due to lost type-safety.
(new BrokenSubClass()).method();