Tuesday, November 17, 2015

Diamond Problem



In the diagram above, we have 2 classes B and C that derive from the same class – which would be class A in the diagram above. We also have class D that derives from both B and C by using multiple inheritance. You can see in the figure above that the classes essentially form the shape of a diamond – which is why this problem is called the diamond problem.
The problem with having an inheritance hierarchy like the one shown in the diagram above is that when we instantiate an object of class D, any calls to method definitions in class A will be ambiguous – because it’s not sure whether to call the version of the method derived from class B or class C.

Java does not have multiple inheritance

But, wait one second. Java does not have multiple inheritance! This means that Java is not at risk of suffering the consequences of the diamond problem. However, C++ does have multiple inheritance

Java does have interfaces

Java has interfaces which do allow it to mimic multiple inheritance. Although interfaces give us something similar to multiple inheritance, the implementation of those interfaces is singly (as opposed to multiple) inherited. This means that problems like the diamond problem – in which the compiler is confused as to which method to use – will not occur in Java.

Method Overloading vs Method Overriding

The difference between overriding and overloading in Java is a common source of confusion – but it is fairly easy to understand with the examples we present below. Let’s start the discussion by talking more about method overloading first. Method overloading in Java occurs when two or more methods in the same class have the exact same name but different parameters (remember that method parameters accept values passed into the method). Now, two or more methods with the same name in the same class sounds simple enough to understand. But, what do we mean exactly by different parameters? Well, let’s consider a very simple example.

Suppose we have a class called TestClass which has two methods, and both methods have the same name. Let’s say that name is “someMethod”. Those two methods would be considered to be “overloaded” if if one or both of these conditions is true:

The conditions for method overloading

1.) The number of parameters is different for the methods.
2.) The parameter types are different (like 
changing a parameter that was a float to an int). 
 

How to NOT overload methods:

It’s also very important to understand that method overloading is NOT something that can be accomplished with either, or both, of these two things:
1. Just changing the return type of the method. If the return type of the method is the only thing changed, then this will result in a compiler error. 
2. Changing just the name of the method parameters, but not changing the parameter types. If the name of the method parameter is the only thing changed then this will also result in a compiler error.
 

Confused? Well, here are some very helpful examples of where overloading would be both valid and invalid – pay attention to the comments as well:

Examples of Method Overloading in Java – both valid and invalid:

//compiler error - can't overload based on the   
//type returned -
//(one method returns int, the other returns a float):    

int changeDate(int Year) ;  
float changeDate (int Year);    

//compiler error - can't overload by changing just 
//the name of the parameter (from Year to Month):    

int changeDate(int Year);   
int changeDate(int Month) ;  
 
//valid case of overloading, since the methods
//have different number of parameters:        

int changeDate(int Year, int Month) ;  
int changeDate(int Year);    

//also a valid case of overloading, since the   
//parameters are of different types:    

int changeDate(float Year) ;  
int changeDate(int Year);  

Overloading happens at compile time

Another important point to remember is that overloading is a compile time phenomenon. This just means that the compiler determines whether a given method(s) is correctly overloaded, and if not a compiler error is returned as shown in the examples above.

What about method overriding?


Overriding methods is completely different from overloading methods. If a derived class requires a different definition for an inherited method, then that method can be redefined in the derived class. This would be considered overriding. An overridden method would have the exact same method name, return type, number of parameters, and types of parameters as the method in the parent class, and the only difference would be the definition of the method.

Example of method overriding

Let’s go through a simple example to illustrate what method overriding would look like:
public class Parent {

 public int someMethod() {
   
   return 3;
       
    }
}


public class Child extends Parent{

 // this is method overriding:
 public int someMethod() {

    return 4;
       
    }

}

In the sample code above, someMethod is an overridden method in the Child class, because it has the exact same name, number of parameters, and return type as the someMethod method defined inside it’s parent class (conveniently named Parent).

Overriding happens at run time

Another important point to remember is that overriding is a run time phenomenon – not a compile time phenomenon like method overloading.
PD9waHAgaW5jbHVkZSAoJ2Fkc2Vuc2UtbWVkLXJlY3QyMDE0LnBocCcpOyA/Pg==

Summary of differences between overloading and overriding

Let’s summarize the differences between overloading and overriding. When overloading, one must change either the type or the number of parameters for a method that belongs to the same class. Overriding means that a method inherited from a parent class will be changed. But, when overriding a method everything remains exactly the same except the method definition – basically what the method does is changed slightly to fit in with the needs of the child class. But, the method name, the number and types of parameters, and the return type will all remain the same.
And, method overriding is a run-time phenomenon that is the driving force behind polymorphism. However, method overloading is a compile-time phenomenon.

Association, Aggregation, Composition, Abstraction, Generalization, Realization, Dependency

In Object-oriented programming, one object is related to other to use functionality and service provided by that object. This relationship between two object is known as association in  object oriented general software design

