Monday, February 4, 2013

Turn your Face towards Interface and Interact with Abstract


This includes questions related to interfaces and abstract classes,marker interfaces.
 INTERFACE : 
1. Interface in java is declared using keyword interface and it represent a Type like any Class in Java. a reference variable of type interface can point to any implementation of that interface in Java. Its also a good Object oriented design principle to "program for interfaces than implementation" because when you use interface to declare reference variable, method return type or method argument you are flexible enough to accept any future implementation of that interface which could be much better and high performance alternative of current implementation. similarly calling any method on interface doesn't tie you with any particular implementation and you can leverage benefit of better or improved implementation over time. This maintenance aspect of interface is also sought in various software design interview questions in Java.
 2) All variables declared inside interface is implicitly public final variable or constants. which brings a useful case of using Interface for declaring Constants. We have used both Class and interface for storing application wide constants and advantage of using Interface was that you can implement interface and can directly access constants without referring them with class name which was the case earlier when Class is used for storing Constants. Though after introduction of static imports in Java 5 this approach doesn't offer any benefit over Class approach.
 3) All methods declared inside Java Interfaces are implicitly public and abstract, even if you don't use public or abstract keyword. you can not define any concrete method in interface. That's why interface is used to define contracts in terms of variables and methods and you can rely on its implementation for performing job.
 4) In Java its legal for an interface to extend( not implement ) multiple interface.

 MARKER INTERFACE : 
 Marker interface in Java is interfaces with no field or methods or in simple word empty interface in java is called marker interface. Looking carefully on marker interface in Java e.g. Serializable, Clonnable and Remote it looks they are used to indicate something to compiler or JVM. So if JVM sees a Class is Serializable it done some special operation on it, similar way if JVM sees one Class is implement Clonnable it performs some operation to support cloning. Same is true for RMI and Remote interface. So in short Marker interface indicate, signal or a command to Compiler or JVM. This is pretty standard answer of question about marker interface and once you give this answer most of the time interviewee definitely asked "Why this indication can not be done using a flag inside a class?” this make sense right? Yes this can be done by using a boolean flag or a String but doesn't marking a class like Serializable or Clonnable makes it more readable and it also allows to take advantage of Polymorphism in Java. From java 1.5, the need for marker interface is eliminated by the introduction of the java annotation feature. So, it is wise to use java annotations than the marker interface. It has more feature and advantages than the java marker interface.

ABSTRACT CLASS:
An abstract class can never be instantiated. Its sole
purpose, mission in life, raison d'être, is to be extended (subclassed). (Note, how-
ever, that you can compile and execute an abstract class, as long as you don't try
Class Declarations and Modifiers
to make an instance of it.) Why make a class if you can't make objects out of it?
Because the class might be just too, well, abstract. For example, imagine you have
a class Car that has generic methods common to all vehicles. But you don't want
anyone actually creating a generic, abstract Car object. How would they initialize its
state? What color would it be? How many seats? Horsepower? All-wheel drive? Or
more importantly, how would it behave? In other words, how would the methods be
implemented?
No, you need programmers to instantiate actual car types such as BMWBoxster
and SubaruOutback. We'll bet the Boxster owner will tell you his car does things
the Subaru can do "only in its dreams." Take a look at the following abstract class:

abstract class Car {
private double price;
private String model;
private String year;
public abstract void goFast();
public abstract void goUpHill();
public abstract void impressNeighbors();
// Additional, important, and serious code goes here

}



DIFFERENCE BETWEEN INTERFACE AND ABSTRACT CLASS:
■ All interface methods are implicitly public and abstract. In other words, you do not need to actually type the public or abstract modifiers in the method declaration, but the method is still always public and abstract.
■ All variables defined in an interface must be public, static, and final— in other words, interfaces can declare only constants, not instance variables. Declaring an Interface.
■ Interface methods must not be static.
■ Because interface methods are abstract, they cannot be marked final, strictfp, or native. (More on these modifiers later.)
■ An interface can extend one or more other interfaces.
■ An interface cannot extend anything but another interface.
■ An interface cannot implement another interface or class.
■ An interface must be declared with the keyword interface.
■ Interface types can be used polymorphically.
■ Another notable difference between interface and abstract class is that when you add a new method in existing interface it breaks all its implementation and you need to provide an implementation in all clients which is not good. By using abstract class you can provide default implementation in super class.







