OOP クラスのポリモーフィズムについて学習したばかりで、抽象基本クラスがどのように役立つかを理解するのに苦労しています。
抽象クラスの目的は何ですか? 抽象基本クラスを定義すると、実際の各クラスに必要な各関数を作成することによって提供されないものが提供されますか?
OOP クラスのポリモーフィズムについて学習したばかりで、抽象基本クラスがどのように役立つかを理解するのに苦労しています。
抽象クラスの目的は何ですか? 抽象基本クラスを定義すると、実際の各クラスに必要な各関数を作成することによって提供されないものが提供されますか?
抽象クラスの目的は、具体的なサブクラスのセットに共通のプロトコルを定義することです。これは、コードや抽象的なアイデアなどを共有するオブジェクトを定義するときに役立ちます。
抽象クラスにはインスタンスがありません。抽象クラスには、少なくとも 1 つの遅延メソッド (または関数) が必要です。C++ でこれを実現するには、純粋仮想メンバー関数を宣言しますが、抽象クラスでは定義しません。
class MyClass {
virtual void pureVirtualFunction() = 0;
}
抽象クラスをインスタンス化しようとすると、常にコンパイラ エラーが発生します。
「実際の各クラスに必要な各関数を作成することによって提供されない、抽象基本クラスを定義することによって提供されるものは何ですか?」
ここでの主なアイデアは、コードの再利用とクラス間の適切な分割です。複数のサブクラスで何度も関数を定義するよりも、親クラスで関数を一度定義する方が理にかなっています。
class A {
void func1();
virtual void func2() = 0;
}
class B : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
class C : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
抽象クラスを使用すると、コンパイル時にプロトコルを適用できます。これらのプロトコルは、クラス ファミリーの一部であることの意味を定義します。
別の考え方として、抽象クラスは、実装するクラスが満たさなければならない契約であるということです。このコントラクトを満たさない場合、クラス ファミリの一部になることはできず、コントラクトに準拠するように変更する必要があります。提供されたコントラクトはデフォルトの機能を提供する場合がありますが、コントラクトのスコープ内にとどまりながら、より具体的な機能または異なる機能を定義するサブクラスに任せることもできます。
小規模なプロジェクトの場合、これは役に立たないように見えるかもしれませんが、大規模なプロジェクトでは、抽象クラス コントラクトを通じてドキュメントを提供するため、適合性と構造が提供されます。これにより、コードの保守が容易になり、サブクラスがそれぞれ同じプロトコルを持つようになり、新しいサブクラスの使用と開発が容易になります。
私は犬を飼っている。メソッド樹皮を持つ抽象クラスの犬。私の特定の犬は 1 つの吠え声を出します。他の犬は別の方法で吠えます。したがって、抽象的な方法で犬を定義すると便利です。
AbstractClass
から派生した型を持つすべてのオブジェクトに必要な機能があるがAbstractClass
、それ自体では適切に実装できない場合、基本クラスとしての抽象クラスが必要AbstractClass
です。
Vehicle
派生クラスCar
、 、 ...を持つ基本クラスを持つ、古くてやや人工的な OO の例は、Motorcycle
ここで良い例を提供します。メソッドが必要だとします。aまたは aが移動するmove()
方法を実装できますが、 s は移動しません。一般的な方法であるため、純粋に仮想的であり、したがって抽象的である必要があります。Car
Motorcycle
Vehicle
Vehicle::move()
Vehicle
各クラスで必要な各関数を作成しないのはなぜですか? (C++)
abstract
各派生クラスでとしてマークされている必要な各関数を作成する必要があります。
質問がある場合は、なぜ抽象クラスで抽象関数を作成するのですか?
これにより、厳密なランタイム ポリモーフィズムが可能になります。
インターフェイスと抽象クラス (一般的な OO)もお読みください。
抽象クラスは、実装するインターフェイスを定義するために使用されます。いくつかの参照を参照してください。
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes
abstract class dog
{
bark();
}
// function inside another module
dogbarking(dog obj)
{
dog.bark(); // function will call depend up on address inside the obj
}
// our class
ourclass: inherit dog
{
bark()
{
//body
}
}
main()
{
ourclass obj;
dogbarking(obj);
}
dogbarking は別のモジュールで記述された関数であることがわかります。抽象クラスの dog だけを認識します。クラス内で関数 bark を呼び出すことはできますが。main 関数では、ourclass のオブジェクトを作成し、抽象クラス dog の参照オブジェクトを使用して受け取った関数 dogbarking に渡します。
文字列を表示する方法が 2 つあるとします。
DisplayDialog(string s);
PrintToConsole(string s);
そして、これら 2 つの方法を切り替えることができるコードを書きたいとします。
void foo(bool useDialogs) {
if (useDialogs) {
DisplayDialog("Hello, World!");
} else {
PrintToConsole("Hello, World!");
}
if (useDialogs) {
DisplayDialog("The result of 2 * 3 is ");
} else {
PrintToConsole("The result of 2 * 3 is ");
}
int i = 2 * 3;
string s = to_string(i);
if (useDialogs) {
DisplayDialog(s);
} else {
PrintToConsole(s);
}
}
このコードは、文字列の表示に使用される特定のメソッドと密接に結びついています。メソッドの追加、メソッドの選択方法の変更などは、これを使用するすべてのコードに影響します。このコードは、文字列を表示するために使用する一連のメソッドと密接に結びついています。
抽象基本クラスは、ある機能を使用するコードを、その機能を実装するコードから分離する方法です。これは、タスクを実行するさまざまな方法すべてに共通のインターフェイスを定義することによって行われます。
class AbstractStringDisplayer {
public:
virtual display(string s) = 0;
virtual ~AbstractStringDisplayer();
};
void foo(AbstractStringDisplayer *asd) {
asd->display("Hello, World!");
asd->display("The result of 2 * 3 is ");
int i = 2 * 3;
string s = to_string(i);
asd->display(s);
}
int main() {
AbstractStringDisplayer *asd = getStringDisplayerBasedOnUserPreferencesOrWhatever();
foo(asd);
}
AbstractStringDisplayer で定義されたインターフェースを使用すると、文字列を表示する新しい方法をいくつでも作成して使用できます。抽象インターフェースを使用するコードを変更する必要はありません。