CrxOop CrxOop: Bringing Object Oriented Programming, and Proper Prototype Based Programming, To Javascript
The aim of the library documented below is to provide developers with a solution to allow development using interfaces and classes as they are known in other object oriented programming (OOP) languages such as C++, C#, Java and PHP. Further more, V1.4 introduces structures, a generalization of the concept of prototypal inheritance, known here as POBP.
Subject
Body*
Email
SUBMIT CLOSE
Menu

3.3.4 Public, Protected and Private Virtual Functions

There are three types of class functions. In this section we discuss the second type, which are non static virtual functions.

Example: Virtual Functions
JS (Tree)
crx_registerClass("ExampleClass",
{
   PUBLIC:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            publicVirtualFunction1: function()
            {
               console.log("publicVirtualFunction1");
            },
            publicVirtualFunction2: function()
            {
               console.log("publicVirtualFunction2");
            },
            publicPureVirtualFunction1: 0
         },
         FINAL:
         {
            FUNCTIONS:
            {
               publicVirtualFinalFunction1: function()
               {
                  console.log("publicVirtualFinalFunction1");
               },
               publicVirtualFinalFunction2: function()
               {
                  console.log("publicVirtualFinalFunction2");
               }
            }
         }
      }
   },
   PROTECTED:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            protectedVirtualFunction1: function()
            {
               console.log("protectedVirtualFunction1");
            },
            protectedVirtualFunction2: function()
            {
               console.log("protectedVirtualFunction2");
            },
            protectedPureVirtualFunction1: 0
         },
         FINAL:
         {
            FUNCTIONS:
            {
               protectedVirtualFinalFunction1: function()
               {
                  console.log("protectedVirtualFinalFunction1");
               },
               protectedVirtualFunction4: function()
               {
                  console.log("protectedVirtualFunction4");
               }
            }
         }
      }
   },
   PRIVATE:
   {
      VARS:
      {
         "privateVar": "ExampleClass::privateVar"
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            privateVirtualFunction1: function()
            {
               console.log("privateVirtualFunction1");
            },
            privateVirtualFunction2: function()
            {
               console.log("privateVirtualFunction2");
            },
            privatePureVirtualFunction1: 0
         }
      }
   }
});
crx_registerClass("ExampleSubClass",
{
   EXTENDS: "ExampleClass",
   PUBLIC:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            publicPureVirtualFunction1: function()
            {
               console.log("ExampleSubClass::publicPureVirtualFunction1");
            }
         }
      }
   },
   PROTECTED:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            protectedPureVirtualFunction1: function()
            {
               console.log("ExampleSubClass::protectedPureVirtualFunction1");
            }
         }
      }
   },
   PRIVATE:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            privatePureVirtualFunction1: function()
            {
               console.log("ExampleSubClass::privatePureVirtualFunction1");
            }
         }
      }
   }
});

//      The following would cause CrxOop to halt, because ExampleClass contains pure
//            virtual functions, and thus can not be instatiated. This makes it an
//            abstract class.
//var gExampleClass = crx_new("ExampleClass");

//      The following would work because ExampleSubClass implements all the pure virtual
//            functions found in ExampleClass. If it did not, this would also make it
//            an abstract class.
var gExampleSubClass = crx_new("ExampleSubClass");
JS (Verbose)
crx_registerClass("ExampleClass",
{
   "VERBOSE": 1,
   "public virtual function publicVirtualFunction1": function()
   {
      console.log("publicVirtualFunction1");
   },
   "public virtual function publicVirtualFunction2": function()
   {
      console.log("publicVirtualFunction2");
   },
   "public virtual function publicPureVirtualFunction1": 0,
   "public virtual final function publicVirtualFinalFunction1": function()
   {
      console.log("publicVirtualFinalFunction1");
   },
   "public virtual final function publicVirtualFinalFunction2": function()
   {
      console.log("publicVirtualFinalFunction2");
   },

   "protected virtual function protectedVirtualFunction1": function()
   {
      console.log("protectedVirtualFunction1");
   },
   "protected virtual function protectedVirtualFunction2": function()
   {
      console.log("protectedVirtualFunction2");
   },
   "protected virtual function protectedPureVirtualFunction1": 0,
   "protected virtual final function protectedVirtualFinalFunction1": function()
   {
      console.log("protectedVirtualFinalFunction1");
   },
   "protected virtual final function protectedVirtualFunction4": function()
   {
      console.log("protectedVirtualFunction4");
   },

   "private virtual function privateVirtualFunction1": function()
   {
      console.log("privateVirtualFunction1");
   },
   "private virtual function privateVirtualFunction2": function()
   {
      console.log("privateVirtualFunction2");
   },
   "private virtual function privatePureVirtualFunction1": 0
});

crx_registerClass("ExampleSubClass",
{
   VERBOSE: 1,
   EXTENDS: "ExampleClass",
   "public virtual function publicPureVirtualFunction1": function()
   {
      console.log("ExampleSubClass::publicPureVirtualFunction1");
   },
   "protected virtual function protectedPureVirtualFunction1": function()
   {
      console.log("ExampleSubClass::protectedPureVirtualFunction1");
   },
   "private virtual function privatePureVirtualFunction1": function()
   {
      console.log("ExampleSubClass::privatePureVirtualFunction1");
   }
});

//      The following would cause CrxOop to halt, because ExampleClass contains pure
//            virtual functions, and thus can not be instatiated. This makes it an
//            abstract class.
//var gExampleClass = crx_new("ExampleClass");

//      The following would work because ExampleSubClass implements all the pure virtual
//            functions found in ExampleClass. If it did not, this would also make it
//            an abstract class.
var gExampleSubClass = crx_new("ExampleSubClass");

publicVirtualFinalFunction1(), publicVirtualFinalFunction2(), protectedVirtualFinalFunction1(), and protectedVirtualFinalFunction2() above are final functions; they can not be overriden in sub classes.

Virtual final functions can not be private.

publicPureVirtualFunction1(), protectedPureVirtualFunction1() and privatePureVirtualFunction1() are pure virtual functions. Classes containing pure virtual functions are Abstract Classes, and can not be instantiated. Classes extending Abstract Classess without fully implementing their pure virtual functions are also Abstract Classes.

Pure virtual functions can not be final.

If you are not familiar with C++, or the concept of virtual functions, refering to the section on class extension might help.

It is important to note, as an example, that like C++, if a derived class was to declate a virtual function f() as private, where it was declared as public in the base class, one could still gain access to f() by casting the instance to the base class. If you are not familiar with C++, an internet search for C++, virtual functions, and the Liskov substitution principle should help.