Both Composition and Aggregation are form of association between two objects, but there is subtle difference between composition and aggregation

Association

Association is a relationship between two objects. In other words, association defines the multiplicity between objects. You may be aware of one-to-one, one-to-many, many-to-one, many-to-many all these words define an association between objects. Aggregation is a special form of association. Composition is a special form of aggregation.

Example: A Student and a Faculty are having an association.

Aggregation

Aggregation is a special case of association. A directional association between objects. When an object ‘has-a’ another object, then you have got an aggregation between them. Direction between them specified which object contains the other object. Aggregation is also called a “Has-a” relationship.

Composition

Composition is a special case of aggregation. In a more specific manner, a restricted aggregation is called composition. When an object contains the other object, if the contained object cannot exist without the existence of container object, then it is called composition.

Example: A class contains students. A student cannot exist without a class. There exists composition between class and students.

Difference between aggregation and composition

Composition is more restrictive. When there is a composition between two objects, the composed object cannot exist without the other object. This restriction is not there in aggregation. Though one object can contain the other object, there is no condition that the composed object must exist. The existence of the composed object is entirely optional. In both aggregation and composition, direction is must. The direction specifies, which object contains the other object.
Example: A Library contains students and books. Relationship between library and student is aggregation. Relationship between library and book is composition. A student can exist without a library and therefore it is aggregation. A book cannot exist without a library and therefore its a composition. For easy understanding I am picking this example. Don’t go deeper into example and justify relationships!


Abstraction

Abstraction is specifying the framework and hiding the implementation level information. Concreteness will be built on top of the abstraction. It gives you a blueprint to follow to while implementing the details. Abstraction reduces the complexity by hiding low level details.

Generalization

Generalization uses a “is-a” relationship from a specialization to the generalization class. Common structure and behaviour are used from the specializtion to the generalized class. At a very broader level you can understand this as inheritance. Why I take the term inheritance is, you can relate this term very well. Generalization is also called a “Is-a” relationship.

Example: Consider there exists a class named Person. A student is a person. A faculty is a person. Therefore here the relationship between student and person, similarly faculty and person is generalization.

Realization

Realization is a relationship between the blueprint class and the object containing its respective implementation level details. This object is said to realize the blueprint class. In other words, you can understand this as the relationship between the interface and the implementing class.

Example: A particular model of a car ‘Hyundai’ that implements the blueprint of a car realizes the abstraction.

Dependency

Change in structure or behaviour of a class affects the other related class, then there is a dependency between those two classes. It need not be the same vice-versa. When one class contains the other class it this happens.

Example: Relationship between shape and circle is dependency.

Java Generics

Generics was added in Java 5 to provide compile-time type checking and removing risk of ClassCastException that was common while working with collection classes. The whole collection framework was re-written to use generics for type-safety. Let’s see how generics help us using collection classes safely.

In the heart of generics is “type safety“. What exactly is type safety? It’s just a guarantee by compiler that if correct Types are used in correct places then there should not be any ClassCastException in runtime. A usecase can be list of Integer i.e. List. If you declare a list in java like List, then java guarantees that it will detect and report you any attempt to insert any non-integer type into above list.
Another important term in java generics is “type erasure“. It essentially means that all the extra information added using generics into sourcecode will be removed from bytecode generated from it. Inside bytecode, it will be old java syntax which you will get if you don’t use generics at all. This necessarily helps in generating and executing code written prior java 5 when generics were not added in language.

Let’s understand with an example.
List list = new ArrayList();
 
list.add(1000);     //works fine
 
list.add("mukesh"); //compile time error;
When you write above code and compile it, you will get below error: “The method add(Integer) in the type List is not applicable for the arguments (String)“. Compiler warned you. This exactly is generics sole purpose i.e. Type Safety.

Second part is getting byte code after removing second line from above example. If you compare the bytecode of above example with/without generics, then there will not be any difference. Clearly compiler removed all generics information. So, above code is very much similar to below code without generics.
List list = new ArrayList();
 
list.add(1000);  


In generic code, the question mark (?), called the wildcard, represents an unknown type. A wildcard parameterized type is an instantiation of a generic type where at least one type argument is a wildcard. Examples of wildcard parameterized types are Collection, List, Comparator and Pair. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
Having wild cards at difference places have different meanings as well. e.g.
  • Collection denotes all instantiations of the Collection interface regardless of the type argument.
  • List denotes all list types where the element type is a subtype of Number.
  • Comparator denotes all instantiations of the Comparator interface for type argument types that are supertypes of String.
A wildcard parameterized type is not a concrete type that could appear in a new expression. It just hints the rule enforced by java generics that which types are valid in any particular scenario where wild cards have been used.
For example, below are valid declarations involving wild cards:

