February 8, 2010

Apex virtual abstract inheritance versus java inheritance !

Apex is said to be inspired from java. But if we compare the polymorphic behavior specially inheritance, apex inheritance is reciprocal of java inheritance. The difference can be stated in following one line

In Java we declare what methods can’t be overridden by the child classes VS Apex declares which methods can be overridden !

For example  in Java we use “final” keyword to stop overriding by child classes, this applies to both classes and methods. But in apex to make a class/method inheritable we have to declare it either “virtual” or “abstract”. So in Java one declares “What you can’t extend”, and in Apex you declare “What you can extend”.

Cons of Apex’s “what you can extend” philosophy 

  • Many times design evolve during coding. You create a bunch of classes and later extend/inherit them to provide more specialization. This is quite easy if you are developing on your own, but if you are integrating with other’s api via managed packages, then you need to ask a new package release to extend some features. This can happen easily in case if we are distributing utility api’s or framework api’s written in apex as managed packages, developers might use many of those Api’s directly but extension/specialization might be required for some in many cases.
  • Classes should be open to specialization by default, if we want to restrict something from getting specialized we should restrict that only.
  • Apart from “What you can extend”, apex also requires you to add “override” keyword before the method you are specializing. That’s again kind of strange, the compiler or run time binding should be smart enough to detect that.

Here is a code sample below that explain the pain in doing a little Object oriented stuff in apex. Java developers know how simple this code will be in JAVA. This example illustrates a simple specialization of “ElectricDevice” class with “Fan”. Notice the use of “virtual” and “override

Apex Code inheritance Sample

public class Polymorphic {
 // PowerSupply class,
 // some stuff to setup and initialize a powersupply
 public class PowerSupply {}

 // Class must be virtual or abstract 
 // without this one can't extend it 
 public virtual class ElectricDevice {
  // Child implementations never need to change this.
  // CAN'T OVERRIDE 
  public void plugToPowerSupply(PowerSupply power) { 
   // Code to plugin to powersupply
  }
  
  // Default device stuff to turn it ON. 
  //Child implementations can change it
  public virtual void turnOn() {} 
  
  // Child implementations use this do there specifics,
  // after Turn ON.
  public virtual void postTurnOn(){}
  
  // Default device stuff to turn it OFF. 
  //Child implementations can change it
  public virtual void turnOff() {}   
 }
 
 public class Fan extends ElectricDevice {
  // overriden turnOn only
  public override void turnOn() {} 
  
  public override void postTurnOn() {
   // Code to start rotation of fan   
  }
 }
}

Java Code inheritance sample

This sample is to show, how simple the same code could be in Java. We just used "final" with plugToPowerSupply(), all other stuff is open to inheritance :)

public class Polymorphic {
 // PowerSupply class,
 // some stuff to setup and initialize a powersupply
 public class PowerSupply {}
 
 // No virtual or abstract 
 public class ElectricDevice {
  // Child implementations never need to change this.
  // CAN'T OVERRIDE 
                // NOTE: only "final" added here.
  public final void plugToPowerSupply(PowerSupply power) { 
   // Code to plugin to powersupply
  }
  
  // Default device stuff to turn it ON. 
  //Child implementations can change it
  public void turnOn() {} 
  
  // Child implementations use this do there specifics,
  // after Turn ON.
  public void postTurnOn(){}
  
  // Default device stuff to turn it OFF. 
  //Child implementations can change it
  public void turnOff() {}   
 }
 
 public class Fan extends ElectricDevice {
  // overriden turnOn only
  public void turnOn() {} 
  
  public void postTurnOn() {
   // Code to start rotation of fan   
  }
 }
}

Though Apex is a great language and is adding cool new features. But I wish the can really use java style inheritance.