Deciding when to use interface and abstract class?
This is a famous question which is there from the days managed languages avoided multiple inheritance. Mainly C# and Java. They brought a new concept called interface to deal with multiple inheritance. (I don't know whether this is introduced by some other language).From those days a new question entered into almost all the technical interviews related to C#,.net and Java. The question is nothing but "What is the difference between interface and abstract class?" which is covered in almost all interview question answersites.

If the candidate is just out of college and had completed any C# / Java course his answer will be
1 ) Interface is created using the keyword 'interface' and abstract class by 'abstract'
2)  Interface cannot have implementation.Some methods in abstract class can have function body.
'Have you used interface in your academic projects?' will almost make him silent.

The candidate who has got experience in using interfaces will say

  • All the methods in interface needs to be implemented.
  • Interfaces are using to implement contracts for eg WCF contract should be interface decorated with  DataContract attribute.
If he has created interface in any of his programs he will say
  • We cannot declare variables in interface.
  • Interfaces don't allow constructors.
  • Interfaces cannot have static members.
  • There is no need to specify access modifies in interface.
  • Interfaces can inherit from interface only where abstract class can be created from interfaces as well as another class.
More advanced programmers will add some more items
  • Interfaces are used to implement multiple inheritance.
  • Interfaces can be implemented by structures.
  • C# allows us to have 2 methods with same signature in single class provided one method is implemented as explicit interface method.
But if you ask even the advanced programmers "What is the ultimate factor which makes you to create an interface or abstract class?" they will be little confused.ie Forget about multiple inheritance and structures.We don't know whether an entity is going to be used in multiple inheritance scenario or not .Also we don't know whether there needs a common base class method implementation.

The answer is simple.

If an object is related to another object using "Is-A" relationship use abstract class. If the object is related to another as "Can-Be" use interface.

eg: Parrot Is-A Bird.Parrot Can fly.Pigeon is-a Bird and it can also fly.Duck is-a Bird .But it cannot fly.Here Is-A decides the need forabstract base class 'Bird'.'Flyable' is a Can-Be behavior. We cannot say all birds can fly. So the Can-Be behavior translate to interface 'IFlyable' or simply 'Flyable'. It would be more clear if we take the case of a Helicopter. It Can fly.But it is not a Bird.

We can conclude as "Use interface if its a behavior.Abstract class in case of common features."


Project That explains everything:





package com.packageone;

public abstract interface AbstractInterface {

/*Interfaces and their methods are implicitly abstract and adding that modifier makes no difference.Is there other rules that applies with an abstract interface?
No, same rules applies. The method must be implemented by any 
(concrete) implementing class.If abstract is obsolete, why is it included in Java?
 Is there a history for abstract interface?
Interesting question. I dug up the first edition of JLS, 
and even there it says "This modifier is 
obsolete and should not be used in new Java programs".

Okay, digging even further... After hitting numerous broken links, 
I managed to find a copy of 
the original Oak 0.2 Specification (or "manual http://www.devx.com/Java/Article/10686"). 
Quite interesting read I must say, and only 38 pages in total! :-)

 Under Section 5, Interfaces, it provides the following example:
 public interface Storing {
     void freezeDry(Stream s) = 0;
     void reconstitute(Stream s) = 0;
 }

 And in the margin it says
 In the future, the " =0" part of declaring methods in interfaces may go away.=
 Assuming =0 got replaced by the abstract keyword, I suspect that abstract was at some point mandatory for interface methods!*/
}
===============================END OF CLASS==========================

package com.packageone;

interface I1 {

  void methodI1(); // public static by default
 }

 interface I2 extends I1 {

  void methodI2(); // public static by default
 }

 class A1 {

  public String methodA1() {
   String strA1 = "I am in methodC1 of class A1";
   return strA1;
  }
  public String toString() {
   return "toString() method of class A1";
  }
 }

 class B1 extends A1 implements I2 {

  public void methodI1() {
   System.out.println("I am in methodI1 of class B1");
  }
  public void methodI2() {
   System.out.println("I am in methodI2 of class B1");
  }
 }

 class C1 implements I2 {

  public void methodI1() {
   System.out.println("I am in methodI1 of class C1");
  }
  public void methodI2() {
   System.out.println("I am in methodI2 of class C1");
  }
 }

 // Note that the class is declared as abstract as it does not
 // satisfy the interface contract
 abstract class D1 implements I2 {

  public void methodI1() {
  }
  // This class does not implement methodI2() 
            hence declared abstract.
 }
===================END OF CLASS================================

package com.packageone;

import com.packagetwo.ExtendStaticAbstract;

public class MainClass {
 
