2012-09-07 7 views
13

私はいくつかのメソッドを持つインタフェースを持っています。インタフェースで宣言されたオーバーライドメソッドの実装

interface IMyInterface 
{ 
    //... 
    void OnItemClicked() 
    //... 
} 

と実装今

class MyClass : IMyInterface 
{ 
    //Other methods 
    public void OnItemClicked(){ /*...*/ } 
} 

、私はこの方法のためにいくつかの変更をしたい、OnItemClicked()のを除いてMyClassように振る舞うクラスを持っていると思います。

私がオーバーライドを継承すると思ったが、私はMyClass変更したくない:私はしたくないのではない私の実装であるため(のようなOnItemClicked公共virtualボイド()...)、

OnItemClicked()が変更するMyClassの唯一の部分であるため、IMyInterfaceを再度実装します。

他の方法がありますか?あなたはMyClass

public class MyNewClass : MyClass 
{ 
    public new void OnItemClicked(){ /*...*/ } //NEW keyword 
} 

から唯一のものを引き出すことができ

+0

これらの2つの中間クラスを作成します。 –

答えて

15

インターフェイスを実装しているので、多態性はおそらくあなたが保持したいものです。基本クラスを仮想で修正せずにメソッドをオーバーライドすることは不可能です。したがって、Tigranが書いたように、仮想クラスではなく新しいクラスを使用する必要があります。

これは、この種のコードが、メソッドの唯一のベースバージョンを書くことが実行されることを意味します

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(); 
5

、このようにあなたが多型をsupprotていないことに注意を払います。

より明確にするために:

 MyClass cl = new MyNewClass(); 
    cl. MyMethod(); 

これは本当オブジェクトタイプがMyNewType場合でも、MyClassメソッドを呼び出します。 は、我々が望むものを呼び出すことができるようにするために、我々はesplicitlyタイプ

 MyNewClass cl = new MyNewClass(); 
    cl. MyMethod(); //WILL CALL METHOD WE WANT 
+0

彼は彼の記事で述べました:私はオーバーライドを継承すると思ったが、MyClass(私の実装ではないので、public仮想void OnItemClicked()など)を変更したくない: –

+0

@ armen.shimoon:しなかった。 MyClassの実装を変更するコードはどこにありますか? – Tigran

+0

私の悪いTigran。私はコードを見て、あなたが "新しい"の代わりに "オーバーライド"を持っていると思った。質問:MyNewClassを "IMyInterface"のインスタンスとして使用する場合、どのメソッドが呼び出されますか? –

3

が最も簡単な方法は、「-さ」「い使用して模倣新しいクラスを作成することです定義する必要があります-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(); 
    } 
} 
+0

いいえ、これをMyClass変数に割り当てることはできません –

+0

はい、答えにMyClass変数を代入してOnItemClicked()を呼び出すと、間違った関数。私はインターフェイスが重要な部分であると想定していました。そうでないと正しく動作しませんでしたが、どちらも他の答えになりませんでした。 –

+0

あなたは正しいです、実際に、私はあなたの答えを他の人に好む、私はちょうどあなたの答えを好む理由を指摘していました:-) –

関連する問題