2012-09-03 7 views
29

抽象クラスとプロパティで実際に使用するかどうか、抽象クラス以外のプロパティをいつ使用するのかよくわかりません。私は簡単な例を作ろうとします。私はこれを持っているとしましょう:抽象的なプロパティを使用する時期と使用しない時期はわかりません

abstract class Human 
{ 
    public GenderType Gender { get; set; } 
    public string Name { get; set; } 
    public Date Born { get; set; } 
    public bool IsNerd { get; set; } 

    abstract public void Speak(); 
    abstract public void Sleep(); 
    abstract public void AnoyingPeopleOnStackOverflow(); 
    //... so on 
} 

class Peter : Human 
{ 
    //Peter is special, he got a second name 
    //But thats all, everything else is the same as like on other humans 
    public string SecondName { get; set; } 

    //...override abstract stuff 
} 

これは問題ありませんか?私が理解しているように、私は抽象プロパティを使用する必要はありません私はそれをオーバーライドしたくない場合。そしてこの状況では、それは大丈夫でしょう。ちょうどSpeakSleepのようなメソッドは抽象的でなければなりません。

これが正常であれば、いつ抽象的なプロパティを使用するのか、それとも使用する必要がありますか?

+1

「抽象的なプロパティを使用するかどうか」---子クラスが特定のメソッド実装を提供する必要があることをアサーションするとき – zerkms

+1

1)これがJavaの場合、おそらく問題はありません。あなたはおそらく単に "インターフェイス"を使用するでしょう。それは本質的にC#でここでやっていることですね。2)私の個人的な気持ちは、それが「契約」の一部である必要がある場合、抽象クラスで宣言することが適切であるということです。言い換えれば、あなたがやったことは完全にOKだと思います。 IMHO ... – paulsm4

+1

@ paulsm4あなたはC#でもそうすることができます。 –

答えて

56

デフォルト実装がなく、派生クラスで実装する必要がある場合は、抽象プロパティを使用します。

基本クラスに実装があり、オーバーライドを許可する場合は、仮想プロパティを使用します。

メンバーを無効にするには、overrideキーワードを使用します。再度オーバーライドしない場合は、メンバーをsealed overrideとマークします。

オーバーライドしたくない場合は、プロパティをabstractまたはvirtualに設定しないでください。

は(これはめったに良いアイデアではありません)非抽象、非仮想メンバを非表示にする newキーワードを使用します。

How to: Define Abstract Properties

私は、抽象プロパティは、多くの場合、彼らはタイプ固有のロジックおよび/または副作用を持っていることを意味デザインで発生することがわかります。基本的には、「ここではすべてのサブクラスで必要なデータポイントがありますが、実装方法はわかりません」 しかしでは、大量のロジックや副作用の原因となるプロパティは望ましくない場合があります。これは重要な考慮事項ですが、修正する権利/間違った方法はありません。

参照:個人的に

、私はめったに頻繁に抽象メソッドを使用していないが、抽象プロパティことがわかります。

4

抽象使用するすべてのサブクラスのメソッド/プロパティを実装するを持っている。各サブクラスがそれを実装する必要がない場合は、それを使用しないでください。 SecondNameは、それぞれの人のために必要とされない場合

あなたの例については、その後、基底クラスで抽象プロパティを作成する必要はありません。一方、すべての人が第二の名前を必要とする場合は、それを抽象的な財産にします。抽象プロパティの正しい使用方法を

例:すべての車はメーカーがあり、そのメーカーがあることをユーザーに伝えることができる必要があるため

public class Car 
{ 
    public abstract string Manufacturer { get; } 
} 

public class Odyssey : Car 
{ 
    public override string Manufacturer 
    { 
     get 
     { 
      return "Honda"; 
     } 
    } 
} 

public class Camry : Car 
{ 
    public override string Manufacturer 
    { 
     get 
     { 
      return "Toyota"; 
     } 
    } 
} 

Maker抽象を作るには、正しいです。

1

抽象プロパティは、クラスに常にプロパティを公開させたいが、そのプロパティの実装をピン止めできない場合に使用します。継承クラスを強制的に/強制的に継承します。

hereがあります。抽象クラスの名前はShapeで、抽象的なAreaプロパティが公開されています。領域の数式は形状の種類ごとに変わるため、基本クラスにAreaプロパティを実装することはできません。すべての図形には(ある種の)領域があるため、すべての図形がプロパティを公開する必要があります。

あなたの実装自体はうまく見えます。 Humanの抽象的なプロパティの賢明な例を考えようとしましたが、合理的なものは考えられませんでした。

11

抽象メンバーは、単にあなたがオーバーライドする必要が仮想メンバーです。これは、実装する必要があるものの、基本クラスでは実装できないものに使用します。

あなたは仮想プロパティを作りたい、そしてそれはあなたのクラスを継承したクラスでオーバーライドされなければならないことをしたい場合は、あなたがそれを抽象的財産になるだろう。

例えばあなたは、動物のクラスを持っている場合は、息をする能力はちょうどそれが動物だという情報からdetemineすることはできないが、それはかなり重要です何か:魚について

public abstract class Animal { 

    public abstract bool CanBreathe { get; } 

} 

犬の実装が異なるだろうと:

public class Dog : Animal { 

    public override bool CanBreathe { get { return !IsUnderWater; } } 

} 

public class Fish : Animal { 

    public override bool CanBreathe { get { return IsUnderWater; } } 

} 
26

私は、私は彼らが何をしたいのかを知って、私は彼らがそれを行う方法気にしない:インタフェース。抽象クラス:

私は、私は彼らが何をしたいのかを知って、私は、彼らはそれのいくつかを行う方法気にしないが、私はどのように彼らはよ(あるいは少なくともそれらのほとんど)にしっかりとアイデアをしましたが、他のビットを行います。

私は、私は彼らが何をしたいのかを知って、そしてどのようにそれらのほとんどはそれを行います:仮想メンバーとの具象クラス。

次のような他の例を持つことができ、例えば抽象メンバを持たない抽象クラス(1つのインスタンスを持つことはできませんが、それが提供する機能は完全に提供されます)。しかし、特定の階層が特定の問題。

(ちなみに、ピーターは人間の一種だとは思っていませんが、ピーターという人は、ピーターと呼ばれる人間の例として考えています。このようにサンプルコードを選ぶのは、この種の問題について考えるときは、通常よりも適切です)。

+3

+1 - 「Peter」は、「Human」のサブクラスのインスタンスである必要があります。 'HumansWithTwoNames' –

+2

@TimMedoraそうですね、サンプルコードを作るときに悪い名前を考えているのですが、通常は問題ではありませんが、これは最も重要な点の1つです。 –

関連する問題