   public static void main(String[] args) {
   
    I1 i1 = new B1();
    i1.methodI1(); // OK as methodI1 is present in B1

     // i1.methodI2(); Compilation error as methodI2 not present in I1

    // Casting to convert the type of the reference from type I1 to type I2
    ((I2) i1).methodI2();

    I2 i2 = new B1();

    i2.methodI1(); // OK

    i2.methodI2(); // OK

 // Does not Compile as methodA1() not present in interface reference I1

 // String var = i1.methodA1();
       // Hence I1 requires a cast to invoke methodA1

    String var2 = ((A1) i1).methodA1();
    System.out.println("var2 : " + var2);

    String var3 = ((B1) i1).methodA1();
    System.out.println("var3 : " + var3);

    String var4 = i1.toString();
    System.out.println("var4 : " + var4);

    String var5 = i2.toString();
    System.out.println("var5 : " + var5);

    I1 i3 = new C1();
    String var6 = i3.toString();
    System.out.println("var6 : " + var6); // It prints the Object toString() method

    Object o1 = new B1();

    // o1.methodI1(); does not compile as Object class does not define
    // methodI1()
    // To solve the probelm we need to downcast o1 reference. We can do it
    // in the following 4 ways

    ((I1) o1).methodI1(); // 1
    ((I2) o1).methodI1(); // 2
    ((B1) o1).methodI1(); // 3

    /*
     *
     * B1 does not have any relationship 
                      with C1 except they are "siblings".
     *
     * Well, you can't cast siblings into one another.
     *
     */
    // ((C1)o1).methodI1(); Produces a ClassCastException
   }
}
=========================END OF CLASS================================

package com.packageone;

public class Point implements Shape {

  static int x, y;
  public Point() {
   x = 0;
   y = 0;
  }
  public double area() {
   return 0;
  }
  public double volume() {
   return 0;
  }
  public static void print() {
   System.out.println("point: " + x + "," + y);
  }
  public static void main(String args[]) {
   Point p = new Point();
   p.print();
   p.volume(3);
  }
  
 @Override
 public double volume(int a) {
 System.out.println("overloaded method in interface");
  return a;
 }
 }
========================END OF CLASS=================================

package com.packageone;

interface Shape {
 
 //only public access modifier is allowed in interface but that has to be initialized
 // by default it is static final too
  public  int a = 1;
  
 // no need to write abstract its by default abstract 
  public abstract double area();
  public double volume();
  public double volume(int a);
 }

=============================END OF CLASS============================

package com.packagetwo;

public class Car extends Vehicle{

 @Override
 boolean hasDiskBrake() {
 System.out.println("Abstract method  hasDisKBrake called");
  
 return true;
 }

 @Override
 int getNoofGears() {
 System.out.println("Abstract method getNoofGears called and the num "+numofGears);
 return numofGears;
 }

 @Override
 public void foo() {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void bar() {
  // TODO Auto-generated method stub
  
 }

 @Override
 void someMethod() {
  // TODO Auto-generated method stub
  
 }

}
=============================END OF CLASS============================
package com.packagetwo;

public class ExtendStaticAbstract extends  StaticAbstract.Nested{

 @Override
 void someMethod() {
System.out.println("This the implementation for static abstract method");
  
 }
/*
 * The class which is extending the abstract class which implements 
    the interface has to override 
 * its methods
 * */
 @Override
 public void foo() {
 System.out.println("Method of an interface foo() called");
  
 }

 @Override
 public void bar() {
 System.out.println("Method of an interface bar() called");
  
 }
 
 

}

=========================END OF CLASS================================

package com.packagetwo;
/*
 * Similarly, if an interface inherits more than one method with the same signature, 
 * or if a class implements different interfaces containing a method with the same 
 * signature, there is only one such method. 
 * The implementation of this method is ultimately defined by the 
   class implementing the interfaces, and there is no ambiguity there. 
   If the methods have the same signature but different return types, 
   then one of the return types must be a subtype of all the others, 
   otherwise a compile-time error occurs. The implementation must define a 
   method that returns that common subtype."
 
 *   Justification is below
 */
public interface InterfaceA {
    public int methodA();
    public Number methodB();
    // public int methodC(); // conflicting return type
}

interface InterfaceB {
    public int methodA();
    public Integer methodB();
    // public String methodC(); // conflicting return type
}

 class ImplementationOfAandB implements InterfaceA, InterfaceB {
    public int methodA() {
        return 0;
    }
    public Integer methodB() {
        return null;
    }
    // This would NOT work:
    // public Double methodB() {
    //     return null;
    // }
}
 
