何がよく見えるか、いつ抽象クラスとプロパティで実際に使用するのか、または非抽象プロパティをいつ使用するのかはよくわかりません。簡単な例を作ってみます。私がこれを持っているとしましょう:
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
}
これでいいですか?私が理解したように、抽象プロパティをオーバーライドしたくない場合は、抽象プロパティを使用する必要はありません。この状況では大丈夫です。Speak
、Sleep
などのメソッドだけが抽象的である必要があります。
さて、これで問題なければ、いつ抽象プロパティを使用するか、または使用する必要がありますか?
デフォルトの実装がなく、派生クラスがそれを実装する必要がある場合は、抽象プロパティを使用します。
基本クラスに実装があるが、オーバーライドを許可する場合は、仮想プロパティを使用します。
override
キーワードを使用して、メンバーをオーバーライドします。メンバーを再度オーバーライドしない場合は、sealed override
としてマークします。
プロパティを上書きしたくない場合は、プロパティをabstract
またはvirtual
としてマークしないでください。
new
キーワードを使用して、非抽象、非仮想メンバーを非表示にします(これはめったに良いアイデアではありません)。
抽象プロパティは、タイプ固有のロジックや副作用があることを意味するデザインでしばしば発生することがわかります。基本的に、「すべてのサブクラスに必要なデータポイントがありますが、実装方法がわかりません」と言っています。 ただし、、大量のロジックを含むプロパティや副作用を引き起こすプロパティは望ましくない場合があります。これは重要な考慮事項ですが、正しい/間違った方法はありません。
見る:
個人的には、抽象メソッドを頻繁に使用しますが、抽象プロパティはめったに使用しません。
私は彼らに何をしてほしいかを知っています、彼らがそれをどうするかは気にしません:インターフェース。
私は彼らが何をしたいのか知っています、彼らがそれをどうやってやるかは気にしませんが、私は彼らが他のビット(または少なくともほとんど)をどのように行うかについてしっかりと考えています:抽象クラス。
私は彼らに何をしたいのか、そして彼らのほとんどがそれをどのように行うのかを知っています:仮想メンバーを持つ具体的なクラス。
他のケース、たとえば抽象メンバーを持たない抽象クラス(1つのインスタンスを持つことはできませんが、どの機能を提供するか、完全に提供します)が、特定の階層が特定の階層にきれいに露骨に提供されるため、それらはよりまれで通常発生します問題。
(ちなみに、私はピーターを人間のタイプとは思わず、各ピーターをたまたまピーターと呼ばれる人間のインスタンスと考えます。このようにサンプルコードを選ぶのは本当に公平ではありませんが、この種の問題について考えると、それは通常よりも適切です)。
抽象メンバーは、オーバーライドする必要がある単なる仮想メンバーです。これは、実装する必要があるが、基本クラスには実装できないものに使用します。
仮想プロパティを作成し、クラスを継承するクラスでオーバーライドする必要がある場合は、それを抽象プロパティにします。
たとえば動物のクラスがある場合、呼吸する能力は、それが動物であるという情報だけから判断することはできませんが、それは非常に重要なことです:
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; } }
}
すべてのサブクラスhaveの場合、abstractを使用してメソッド/プロパティを実装します。サブクラスごとに実装する必要がない場合は、使用しないでください。
あなたの例として、各人にSecondName
が必要ない場合、基本クラスに抽象プロパティを作成する必要はありません。一方、すべての人が2番目の名前を必要とする場合、それを抽象プロパティにします。
抽象プロパティの正しい使用例:
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";
}
}
}
every車にはメーカーがあり、そのメーカーをユーザーに伝えることができる必要があるため、Maker
abstractを作成するのは正しいことです。
クラスに常にプロパティを公開させたいが、そのプロパティの実装を固定できない場合、抽象クラスのプロパティを使用します-継承クラスにそれを任せる/強制する。
例があります here 、抽象クラスの名前はShape
で、抽象Area
プロパティを公開します。面積の式は形状のタイプごとに変わるため、基本クラスにArea
プロパティを実装することはできません。すべての図形には(何らかの)領域があるため、すべての図形にプロパティを公開する必要があります。
実装自体は問題ありません。 Human
の抽象プロパティの賢明な例を考えようとしていましたが、合理的なものは考えられませんでした。