私はそれにいくつかのメソッドを持つインターフェースを持っています。
_interface IMyInterface
{
//...
void OnItemClicked()
//...
}
_
そして実装
_class MyClass : IMyInterface
{
//Other methods
public void OnItemClicked(){ /*...*/ }
}
_
ここで、OnItemClicked()
以外はMyClass
のように動作するクラスが必要です。このメソッドにいくつかの変更を加えます。
オーバーライドを継承することを考えましたが、MyClass
を変更したくありません(例:public virtual
void OnItemClicked()...)。実装、
OnItemClicked()は変更するMyClassの唯一の部分であるため、再度IMyInterface
を実装したくありません。
他に方法はありますか?
あなたがインターフェースを実装しているので、多態性はおそらくあなたが保持したいものです。基本クラスを仮想で変更せずにメソッドをオーバーライドすることは不可能であるため、Tigranが書いたように、仮想の代わりにnewを使用する必要があります。
つまり、この種のコードを記述しても、メソッドの基本バージョンのみが実行されます。
List<MyClass> aList = new List<MyClass>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (MyClass anItem in aList)
anItem.OnItemClicked();
適切なコードを実行するには、次のような醜いコードを書く必要があります。
List<MyClass> aList = new List<MyClass>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (MyClass anItem in aList)
{
MyNewClass castItem = anItem as MyNewClass;
if (castItem != null)
castItem.OnItemClicked();
else
anItem.OnItemClicked();
}
とにかく、IMyInterfaceとして宣言された変数に割り当てられたときに、クラスが適切なメソッドを実行する方法があります。先に進むには、オーバーライドするインターフェイスの部分を明示的に実装します。この場合はOnItemClickedメソッドです。コードは次のとおりです。
public class MyNewClass : MyClass, IMyInterface // you MUST explicitly say that your class implements the interface, even if it's derived from MyClass
{
public new void OnItemClicked() //NEW keyword here you have the overridden stuff
{
/*...*/
}
void IMyInterface.OnItemClicked() // No need for public here (all interfaces's methods must be public)
{
this.OnItemClicked();
}
}
この方法では:
MyClass cl = new MyNewClass();
cl.OnItemClicked();
基本メソッドを実行します
MyNewClass cl = new MyNewClass();
cl.OnItemClicked();
派生クラスのメソッドを実行します
IMyInterface cl = new MyNewClass();
cl.OnItemClicked();
派生クラスのメソッドを実行し、実行時にバインドされます。つまり、私の最初の例のコードを次のように記述し、適切なメソッドを実行させることができます。
List<IMyInterface> aList = new List<IMyInterface>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (IMyInterface anItem in aList)
anItem.OnItemClicked();
MyClass
から派生できます
public class MyNewClass : MyClass
{
public new void OnItemClicked(){ /*...*/ } //NEW keyword
}
唯一のことは、この方法で多態性をサポートしないことに注意してください。
より明確にするために:
MyClass cl = new MyNewClass();
cl. MyMethod();
realオブジェクトタイプがMyClass
であっても、これはMyNewType
メソッドを呼び出します。私たちが望むものを呼び出すことができるようにするには、型を明示的に定義する必要があります
MyNewClass cl = new MyNewClass();
cl. MyMethod(); //WILL CALL METHOD WE WANT
最も簡単な方法は、「has-a」を使用して「is-a」を模倣する新しいクラスを作成することです。
public interface IMyInterface
{
void OnItemClicked();
void OnItemHover();
void OnItemDoubleClicked();
}
public class MyNewClass : IMyInterface
{
private IMyInterface _target;
public MyNewClass(IMyInterface target)
{
_target = target;
}
public void OnItemClicked()
{
// custom functionality
}
public void OnItemHover()
{
_target.OnItemHover();
}
public void OnItemDoubleClicked()
{
_target.OnItemDoubleClicked();
}
}
パターンブリッジを使用 http://en.wikipedia.org/wiki/Bridge_pattern