September 4, 2011

Apex inheritance – Extending managed package abstract/virtual classes & interfaces !

In my recent project, I came across a requirement to create a base class in a managed package with child extension packages would extend to add their value to it.

Before starting the actual work, I thought of googling about experiences of force.com community members about the same. Interestingly I found one relevant link only i.e. this force.com discussion board question. I became doubtful about this working after reading this post, so thought of giving a quick try, before doing it for our customers. The good news in advance is that “this managed package inheritance works”. The fixture for this POC experiment is explained below.

Fixture for this experiment !

In a top level global class, all 3 types of inheritance forms are created as shown below

global class ManagedPackageInheritance {
   // Virtual Class
    global virtual class VirtualClass {
        global virtual void foo () {
            System.debug('#Foo from Managed Package !');
        }
    }
   
   // Interface
    global interface IInterface {
        void bar ();
    }
    
   // Abstract class
    global abstract class AbstractClass {    
        global abstract void foo() ;
    }
}

Inheriting from Managed package apex classes.

The above test fixture was packaged. This package was uploaded as a managed package with namespace prefix “abhinav” and was installed in some other salesforce DE org.

Here we created following child classes implementing/extending all the parent classes/interfaces in the managed package. Everything seems to be working fine, including calling parent class method using super.methodName(). All code shown below :

                        
// Extend Virtual class in managed package
global class PlayVirtualInheritance extends abhinav.ManagedPackageInheritance.VirtualClass {
   // override the virtual method
   global override void foo() {
    super.foo();
        System.debug('#Foo from Target Org !');
    }
}

// Implement interface in managed package
global class PlayInterfaceInheritance implements abhinav.ManagedPackageInheritance.IInterface {
    global void bar() {
    }
}

// Extend Abstract class in managed package
global class PlayAbstractInheritance extends abhinav.ManagedPackageInheritance.AbstractClass {
    global override void foo() {
        System.debug('#Foo from Target Org !');
    }
}

Please Note !

Inheritance in managed package, works but comes with two very important and strange warning(link to apex doc), shown below :

  • Classes defined with either virtual or abstract cannot also be defined as global in Developer Edition organizations. They can be defined as global in sandbox organizations. Only private and public classes can be defined as either virtual or abstract in Developer Edition organizations. However, a class defined as global can extend virtual or abstract classes in either Developer Edition organizations or sandboxes.
    • Abhinav: Strange, as I was able to create global classes both virtual & abstract from a DE org. The same was packaged as managed released. Seems this restriction is no more applicable. Salesforce team please confirm ?
  • You cannot add a method to an abstract or virtual class after the class has been uploaded in a Managed - Released package version. For more information about managed packages, see Developing Apex in Managed Packages.
    • Abhinav: This is very much true, so please do a lot for brain storming before finalizing design of classes and packaging it as managed released.

Feedback

Looking forward for your views and experiences on this topic !