1

重複の可能性:
インターフェースと抽象クラス(一般的なOO)

MSDNの記事の1つで、次の行が言及されています

インターフェースはそれ以降のバージョンで新しいメンバーを指定できませんが、抽象クラスは追加機能をサポートするために必要に応じてメンバーを追加できます。

ここからこの文を選びました。段落3で同じ文を読むことができます。

何かが足りない場合に備えて、事前に申し訳ありませんが、混乱があります。

Abstaractクラスまたはインターフェイスが宣言され、派生クラスがメソッドを継承すると、いずれの場合も、すべてのメソッドがオーバーライドされる必要があります。そうしないと、コンパイルエラーが発生します。

あなたのコメント?

4

4 に答える 4

4

Abstaractクラスまたはインターフェイスが宣言され、派生クラスがメソッドを継承すると、いずれの場合も、すべてのメソッドがオーバーライドされる必要があります。そうしないと、コンパイルエラーが発生します。

いいえ、抽象クラスの場合、オーバーライドする必要があるのは抽象メソッドのみです。エラーなしで非抽象メソッドを追加できます。

たとえば、バージョン1:

public abstract class FooBase
{
    public abstract void Bar();    
}

public class FooImpl : FooBase
{
    public override void Bar() {}
}

次に、バージョン2の新しい非抽象メソッドを導入します。FooBase

public abstract class FooBase
{
    public abstract void Bar();   

    public void NewMethod() {}
}

...そして問題はありません。

APIを使用するすべてのコードが同時に再構築される会社の内部コードの場合、これは多くの場合、インターフェイスまたは抽象クラスのいずれかでまったく問題にならないことに注意してください。インターフェイスにメソッドを追加する場合は、すべての実装を同時にアップグレードできるため、追加できます。

注意が必要なのは、コードベース全体を制御できない場合です。

于 2012-11-28T17:52:18.193 に答える
1

インターフェイスを実装するクラスは、インターフェイスで定義されたすべてのメソッドとプロパティを実装する必要があります。

抽象クラスから継承する場合は、すべての抽象メンバーを実装/オーバーライドする必要がありますが、非抽象メンバーは、具象クラスから継承する場合と同じように継承されます。

于 2012-11-28T17:54:43.570 に答える
0

インターフェイスから継承する場合は、そのインターフェイスのすべてのメンバーを実装する必要があります。ただし、適切と思われる場合は、インターフェイスを拡張できます。複数のインターフェースを継承することもできます。有効な例:

public interface IPerson
{
    string FullName { get; set; }
    string SSN { get; set; }
}

public interface IPersonDBContext
{
    void Save(IPerson person);
}

public class PersonData : IPerson, IPersonDBContext
{
    // Implements IPerson FullName
    public string FullName { get; set; }

    // Implements IPerson SSN
    public string SSN { get; set; }

    // Implements IPersonDBContext Save()
    public void Save(IPerson person)
    {
        // Code to save the IPerson instance to the DB...
    }

    // Added method, not included in any interface...
    public void Validate(IPerson person)
    {
        // Code to validate the IPerson instance...
    }
}

これで、抽象クラスの場合、継承できる具体的なメソッドを含めることができますが、オーバーライドする必要のあるいくつかのメソッドを指定することもできます。ただし、複数の基本クラスを持つことはできないことに注意してください(抽象クラ​​スは引き続きクラスです...)。したがって、インターフェイスのように2つの抽象クラスを混在させることはできません。例:

public abstract class Person
{
    public string FullName { get; set; }
    public string SSN { get; set; }

    public abstract void Save();
}

public class PersonData : Person
{
    // Implements Abstract Person Save() Method
    public override void Save()
    {
        // Save logic here...
    }

    // Non-inherited member...
    public void Validate()
    {
        // Access properties of the base class (Abstract Person)
        this.FullName.ToString();
        this.SSN.ToString();
    }
}

最後に、そして最も強力なことに、単一の抽象基本クラスを必要な数のインターフェースと組み合わせることができます...したがって、例2の抽象クラスPersonと例1のインターフェースIPersonDBContextを保持すると、これを行うことができます。 :

public class PersonData : Person, IPersonDBContext
{
    // Implements Abstract Person Save() Method
    public override void Validate()
    {
        // Access properties of the base class (Abstract Person)
        this.FullName.ToString();
        this.SSN.ToString();
    }

    // Inplmenets IPersonDBContext Save()
    public void Save(Person person)
    {
        // Save logic here...
    }

    // Non-inhereted method
    public void Clone(Person person)
    {
        // Logic to make a member-wise clone.
    }
}

お役に立てば幸いです...

于 2012-11-28T18:17:58.693 に答える
0

インターフェイスを実装すると、そのメソッドをオーバーライドする必要があります。ただし、クラスを継承すると、選択肢が得られます。オーバーライドする必要があるのは抽象メソッドのみです。MSDNの抜粋は、厳密なインターフェイスコントラクトの価格は、すべての実装者が追加されたメソッドを実装する必要があるときに、後で高額になる可能性があることを指摘しています。仮想メソッドでクラスの親を使用すると、後で特殊化が必要かどうかを判断できます。

于 2012-11-28T18:08:21.597 に答える