
Виртуальные функции
Механизм виртуальных функций позволяет в иерархию наследования классов ввести особые функции - виртуальные функции, которые, будучи определёнными в базовом классе, могут применяться в объектах наследуемых классов, а при необходимости и переопределяться. При этом обращаться к этим функциям необходимо по объекту через указатель базового класса для языка С++ и через ссылочную переменную базового класса для языка Java.
//Java class А { // Объявление функции F() public void F ( ) {System.out.println("A.F");} } class В extends А { // Наследуемая функция F() переопределяется public void F ( ) {System.out.println("B.F");> } class С extends А { // Наследуемая функция F() переопределяется public void F ( ) {System.out.println("C.F");> } class Test { public static vold main ( ) { A a= new A ( ); B b= new B ( ); C c= new C ( );
A r= a; r.F();
r=b; r.F(); r= c;
r.F(); } } /*Result: A.F B.F C.F C.F */
|
//C++ class А { public: // Объявление виртуальной функции F() virtual void F ( ) {Console::WriteLine ("A:: F");} }; class В : public А { public: // Наследуемая виртуальная функция F() переопределяется void F ( ) {Console::WriteLine ("B:: F");} }; class С : public В { public: void F ( ) {Console::WrlteLlne ("C:: F");} }; }; void rnain < ) { А *pA= new А; В *pB= new В; С *pC= new С; pA -> F (); pB->F(); pC -> F ( ); } /*Result: A:: F B:: F C:: F */ |
Если объявить функцию виртуальной, мы можем динамически, при необходимости, во время выполнения программы, присвоить ссылке на базовый класс ссылку на требуемый объекта порождённого класса, и наша программа изменив функционирование, выполняя виртуальную функцию этого объекта.
Абстрактные функции
При объявлении абстрактной функции в классе необходимо указать требуемый доступ - protected или public. Поскольку абстрактная функция должна переопределяться в порождённом классе, она не может иметь доступ private.
Абстрактными функциями представляют одноимённые функции порождённых классов, тела которых могут несколько отличаться для объектов различных порождаемых классов. Как видим, абстрактная функция схожа с виртуальной функцией, поскольку требует переопределения, но в отличие от виртуальной функции она не содержит тело.
//Java abstract class А { // Объявление абстрактную функции F() abstract public void F ( ); } class В extends А { // Наследуемая абстрактная функция F() переопределяется public void F ( ) {System.out.println ("B.F");> } class С extends В { // Наследуемая абстрактная функция F() не переопределяется //public void F ( ) {System.out.println ("C.F");} } class Test { public static vold maln ( ) { В b= new В (); С c= new С (); b.F(); c.F(); } } /*Result: B.F B.F */ |
//C++ // Абстрактный класс class А { protected: // Объявление чистой виртуальной функции F() virtual void F ( }= О; }; class В : public А { public: // Наследуемая чистая виртуальная функция F() переопределяется void F ( ) {Console::WriteLine ("B:: F");} }; class С : public В { public: // Наследуемая чистая виртуальная функция F() не переопределяется //void F ( ) {Console::WriteLine ("C:: F");} }; vold main ( ) { B *pB=new B; С *pC= new С; pB -> F (); pC -> F (); } /*Result: B:: F B:: F */ |
Вывод: язык Java похож на С++, так как он от него начал свое развитие. При этом языки Java был реализован, позволяя как простое создание и использование компонентов, так существенное повышение надёжности и защищённости многокомпонентных программ, правда проигрывая языку С++ в эффективности их выполнения. Меньшая эффективность обусловлена применением языками Java специальных сред выполнения программного кода. Неуправляемый программный код языка С++ превратился в управляемый программный код в языках Java.