class CAnimal
{
private:
voidvirtual Speak(){}
};
class CDog : public CAnimal
{
public:
void Speak(){Print("Гав!");}
};
class CBigDog : public CDog
{
public:
void Speak(){Print("Громкий гав!");}
};
voidOnStart()
{
CDog oDog;
oDog.Speak();
CBigDog oBigDog;
oBigDog.Speak();
CDog* pDog = &oBigDog;
pDog.Speak(); // "Громкий гав!", а не "Гав!", как было бы без виртуального метода
}
これを利用して、finalというキーワードの類似品を作り、さらなる継承を明示的に禁止することができます。
しかし、上の例のように、アナログを作ることはできません。プライベートメソッドであってもfinalを指定する必要があります。
奇妙なことに、公共の相続の場合、最大限のアクセスは保護されるべきで、プライベートなものではないのです。
そして、例の関数が正確にオーバーロードされているのか?
奇妙なことに、公共の相続の場合、最大限のアクセスは保護されるべきで、プライベートなものではないのです。
また、例の場合、その関数は正確にオーバーロードされているのでしょうか?
そうですね。自分で見つけただけなんですけどね。
もし、あなたが
BASE() {Func();} // вместо void Init() {Func();} Вызов Base.Init() - убрать конечно.は、実行した後に自分で確認し、何が起こるかわかるかどうかを確認することができます。
端末のログを見ると
は、ソースコードの指定された場所に不器用に移動します。端末のログでこのようなメッセージをダブルクリックすると、指定した行に直行できると便利なのですが。
もし支持している人がいたら、声を上げてください。
古典的なのは、ベースクラスでのインタフェースと、子孫での再定義である。
古典的なのは、protected/publicな仮想メソッドがオーバーライドされる場合です。でも、プライベートの場合は、(用途が)あまり明確ではありません。ご返信ありがとうございます。
そうなんです、もうお返事を見ずに例のものを削除してしまいました、本当に残念です。
私自身、回答中に基本的なことがわからなくなってしまいました。その例ではすべてが正しかったので、削除するべきではありませんでした。同じ例をもう一度、使用例で。
私自身、回答中に基本的なことがわからなくなりました。その例ではすべてが正しかったので、削除するべきではありませんでした。再度、使用例を挙げて説明します。
コンパイラはデイスを作らない。
というのも、CAnimalインターフェイスがどこかで使われているのを見ることができないからです。また、2人の子孫も公開されている。トピックは理解しているので大丈夫です。
通常の例です。抽象的な動物は、基本的に何らかの音を出しますが、未定義なので、Speak()メソッドを呼び出すことはできません;特定の種の動物に対してのみ呼び出すことができます。そこで、ベースクラスで閉じた仮想メソッドを宣言し、子孫クラスでそれをオーバーライドして開く。
通常の例です。抽象的な動物は、基本的に何らかの音を出しますが、未定義なので、Speak()メソッドを呼び出すことはできません;特定の種の動物に対してのみ呼び出すことができます。そこで、ベースクラスで閉じた仮想メソッドを宣言し、子孫クラスでそれをオーバーライドして開く。