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.5 Friend Classes

A class can declare its own friend classes giving function members of the friend classes the same access its own function members have.

JS (Tree)
crx_registerClass("ExampleClass1",
{
   PRIVATE:
   {
      VARS:
      {
         'privateVar': 'I am ExampleClass1'
      }
   },
   PROTECTED:
   {
      FUNCTIONS:
      {
         'protectedFunction': function()
         {
            console.log('protectedFunction: ' + this.privateVar);
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            'protectedVirtualFunction': function()
            {
               console.log('protectedVirtualFunction: ' + this.privateVar);
            }
         }
      }
   }
});
crx_registerClass("ExampleClass2",
{
   EXTENDS: "ExampleClass1",
   FRIENDS: ["FriendOfExampleClass2"],
   PRIVATE:
   {
      VARS:
      {
         'privateVar': 'I am ExampleClass2'
      },
      FUNCTIONS:
      {
         'privateFunction': function()
         {
            console.log('privateFunction: ' + this.privateVar);
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            'privateVirtualFunction': function()
            {
               console.log('privateVirtualFunction: ' + this.privateVar);
            }
         }
      },
      STATIC:
      {
         FUNCTIONS:
         {
            'privateStaticFunction': function(pExampleClass2)
            {
               console.log('privateStaticFunction: ' + this.O(pExampleClass2).privateVar);
               this.O(pExampleClass2).SR("ExampleClass1", "protectedFunction");
               this.O(pExampleClass2).protectedFunction();
               this.O(pExampleClass2).protectedVirtualFunction();
            }
         }
      }
   },
   PROTECTED:
   {
      FUNCTIONS:
      {
         'protectedFunction': function()
         {
            console.log('protectedFunction: ' + this.privateVar);
         }
      }
   }
});
crx_registerClass("FriendOfExampleClass2",
{
   PUBLIC:
   {
      FUNCTIONS:
      {
         'test1': function(pExampleClass2)
         {
            //   FriendOfExampleClass2 being a friend class of ExampleClass2,
            //      its instance functions can gain access to the private memory
            //       area of instances of ExampleClass2 using 0().
            console.log(this.O(pExampleClass2, "ExampleClass2").privateVar);
            this.O(pExampleClass2, "ExampleClass2").SR("ExampleClass1", "protectedFunction");
            this.O(pExampleClass2, "ExampleClass2").protectedFunction();
            this.O(pExampleClass2, "ExampleClass2").protectedVirtualFunction();
            
            //   Although FriendOfExampleClass2 is a friend class of ExampleClass2,
            //      its intance functions can not gain access to private static
            //      members of ExampleClass2 directly. Hence the following
            //      would not work.
            //crx_static("ExampleClass2").privateStaticFunction(pExampleClass2);            
            
            //   Although many solutions exist for this, non of them lead to a
            //      satisfactory syntax, and hence why there is currently no
            //      support for that in CrxOop. A work around is to gain
            //      access to the private static members of ExampleClass2
            //      using an instance of ExampleClass2.
            this.O(pExampleClass2, "ExampleClass2").STATIC.privateStaticFunction(pExampleClass2);
         }
      },
      STATIC:
      {
         FUNCTIONS:
         {
            'test2': function(pExampleClass2)
            {
               //   FriendOfExampleClass2 being a friend class of ExampleClass2,
               //      its static functions can gain access to the private memory
               //       area of instances of ExampleClass2 using O().
               console.log(this.O(pExampleClass2, "ExampleClass2").privateVar);
               this.O(pExampleClass2, "ExampleClass2").SR("ExampleClass1", "protectedFunction");
               this.O(pExampleClass2, "ExampleClass2").protectedFunction();
               this.O(pExampleClass2, "ExampleClass2").protectedVirtualFunction();

               //   Although FriendOfExampleClass2 is a friend class of ExampleClass2,
               //      its static functions can not gain access to private static
               //      members of ExampleClass2 directly. Hence the following
               //      would not work.
               //crx_static("ExampleClass2").privateStaticFunction(pExampleClass2);

               //   Although many solutions exist for this, non of them lead to a
               //      satisfactory syntax, and hence why there is currently no
               //      support for that in CrxOop. A work around is to gain
               //      access to the private static members of ExampleClass2
               //      using an instance of ExampleClass2.
               this.O(pExampleClass2, "ExampleClass2").STATIC.privateStaticFunction(pExampleClass2);
            }
         }
      }
   }
});
instance = crx_new('FriendOfExampleClass2');

