Tuesday, November 4, 2014

Covariant, Contravariant and Invariant (class invariant) in Java

Type variance is another feature which defines the flexibility in code writing every of programming language. Let me show you some of the variant type jargon's which explains the type variance.

When ever we are talking about type variance,
we end up with explaining about sub-typing which is again inheritance. Because the above stated jargon's Covariant, Contravariant can clearly explain only with sub-typing and we use there terms in the context of Overloading and overriding Sticking to one language, examples shown below explains Covariance,Contravariance in Java. We will discuss Invariance later. The basic principle of there type variance is (quote from wikipedia)

If Cat is Subtype of Animal, then an expression of type Cat can be used whenever an expression of type Animal could.

Based on the above principle let see how the type has been divided and what actually it is.


Covariance:


Consider you have Parent and Child relationship and trying to override the methods of Parent in Child, Co-variance means that the overriding method returning a more specific type. Below example shows you the same, Parent method returning Object and where as the Child method decided to return a specific type (String) where String is child of Object class. Hence covariance existed here.

Covariant return type :

public class Parent{  
  public Object doSomething(){}  
 }  
 public class Child extends Parent{  
  public String doSomething() {}  
 }

Covariant arg type :

public class Codeinventions {  
      public static void print(Object[] arg) {  
           for (Object object : arg) {  
                System.out.println(object);  
           }  
      }  
      public static void main(String[] args) {  
           String[] strs = { "Java", "Codeinventions" };  
           print(strs);  
      }  
 }  
 Result :  
 Java  
 Codeinventions  

So, it is clear that we can pass a Sub-type where a Parent needed, since Every Child is a Parent. Yes Java supports it. And the same logic works in Generics as well.

Contravariance:


Contravariance is just reverse to Covariance. Passing exact type to the required place. There will be no flexibility in coding. But useful to avoid run time problem since you are being forced to stick to the exact type.

When you want to pass a Parent where Child is required, that's Contravariance and many languages won't allow you to do it. At least in Java I can confirm you that, it is not allowed to do so. Look at the Contravariance shown in below, and you end up with the error "The method print(String) in the type ParentClass is not applicable for the arguments (Object)". 
public class ParentClass {  
      public static void print(String str) {  
           System.out.println(str);  
      }  
      public static void main(String[] args) {  
           Object str = "Codeinventions";  
           print(str);  //compiler error here 
      }  
 }  
Form the compiler error shown above, there is no way of supporting Contravariance in Java.

Invriant (class invariant):


Invariant  or variance is something which is always true no matter what the context is. 

Variant or Variance is not just a unchanged variable it's more of a term which used to represent something which never changed what so ever it's context, Let me explain you the same with respect to Java with help of a Class called as Class Invariance. Consider there is a class called  Account and have a holder in itNow, Invariance or Class Invariance is, no matter where the Account being use in the program the state of the invariant holder will be satisfies some conditions(always true) at any context. That's the design decision to make which variable is invariant in the program. 
 Class Account {  
 private AccountHolder holder = new AccountHolder();  
 }
If you see in the above code making  holder an invariant mean that no matter what the state of Account, my holder always holds some properties which are never be changed in normal conditions. May change in special conditions but with notifying to the owner.

There invariant's are useful or comes into picture while designing the program and for programmers while debugging the program. Consider at some point you are getting some weird results from a method and trying to debug your program, the basic principle you need to apply is see any invariant's are gone change and proceeding your debug keeping in mind these class invariant's so that it makes your debug easy as well.
Post a Comment