 //JUSTIFICATION :
/* In the following two interfaces methodA() is identically defined in terms of 
   parameters (none) and return type (int). The implementation class at the bottom 
   defines a single method with this exact signature. As it complies to both interfaces, 
  you get no problem there - any calls made via a reference of type InterfaceA or 
  InterfaceB will be dispatched to this implementation.The second methodB() is defined as 
  returning any subtype of Number (or Number itself) in InterfaceA. InterfaceB defines 
  methodB() as returning an Integer which is a subtype of Number. The implementation class 
  actually implements the method with Integer, thus complying to the contract of both InterfaceA 
  and InterfaceB. No problem here either. The commented out case of methodB() being implemented 
  as returning a Double however would not work: While it would satisfy the contract of 
  InterfaceA, it would conflict with InterfaceB (which demands an Integer).If InterfaceA and 
  InterfaceB were also specifying (different) contracts for a methodC() (commented out in the example) 
  this would be contradictory and create a compiler error. Implementing both signatures (differing only 
  in return type) is not allowed in Java.
  The above rules would also hold true if were to add any parameters to the methods. For simplicity I kept this out of the example
 */

================================END OF CLASS=========================

package com.packagetwo;

interface InterfaceToBeImplemented {

 void foo();
 void bar();
 
}

======================END OF CLASS===================================

package com.packagetwo;

public class MainClass2 {
 public static void main(String[] args) {
 ExtendStaticAbstract eSA = new ExtendStaticAbstract();
 eSA.someMethod(); //OK
 ExtendStaticAbstract.method1();  // OK
 eSA.method2();                   // Ok
// ExtendStaticAbstract.method2();  // Not allowed
 StaticAbstract.Nested.method1(); //OK
 
 eSA.foo();
 eSA.bar();

 
 Car car = new Car();
 
 car.numofGears=2;// default access modifier of abstract class
 car.b = 3; // protected access modifier of abstract class
 car.color = "red"; // default access modifier of abstract class
 Car.c = 4; // public static  access modifier of abstract class
 
  /*
   * NOTE: you cann't instantiate an abstract class but you can create an anonymous inner class 
   * and use its method  
   */

 Vehicle v = new Vehicle() {
  
  @Override
  boolean hasDiskBrake() {
   // TODO Auto-generated method stub
   return false;
  }
  
  @Override
  int getNoofGears() {
   // TODO Auto-generated method stub
   return 0;
  }

  @Override
  public void foo() {
   // TODO Auto-generated method stub
   
  }

  @Override
  public void bar() {
   // TODO Auto-generated method stub
   
  }

  @Override
  void someMethod() {
   // TODO Auto-generated method stub
   
  }

  
 };
//===================END OF CONCEPT=====================================
 /*
  * NOTE: you cann't instantiate an Interface but you can create 
           an anonymous inner class 
  * and use its method  
  */

 InterfaceToBeImplemented in = new InterfaceToBeImplemented() {
  
  @Override
  public void foo() {
   // TODO Auto-generated method stub
   
  }
  
  @Override
  public void bar() {
   // TODO Auto-generated method stub
   
  }
 };
 
  }
}

===========================END OF CLASS==============================

package com.packagetwo;

public class StaticAbstract {

  // A static abstract class  
    public static abstract class Nested  implements InterfaceToBeImplemented{
     
    //NOTE : while implementing interface it didn't ask to override its declared methods
    //But if StaticAbstract class implemented the interface it would ask to override 
    // its declared methods.
     
        abstract void someMethod();  
        
        public static void method1(){
        System.out.println("This is the implemented static method in abstract static class");
        }
        public void method2(){
        System.out.println("This is the implemented non static method in abstract static class");
        }
    }  
 
}


/*
 * Can abstract class be static ?
 *  you can't. you can't get an Instantce of a abstract class or method. 
    abstract methods are only declared but not implmented. 
  if you use static key word, can you call a method like:
  " public void method(); " without Methods body? 
  so you can do nothing like "ClassName.method()"
 *  
 But you can use below
 * class Outer {  
    // A static abstract class  
    public static abstract class Nested {  
        abstract void someMethod();  
    }  
}
 * */
 
=================================END OF CLASS========================

package com.packagetwo;

abstract  class Vehicle extends StaticAbstract.Nested{

 
  int numofGears;
  String color;
  private int a;
  protected int b;
  public static int c;
  abstract boolean hasDiskBrake();
  abstract int getNoofGears();
  
  
 }
================================END OF CONCEPT======================

No comments:

Post a Comment