instance.test1(crx_new('ExampleClass2'));
console.log('------------------');
crx_static('FriendOfExampleClass2').test2(crx_new('ExampleClass2'));
I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
privateStaticFunction: I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
------------------
I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
privateStaticFunction: I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
JS (Verbose)
crx_registerClass("ExampleClass1",
{
   VERBOSE: 1,
   'private var privateVar': 'I am ExampleClass1',
   'protected function protectedFunction': function()
   {
      console.log('protectedFunction: ' + this.privateVar);
   },
   'protected virtual function protectedVirtualFunction': function()
   {
      console.log('protectedVirtualFunction: ' + this.privateVar);
   }
});
crx_registerClass("ExampleClass2",
{
   VERBOSE: 1,
   EXTENDS: "ExampleClass1",
   FRIENDS: ["FriendOfExampleClass2"],
   'private var privateVar': 'I am ExampleClass2',
   'private function privateFunction': function()
   {
      console.log('privateFunction: ' + this.privateVar);
   },
   'private virtual function privateVirtualFunction': function()
   {
      console.log('privateVirtualFunction: ' + this.privateVar);
   },
   'private static function privateStaticFunction': function(pExampleClass2)
   {
      console.log('privateStaticFunction: ' + this.O(pExampleClass2).privateVar);
      this.O(pExampleClass2).SR("ExampleClass1", "protectedFunction");
      this.O(pExampleClass2).protectedFunction();
      this.O(pExampleClass2).protectedVirtualFunction();
   },
   'protected function protectedFunction': function()
   {
      console.log('protectedFunction: ' + this.privateVar);
   }
});
crx_registerClass("FriendOfExampleClass2",
{
   VERBOSE: 1,
   'public function test1': function(pExampleClass2)
   {
      //   FriendOfExampleClass2 being a friend class of ExampleClass2,
      //      its instance functions can gain access to the private memory
      //       area of instances of ExampleClass2 using 0().
      console.log(this.O(pExampleClass2, "ExampleClass2").privateVar);
      this.O(pExampleClass2, "ExampleClass2").SR("ExampleClass1", "protectedFunction");
      this.O(pExampleClass2, "ExampleClass2").protectedFunction();
      this.O(pExampleClass2, "ExampleClass2").protectedVirtualFunction();
      
      //   Although FriendOfExampleClass2 is a friend class of ExampleClass2,
      //      its intance functions can not gain access to private static
      //      members of ExampleClass2 directly. Hence the following
      //      would not work.
      //crx_static("ExampleClass2").privateStaticFunction(pExampleClass2);            
      
      //   Although many solutions exist for this, non of them lead to a
      //      satisfactory syntax, and hence why there is currently no
      //      support for that in CrxOop. A work around is to gain
      //      access to the private static members of ExampleClass2
      //      using an instance of ExampleClass2.
      this.O(pExampleClass2, "ExampleClass2").STATIC.privateStaticFunction(pExampleClass2);
   },
   'public static function test2': function(pExampleClass2)
   {
      //   FriendOfExampleClass2 being a friend class of ExampleClass2,
      //      its static functions can gain access to the private memory
      //       area of instances of ExampleClass2 using O().
      console.log(this.O(pExampleClass2, "ExampleClass2").privateVar);
      this.O(pExampleClass2, "ExampleClass2").SR("ExampleClass1", "protectedFunction");
      this.O(pExampleClass2, "ExampleClass2").protectedFunction();
      this.O(pExampleClass2, "ExampleClass2").protectedVirtualFunction();

      //   Although FriendOfExampleClass2 is a friend class of ExampleClass2,
      //      its static functions can not gain access to private static
      //      members of ExampleClass2 directly. Hence the following
      //      would not work.
      //crx_static("ExampleClass2").privateStaticFunction(pExampleClass2);

      //   Although many solutions exist for this, non of them lead to a
      //      satisfactory syntax, and hence why there is currently no
      //      support for that in CrxOop. A work around is to gain
      //      access to the private static members of ExampleClass2
      //      using an instance of ExampleClass2.
      this.O(pExampleClass2, "ExampleClass2").STATIC.privateStaticFunction(pExampleClass2);
   }
});
instance = crx_new('FriendOfExampleClass2');

instance.test1(crx_new('ExampleClass2'));
console.log('------------------');
crx_static('FriendOfExampleClass2').test2(crx_new('ExampleClass2'));
I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
privateStaticFunction: I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
------------------
I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1
privateStaticFunction: I am ExampleClass2
protectedFunction: I am ExampleClass1
protectedFunction: I am ExampleClass2
protectedVirtualFunction: I am ExampleClass1