web-dev-qa-db-ja.com

抽象クラスと通常のクラスを使用する利点

私は、コード量ではなくコード品質に焦点を当てた小規模なコーディングプロジェクトを自分で始めることにし、抽象クラスの使用について質問しました。

今私は抽象クラスとインターフェースの違いを知っていますが、最大のもの(私は思う)は、そのインターフェースでは、インターフェースと抽象クラスを使用してクラスによって実装する必要があるメソッドのみを定義でき、メソッドとメンバーの両方を定義できることです必要に応じて、デフォルトのメソッド実装。私の質問は、抽象クラスと通常のクラスを使用する主な利点は何ですか?私が考えることができる2つの唯一の本当の違いは、抽象クラスのインスタンスを作成できないことです。 2つの間に他の違いはありますか?

22
ryanzec

厳密にはデザインの観点から、物事を単純化するのが最善です。物事を単純化する最良の方法は、単純な類推を使用することだと思います。鳥のアナロジーを使ってみましょう...

インターフェース:定義する必要がある特定の機能を強制したい場合に使用します。例えばIBirdはScreamLikeABirdとFly(インターフェース関数)の契約を結んでいます。しかし、もっと具体的にして、Runコントラクトを持つIOstrichを持つことができます。あなたはまた、攻撃契約を持つIHawkを持っているかもしれません...など。

要約:基本関数を適用し、基本プロパティを設定する場合に使用します。例えばAvianは、LayEggと呼ばれる関数や、Age、Species、NumberOfChicksなどと呼ばれるプロパティを持つ鳥の基本クラスになる可能性があります。すべての鳥が卵を産むので、これらのことは鳥の行動を変更しない/すべきではない...などしかし、すべての鳥が同じように悲鳴を上げたり飛んだりすると、同じように聞こえるわけではありません(一部は飛ぶことさえありません)。

20

抽象クラスのインスタンスを作成できないことに加えて、一部の言語では、抽象クラスに抽象メソッドを持つことをサポートする場合があります。インターフェイスと同様に、抽象メソッドは、抽象クラスから継承するクラスによって実装する必要があります。

私の考えでは、抽象クラスの主な利点は、同じ型のクラス間で共有する必要があるコードがある場合です。通常、これにはインターフェースを使用できますが、そのようなクラスの機能が重複し、コードが重複する場合があります。この場合、抽象クラスを使用して、そこにコードを置くだけです。

13

OOの世界では、抽象クラスは設計と実装の制約を課すために使用されました。それ以上はありません。いかなる場合でも抽象クラスを使用する必要はありません。しかし、これらの制約を課した方がよい場合もあります。では、それらは何ですか?ooの対応物と比較して見てみましょう。

抽象クラ​​スvsインターフェース

ご存じのとおり、これらは継承の2つの主要な概念です。

基本的に、インターフェイスは、基礎となるサービスを継承する意思があることを宣言するためだけに使用され、それだけです。実装は含まれておらず、機能もありません。その意味で、インターフェースは抽象的です。これが、実装上の制約というよりは設計上の制約である理由です。スピーカーのヘッドフォンジャックを考えてみてください。各ヘッドフォンは、ジャックインターフェイスを実装する必要があります(start、stop、listen、turnDown、turnUpメソッドを使用)。各ヘッドフォンはこのインターフェイスをオーバーライドして、スピーカーが提供する機能を継承し、それに応じて実装する必要があります。

一方、抽象クラスには、実装を持つメソッドが含まれる場合があります。それが基本的な違いであり、その意味では、インターフェース以上の再利用を利用するかもしれません。さらに、それらには、インターフェースを介してはアクセスできないプライベートで保護された非静的フィールドが含まれる場合があります。サブクラスは、抽象メソッドを使用していくつかの必須機能を実装するように強制することができます(実装のないもの)。抽象クラスはインターフェースよりも機敏です。

もちろん言うまでもありませんが、Java)で拡張できるクラスは1つだけです。

抽象クラ​​スと通常のクラス

では、なぜ通常のクラスを使用しないのか。抽象クラスを使用する利点は何ですか?これはとても簡単です。抽象クラスを使用する場合は、コア機能を兄弟によって実装する必要があります。開発者は、基本的な機能を実装する必要があることを覚えておく必要はありません。これは、通常のクラスに対して設計上の制約を課す抽象クラスです。さらに、クラスを抽象化することにより、その(不完全な)クラスが誤って作成されるのを防ぎます。

8
stdout

私の意見では、抽象クラスは本と同じように実際のプロジェクトでより多くの用途があります。場合によっては、プロジェクトマネージャーがメソッド宣言を提供するだけで、マネージャーが提供するコア構文を変更せずにメソッドのコードを記述する必要があります。これが、抽象クラスが完全に使用される方法です。単純なクラスメソッドでは、定義、宣言、コーディングを同時に行いますが、抽象クラスでは行いません。例:-

abstract class Test
{
    abstract void show();//method provided
}
class Child extends Test
{
    void show()//coding 
    {
        System.out.println("saurav");
    }
}
class main
{
    public static void main(String[] args) 
    {
    Test c = new Child();
    c.show();   
    }
}
2
saurav

抽象クラスvs通常のクラスvsインターフェース。抽象クラスは通常、一般化の概念をサポートし、抽象メソッドを含めるとサブクラスの抽象メソッドの実装を記述しなければならないため、複数年のプロジェクトを設計することにより、プログラマーが脳の規律をか​​なり維持できるように貢献しますこの機能は、開発者が無力な場合の短期間のプロジェクトには不利です。

0
Gleb M

クラスAを別のクラスBで拡張する場合(つまり、AからBでプロパティを共有する場合)、抽象クラスと通常のクラスにいくつかのユースケースの違いを置くことができます。

抽象クラ​​ス:一部のメソッドを拡張するクラスで強制的に使用する場合は、抽象クラス 'Abs'を使用します(Abs)。

通常のクラス:通常のクラスAを別のクラスBで拡張しながら、Aのすべての関数を使用できますが、必須ではありません。

Aから関数をオーバーライドすると、Bにプロパティが追加されます。

例えば

class Automobile{
//type of fuel
abstract String gasOrPetrol(){
}
}

class BMW extends Automobile{
//I will have to worry if I don't know the fuel type of my BMW;
//so i made it compulsory to be implemented
//One more point, I also need to make the method abstract to make it really compulsory

//
String fuel="Petrol";
@Override
String gasOrPetrol() {
    return "fuelType is "+fuel;
}
}

私の意図は、抽象クラスが持つ良いものについてのアイデアを与えることです。ハッピーコーディング...

0
Taba

クラスを抽象として宣言する唯一の理由は、インスタンス化できないようにするためです。いくつかのクラス間で共有される共通の機能を使用する状況がありますが、それ自体では、その共通の機能はオブジェクトを表さないか、不完全なオブジェクトを表しています。その場合は、インスタンス化できないように、共通の機能を抽象として定義します。

0
No name