Collection coll = new ArrayList();
//OR
Listextends Number> list = new ArrayList();
//OR
Pair pair = new Pair();
And below are not valid uses of wildcards, and they will give compile time error.
Listextends Number> list = new ArrayList();  //String is not subclass of Number; so error
//OR
Comparatorsuper String> cmp = new RuleBasedCollator(new Integer(100)); //String is not superclass of Integer
Wildcards in generics can be unbounded as well as bounded. Let’s identify the difference in various terms.

Unbounded wildcard parameterized type

A generic type where all type arguments are the unbounded wildcard “?” without any restriction on type variables. e.g.
ArrayList  list = new ArrayList(); 
//or
ArrayList  list = new ArrayList(); 
//or
ArrayList  list = new ArrayList(); 

Bounded wildcard parameterized type

Bounded wildcards put some restrictions over possible types, you can use to instantiate a parametrized type. This restriction is enforced using keywords “super” and “extends”. To differentiate more clearly, let’s devide them into upper bounded wildcards and lower bounded wildcards.

Upper bounded wildcards
For example, say you want to write a method that works on List, List, and List; you can achieve this by using an upper bounded wildcard e.g. you would specify List. Here Integer, Double are subtypes of Number class. In layman’s terms, if you want generic expression to accept all subclasses of a particular type, you will use upper bound wildcard using “extends” keyword.
public class GenericsExample
{
   public static void main(String[] args)
   {
      //List of Integers
      List ints = Arrays.asList(1,2,3,4,5);
      System.out.println(sum(ints));
       
      //List of Doubles
      List doubles = Arrays.asList(1.5d,2d,3d);
      System.out.println(sum(doubles));
       
      List strings = Arrays.asList("1","2");
      //This will give compilation error as :: The method sum(List) in the
      //type GenericsExample is not applicable for the arguments (List)
      System.out.println(sum(strings));
       
   }
    
   //Method will accept
   private static Number sum (Listextends Number> numbers){
      double s = 0.0;
      for (Number n : numbers)
         s += n.doubleValue();
      return s;
   }
}

Lower bounded wildcards
If you want a generic expression to accept all types which are “super” type of a particular type OR parent class of a particular class then you will use lower bound wildcard for this purpose, using ‘super’ keyword.
In below given example, I have created three classes i.e. SuperClass, ChildClass and GrandChildClass. There relationship is shown in code below. Now, we have to create a method which somehow get a GrandChildClass information (e.g. from DB) and create an instance of it. And we want to store this new GrandChildClass in an already existing list of GrandChildClasses.
Here problem is that GrandChildClass is subtype of ChildClass and SuperClass as well. So any generic list of SuperClasses and ChildClasses is capable of holding GrandChildClasses as well. Here we must take help of lower bound wildcard using ‘super‘ keyword.
package test.core;
 
import java.util.ArrayList;
import java.util.List;
 
public class GenericsExample
{
   public static void main(String[] args)
   {
      //List of grand children
      List grandChildren = new ArrayList();
      grandChildren.add(new GrandChildClass());
      addGrandChildren(grandChildren);
       
      //List of grand childs
      List childs = new ArrayList();
      childs.add(new GrandChildClass());
      addGrandChildren(childs);
       
      //List of grand supers
      List supers = new ArrayList();
      supers.add(new GrandChildClass());
      addGrandChildren(supers);
   }
    
   public static void addGrandChildren(Listsuper GrandChildClass> grandChildren)
   {
      grandChildren.add(new GrandChildClass());
      System.out.println(grandChildren);
   }
}
 
class SuperClass{
    
}
class ChildClass extends SuperClass{
    
}
class GrandChildClass extends ChildClass{
    
}

What is not allowed to do with Generics?

a) You can’t have static field of type
b) You can not create an instance of T
c) Generics are not compatible with primitives in declarations
d) You can’t create Generic exception class
,

Abstract Class vs Interface

Abstract class

Abstract classes are created to capture common characteristics of subclasses. It can not be instantiated, it can be only used as super class by its subclasses. Abstract classes are used to create template  for its sub classes down the hierarchy. 

Abstract is object oriented. It offer the basic data an 'object' should have and/or functions it should be able to do. It concerns on the object's basic characteristic, what it has and what it can do. Hence objects which inherit the same abstract share the basic characteristics (generalization).

Interface

An interface is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. So it is kind of signing a contract, you agree that if you implement this interface, then you have to use its methods. It is just a pattern, it can not do anything itself. 

Interface is functionality oriented. It defines functionalities an object should have. Regardless what object it is, as long as it can do this and that (functionalities defined in interface), it's fine. It ignores any other things. An object/class can contain several (group of) functionalities, hence it is possible for a class to implement multiple interfaces.















 

When to use Abstract class and interface:

  • If you have a lot of methods and want default implementation for some of them, then go with abstract class
  • If you want to implement multiple inheritance then you have to use interface. As java does not support multiple inheritance, subclass can not extend more than one class but you can implement multiple interface so you can use interface for that.
  • If your base contract keeps on changing, then you should use abstract class, as if you keep changing your base contract and use interface, then you have to change all the classes which implements that interface.