抽象クラスでできることすべてが通常のスーパークラスでできるのなら、なぜ通常のスーパークラスを使用できるのに抽象クラスを使用するのでしょうか。
3 に答える
コメントと回答はすでにこれを暗示していると思いますが、もっと率直に述べたいと思います。抽象クラスでできることを通常のスーパークラスですべて行うことはできません。抽象クラスを使用すると、メソッドの実装を含めずにメソッドのシグネチャを定義できます。抽象クラスでは、メソッドを直接インスタンス化することはできません。
したがって、3 つのメソッドを持つクラス シグネチャがあり、それらの実装を共有したくない場合は、インターフェイスを使用します。これらのメソッドの 1 つの実装を共有したい場合は、抽象クラスを使用し、そのクラスの 2 つのメソッドを抽象化します。メソッドのすべての実装を共有したい場合、直接インスタンス化する意味がない場合は抽象クラスを使用するか、インスタンス化する場合は通常のクラスを使用します。
(これは C# での私の経験に基づいています。詳細は言語によって異なります。)
基本クラスは、メソッドの独自の実装を提供します。これらの実装は、(言語によっては) オーバーライドされる場合があります。
抽象クラスはデフォルトの実装を提供せず、すべての継承クラスはケースバイケースでメソッドを実装する必要があります。
上記の詳細は、言語によって異なる場合があります。適切なドキュメントをお読みください。
次の例を考えてみましょう:Number
抽象クラスにはadd()
メソッドがあります。AOddNumber
とEvenNumber
サブクラスは実質的に同じadd()
メソッドを実装する必要があるため、コードが重複しています。ここでは、スーパークラスを持つ方がより理にかなっています (または、少なくとも、 のRealNumber
サブクラスを持つことNumber
)。
ただし、数値が抽象的でない場合Complex
のサブクラスであると考えてください。 (実数加算アルゴリズムであると仮定して) にあるメソッドは、複素数には意味がありません。ここでは、抽象クラスがより理にかなっています。一部の言語ではスーパークラス メソッドをオーバーライドできますが、このシナリオではそれはちょっと厄介です。Number
add()
Number
抽象クラスは、多くの類似したものを共通の方法で表現する必要がある場合に非常に役立ちます。
たとえば、コードで動物園を表現したいと考えていて、適切な食べ物があることを確認するために食料品リストを取得する必要があるとします。すべての動物の好きな食べ物をどのように表しますか? そして、それぞれがどんな音を立てますか?彼らの動きはどうですか?スーパークラスを使用して、食べ物、騒音、動きの大きなリストを保持することもできますが、動物に共通の定義を設定し、各動物に独自の実装の詳細を提供する方が簡単です。
public class Zoo {
public Animals[] AnimalsInZoo { get; set;}
public List<Food> GetGroceryList(){
List<Food> groceries = new List<Food>();
foreach(Animal a in Animals[]){
groceries.Add(a.FavoriteFood);
}
return groceries;
}
public void MakeAnimalsSing(){
foreach(Animal a in Animals[]){
a.MakeNoise();
}
}
}
抽象 Animal クラスは次のようになります。
public abstract class Animal {
public abstract void MakeNoise();
public abstract Food FavoriteFood { get; }
public abstract void Move();
}
そして、動物園には 2 種類の動物がいたとします。
public class Panda : Animal{
public override void MakeNoise(){
// grunt
}
public override void Move(){
// walk
}
public override Food FavoriteFood {
get {
return new Bamboo();
}
}
}
public class Parrot: Animal{
public override void MakeNoise(){
// talk
}
public override void Move(){
// fly
}
public override Food FavoriteFood {
get {
return new Cracker();
}
}
}
共通の抽象クラスを持つことで、どの種類の動物を扱っているかを明確に知らなくても、さまざまな種類の動物を簡単に扱うことができますが、それぞれが独自の方法で振る舞うことができます。
スーパークラスは、その柔軟性や詳細を提供できません。