1 2 Previous Next


18 posts

Java arrays in depth Blog

Posted by hellofadude Sep 26, 2014

If you have followed previous posts, you might begin to perceive a pattern in the semantics of the Java programming language. If not, it might help to go over previous posts as I tend to return to expand on previous topics or add clearer examples as time permits. Inner classes might at first seem like a whole new language to the uninitiated but they are a nice feature in Java that allow you to logically group related classes and control the visibility of one class from outside of the other.

Even more than that, inner classes provide you with the ability to inherit from more than one interface or implementation in a kind of "multiple implementation inheritance". The code in an inner class can be used to manipulate the members of the outer class within which it exists. Inner classes are not limited to the functionality of the base class of the outer class, but can inherit independently of it. Whereas outer classes allow you to undertake some kind of multiple inheritance with interfaces, inner classes allow you to do the same thing not only with interfaces but with abstract or concrete classes. This mechanism allows you to code solutions to some otherwise intractable programming problems. The syntax for creating inner classes is pretty straightforward:- package kingsley.java; public class Company {     class Employee {         private String name;         Employee(String name) {             this.name = name;         }         public String getName() {             return name;         }     }     class Department {         private String name;         Department (String name) {             this.name = name;         }         public String getName() {             return name;         }     }     public Employee employed(String name) {         return new Employee(name);     }     public Department department(String name) {         return new Department(name);     }     public void newStarter(String name, String department) {         Employee emp = employed(name);         Department dpt = department(department);         System.out.println(emp.getName() + " is a member of " + dpt.getName());     }     public static void main(String[] args) {         Company c = new Company();         c.newStarter("kingsley", "IT");         // Referencing inner classes         Company.Employee ce = c.employed();         Company.Department cd = c.department();     } } /* Output kingsley is a member of IT *// Here, the outer class Company has methods that return references to the inner classes Employee and Department. The newStarter() within the outer class is able to use inner classes like it would any other class, with the only difference being these classes are actually nested within Company. In the main() notice how we reference objects of the inner classes with OuterClassName.InnerClassName. This is necessary because objects of any non-static inner class can only be created in association with an object of the outer class, outside of any non-static method within the outer class. As a consequence, objects of the inner classes you create usually have access to all the private and protected members of the surrounding class without any special syntax. This is because when you create an inner class in Java, the compiler captures a reference to the particular enclosing class within which the inner class exists, thus making it possible to reference members of the enclosing class, in this way, a derived inner class can be used to manipulate the members of an enclosing class. The following example demonstrates this clearly:- package kingsley.osime; interface Repeater {     boolean start();     String current();     void next(); } public class StringArray {     private static String[] sequence;     public StringArray(String s) {         this.sequence = s.split(" ");     }     private class ReverseSequence implements Repeater {         private int i = 0;         public boolean start() {             return i == sequence.length;         }         public String current() {             return sequence[sequence.length-(i+1)];         }         public void next() {             if(i < sequence.length)                 ++i;         }       }     public Repeater repeater() {         return new ReverseSequence();     }     public static void main(String[] args) {         StringArray sa = new StringArray("Good sense is of all things the most " +  "equally distributed among men");         Repeater repeater = sa.repeater();         while(!repeater.start()) {             System.out.print(repeater.current() + " ");             repeater.next();         }     } } /* Output men among distributed equally most the things all of is sense Good *// In this example, the derived inner class RequestSequenceis used to manipulate the array member within the enclosing class by providing functionality for an interface that acts like an iterator. In this instance the content of the array member is read in reverse.

Multiple implementation inheritance

With inner classes you can solve the problem of multiple implementation inheritance when you are limited to working with abstract or concrete classes as opposed to interfaces:- package Innerclasses.java; abstract class A {} class B {} class C extends A {     class D extends B {     } } public class MultipleImplementation {     static void takesA(A a) {}     static void takesB(B a) {}       public static void main(String[] args) {           C c = new C();           takesA(c);         // using dot new to create object         //inner class directly           takesB(c.new D());     } } Note the use of an object of the outer class followed by the new keyword to create an object of the inner class in the takesB() method.  Java will not allow you to create an object of the inner class directly, unless you already have an object of the outer class. The only exception to this rule is when you are dealing with nested classes i.e. inner classes that have been declared static

.this keyword

If you want to reference the outer class from within the inner class, you must first reference the outer class followed by a dot and then the this keyword like so:- package kingsley.osime; public class Outer {     void d() { System.out.println("Outer d()"); }     public class Inner {         public Outer getOuter() {             return Outer.this;         }     }     public Inner getInner() { return new Inner(); }     public static void main(String[] args) {         Outer ot = new Outer();         Outer.Inner oi = ot.getInner();         oi.getOuter().d();     } } /* Output Outer d() *// If you were to use the this keyword on its own from within the inner class, Java will return a reference to the inner class itself. Just as an inner class is able to reference the members of the outer class without qualification, an outer class is likewise able to access the private elements of the inner class but must do so by directly referencing the inner class:- package Innerclasses.java; public class Outer {     class Inner {         private String s = "My String";     }     public String innerString() {         return new Inner().s;     }     public static void main(String[] args) {         Outer ot = new Outer();         System.out.println(ot.innerString());         Outer.Inner oi = ot.new Inner();     } } /* Output My String *//

Upcasting inner classes

Inner classes provide a very useful way to hide implementation when inheriting from a base class or interface, in this way, one may restrict the visibility of one's classes from client programmers by providing only a reference to the base class or interface. Here is a modified version of an earlier example to illustrate this point; we modify our Employee and Department implementations to interfaces and inherit from both using private and protected inner classes here:- package Innerclasses.java; import Interfaces.java.Department; import Interfaces.java.Employee;   class Company1 {     String employee;     String department;     protected class NEmployee implements Employee {         public String getName() {             return employee;         }     }     private class NDepartment implements Department {         public String name() {             return department;         }     }     public Employee employed() {         return new NEmployee();     }     public Department getName() {         return new NDepartment();     } } public class NewCompany {     public static void main(String[] args) {         Company1 c1 = new Company1();         Employee emp = c1.employed();         Department dept = c1.getName();         Company1.NEmployee ce = c1.new NEmployee();         // Can not access private inner class         //!  Company1.NDepartment cn = c1.new NDepartment();     } } Note that when you apply the private access specifier to a derived inner class you restrict access to that class to the client programmer thereby preventing any type coding dependencies. Take note of the upcasting taking place within the public interface of the outer class  from a more specific class to the more generalised type. Further, unlike a privateinner class, a protected inner class does allow some limited access.

Inheriting from inner classes

On the subject of inheritance, Java does not prevent you from inheriting from an inner class when such a design make sense to you. The only requirement is that you make the association between the outer class and inherited inner class, explicit like so:- class Outer {     class Inner {} } public class InnerInheritance extends Outer.Inner {     InnerInheritance(Outer ot) {         ot.super();     }     public static void main(String[] args) {         Outer ot = new Outer();         InnerInheritance ii = new InnerInheritance(ot);     } } When you inherit from an inner class, you need to add special syntax to the constructor as the default constructor will not work. Note how we reference the enclosing class of the inherited inner class from within the derived class constructor in order to provide the correct reference.

Local and anonymous inner classes

Java also allows you to create what we refer to as local and anonymous inner classes that exist within  method scopes. A local inner class is a class created within the scope of a method as opposed to just being within a class. You use a local inner class to return a reference when you're implementing an interface and to help solve some very complex programming problems whereby a class might be the only means of sufficiently expressing the level of complexity required. An anonymous inner class is a local inner class that has no name and can be expressed within a method or arbitrary scope. The syntax for both types of classes is like so:- package Innerclasses.java; import Interfaces.java.Employee; public class Company2 {     public Employee createEmployee(String name) {         class NewEmployee implements Employee {             String name;             public NewEmployee(String myName) {                 this.name = myName;             }             public String getName() {                 System.out.println(name);                 return name;             }         }         return new NewEmployee(name);     }       public Employee createEmployee2() {         return new Employee() {             String name = "kingsley-Anonymous";             public String getName() {                 System.out.println(name);                 return name;             }         };     }     public static void main(String[] args) {         Company2 c2 = new Company2();         Employee em = c2.createEmployee("Kingsley-local");         Employee em2 = c2.createEmployee2();         em.getName();         em2.getName();     } } /* Output Kingsley-local kingsley-Anonymous *// As you can see, the local inner class begins and ends within the scope of a method, aside from which it is no different to how you would implement any other class. The anonymous inner class provides exactly the same functionality as an inner class except that it is shorthand and quicker to write because you write the class as an expression within the method or scope. Here we simply implement the methods within the interface as we would do if we were implementing in a class. Notice the semi-column at the end of the expression as if it were any other statement in Java. Theoretically, we can implement local and anonymous inner classes within any arbitrary scope surrounded by curly braces.

Nested classes

Nested classes are inner classes that have been declared static. When you declare an inner class static, you do not require an object of the outer class to create the inner class and you are restricted from accessing a non-static outer class from an object of a nested class. Here is our Company example modified to use nested inner classes:- package Innerclasses.java; import Interfaces.java.Department; import Interfaces.java.Employee; public class Company4 {     private static class NewEmployee implements Employee {         private String name;         NewEmployee(String name) {             this.name = name;         }         public String getName() {             return name;         }     }     protected static class EmployeeDepartment implements  Department {         private String name;         EmployeeDepartment (String name) {             this.name = name;         }         public String name() {             return name;         }         static class BusinessUnit {             static String bu = " Finance ";               static String getBU() {                   return bu;               }         }     }     public static Employee employed(String name) {         return new NewEmployee(name);     }     public static Department department(String name) {         return new EmployeeDepartment(name);     }     public static void main(String[] args) {         Employee em = employed("kingsley");         Department dept = department("IT");   System.out.println(Company4.EmployeeDepartment.BusinessUnit.getBU());     } } /* Output Finance *// In this example, note how we do not require an object of the outer class to create an object of the inner class in the main(). Unlike a non-static inner class, a nested inner class can have static data, fields and other nested static classes as you can observe from  the nested BusinessUnitclass.

Nesting within interfaces

Java also allows you to nest classes within interfaces when you wish to create some common code to be used by different implementations of the interface. When you put a class in an interface it is automatically public, however you must explicitly declare the class static to ensure it does not violate the normal interface rules. Here's an example that implements the enclosing interface in the nested class:- package Innerclasses.java; public interface NestedInterface {     void f();     static class InnerClass implements NestedInterface {         public void f() {             System.out.println("Nested Class in Interface");         }         public static void main(String[] args) {             new InnerClass().f();         }     } } /* Nested Class in Interface *//

Implementing callbacks

At once inner classes might seem like a bit tedious and rather difficult to manage to the impatient mind, but it is worth taking the extra effort to understand some of the benefits of using inner classes in your program code. As mentioned earlier, inner classes allow you to inherit from more than one abstract or concrete class, something you are severely restricted from doing with outer classes. Further more, a single outer class can have multiple inner classes implementing the same interface in different ways. This is a particularly powerful programming technique that allows you to implement a control type framework like the Template method design pattern. Because inner classes retain scope information, they also allow you to provide a kind of call-back mechanism which acts like a pointer in your code. With a callback some other object is has the necessary information to reach back into the originating object at some later point in time:- import java.util.ArrayList; import java.util.List; interface U {     void a1();     void a2();     void a3(); } class A {     int i = 0;     int count;     public A(int i) {         this.i = i;         count = i++;     }     public U getU() {         return new U() {             public void a1() { System.out.println("a1() " + count); }             public void a2() { System.out.println("a2() " + count); }             public void a3() { System.out.println("a3() " + count); }         };     } }     class B {         U[] ul = new U[3];         int i = 0;         public void addRef(U ui, int i) {             ul[i] = ui;         }         public void setRef(int i) {             System.out.println("Setting element at " + i + " to null");             ul[i]  = null;         }         public void goOver(int i) {             ul[i].a1();             ul[i].a2();             ul[i].a3();         }     } public class Callback {     public static void main(String[] args) {         B b = new B();         for(int i = 0; i < 3; i++) {             A a1 = new A(i);             b.addRef(a1.getU(), i);             b.goOver(i);           }         b.setRef(1);     } } /* Output a1() 0 a2() 0 a3() 0 a1() 1 a2() 1 a3() 1 a1() 2 a2() 2 a3() 2 Setting element at 1 to null *// This simple example creates a method in class A that returns a reference to interface U by building an anonymous inner class. In a second class B we create an array containing U references and implement various methods that allows us to accept and add U references to the array, remove U references from the array and a third method through which we can move through the array and call the methods in U. In the main(), we populate a single B object with U references returned by a number of A objects. We then use B to call back into all the A objects. This is a simplification of a very powerful programming technique. Understanding when and how to use inner classes is more of a design issue that  should become second nature with repeated practice to the dedicated programmer.

In the normal course of solving a general programming problem, it is almost certain that you will become compelled to create, and identify useful ways by which to hold any number of objects within your program. In Java, you are normally inclined toward the array as the natural choice for holding a group of primitives, but this has the obvious limitation of being of a fixed size, whereas, under normal circumstances, you are unlikely to know before hand, the number of objects, or indeed anything about their type before run-time.

The java.util package provides a collection of type safe containers with which you can very quickly and easily begin to solve a number of well documented programming problems. These containers are expressed as basic interfaces of two libraries - 1) Collection interface:- which describe a sequence of individual elements to which certain rules may be applied. Containers within this category include List, Set and Queue and 2) Map interface:- a group of key-value pairs that allow you to look up a value using a key. A Map is also known as an associative array. Type safety within this context refers to the ability to ensure that only objects of the specified type can be inserted into a particular container. Java makes this possible through the use of generics, which provides a way for classes and interfaces to become parameters within other classes, interfaces and methods. For instance, one of the most commonly used container in Java is the ArrayList which represents a type of Collection. We could create a type safe ArrayList container to hold Fruit objects in the following way:- ArrayList<Fruit> fruits = new ArrayList<Fruit>();The angle brackets surrounding the type parameter is used to denote  the actual type (class or interface) for which purpose the container was created. Java's containers are very simple to learn and use once you are able to get your head around the concept of generics. The following examples are designed to further elucidate the matter. First a non-parameterised  container is used to  hold a number of unrelated objects:- package kingsley.java import java.util.ArrayList;   class Fruit {     private static long counter;     private final long id = counter++;     public long getId() { return id; } } class Furniture { } public class UsingNonParameterisedContainer {     @SuppressWarnings("unchecked")     public static void main(String[] args) {         ArrayList fruits = new ArrayList();         for(int i = 0; i < 2; i++)             fruits.add(new Fruit());         fruits.add(new Furniture());         for(int i = 0; i < fruits.size(); i++)             System.out.println((Fruit)fruits.get(i));                //! Class cast Exception     } } In this example a non-parameterised ArrayList class is used to hold Fruit and Furniture objects, both of which are of dissimilar types. Because the container is not parameterised, the compiler is unable to undertake any form of type checking and elements are upcast to Object making it possible to include different  types into the container absent warning. The problem arises when we go to retrieve elements from the container and we have to make a cast back to the original types. In this particular example, the compiler reports a class cast exception because it is unable to cast a Furniture object to Fruit In contrast to the previous example, this next example uses a type safe container (generics) to achieve much the same thing with the proviso that these containers are much more intuitive and produce better result:- package kingsley.java import java.util.ArrayList; class Mango extends Fruit {} class Orange extends Fruit {} class Funiture {} class Table extends Furniture {} public class UsingParameterisedContainer {     public static void main(String[] args) {         ArrayList<Fruit> fruits = new ArrayList<Fruit>();         for(int i = 0; i < 3; i++)             fruits.add(new Mango());         fruits.add(new Orange());         //fruits.add(new Table()); Compiler error!         for(int j = 0; j < fruits.size(); j++)             System.out.println(fruits.get(j).getId());         //using foreach syntax to iterate through list         for(Fruit f : fruits)             System.out.println(f.getClass().getSimpleName());     } } /*Output 0 1 2 3 Mango Mango Mango Orange *// In this version of a previous code, the parameterised container ArrayList is configured to hold Fruit objects with the addition of angle brackets that denote  the use of generics. In this example, a number of Fruit subtypes are added to the container with little fuss, but the attempt to add a Table object induces a compiler error. The compiler protects Java's containers from abuse by undertaking type checking  to guarantee that the container holds only the specified type. As a result of this guarantee, note that there is now no need to make a cast when retrieving elements from the container. In the previous example, a wrong type was only flagged at runtime, with Java's post SE 5 containers you get to find out about these sorts of bugs much sooner. The example further demonstrates how to select each element from within the container using both the for loop and foreach syntax, both of which are ideally suited to a number of different scenarios. The use of the foreach syntax with any Collection object is made possible because of the presence of the Iterable interface whose iterator() method produces an Iterator.

Collection<E> Interface

In Java, collections is a term used to describe a single unit or group comprising of multiple elements. It is synonymous with the concept of a container and both are often used interchangeably. Java provides a collections framework that comprise more than a dozen interfaces that make it possible for containers to be manipulated independent from the details of their implementation. At the root of this framework is the Collection interface which  represents a generalisation of the concept of a collection implemented by all containers of this type in a way that allows for  a greater level of flexibility and variety in the range of it's application and implementation. An ArrayList is an oft used type of Collection which we might have chosen to implement in the following way:- Collection<Fruit> fruits = new ArrayList<Fruit>();  By upcasting an ArrayList object to a Collection reference, we are in effect programming to the interface. This is a preferred method of programming that encourages loose coupling and high cohesion. Of course, such an arrangement would restrict our access to the methods in the ArrayList class, however this technique provides us with much flexibility that means we could easily switch implementation to any other subtype of the Collection interface with very little effort. The Collection interface provides several methods that can be used to manipulate elements within containers including for instance some of the more frequently used ones like size() method, which returns the number of elements in the specified collection, the iterator() method, returns an iterator over all elements in the collection, the remove() method which removes an instance of the specified element from the collection, the toArray() method which returns an array containing all of the elements in this collection and a number of others. One may wish to consult the Java API for the full list of  methods available to  subtypes of the Collectioninterface.

List<E> Interface

List is a basic type of Collection that maintains elements in a particular sequence and may contain duplicate elements. In addition to the methods inherited from the Collection interface, List provides additional methods including for instance methods that allow indexed access to elements within the list and unlike arrays, are automatically resizeable to accommodate additional elements. The most commonly used List implementation include those referred to previously i.e. ArrayList - a type of List that particularly excels at randomly accessing elements but is less efficient at insertion and removal operations and LinkedList - a type of List that performs insertion and removal operations more efficiently than does an ArrayList but is known to be less efficient at random access operations. In addition to Implementing the basic List interface, a LinkedList includes methods that make it useable as a Queue or double-ended queue (Deque). A Deque is a linear collection of elements that allows the addition and removal of elements at both end points. The following example demonstrates some of the more common operations associated with objects of a List subtype:- import java.util.*; public class ListsOperations {       public static void main(String[] args) {         ArrayList<Integer> arrayList = new ArrayList<Integer>(10);         LinkedList<Integer> linkList = new LinkedList<Integer>();         Random rand = new Random(10);         for(int i = 0; i < 10; i++) {             arrayList.add(i*rand.nextInt(100));             linkList.add(arrayList.size()*rand.nextInt(100));         }         System.out.println("1: arrayList = " + arrayList);         arrayList.add(new Integer(500));// appends to end of list         System.out.println("2: arrayList.add(new Integer(500)) = " +  arrayList);         System.out.println("3: arrayList.contains(new Integer(500)) = " + arrayList.contains(new Integer(500)));         System.out.println("4: arrayList.remove(new Integer(92)) = " + arrayList.remove(new Integer(92)));         System.out.println("5: arrayList.indexOf(291) = " + arrayList.indexOf(291));         System.out.println("6: linkList = " + linkList);         System.out.println("7: linkList.getFirst() = " + linkList.getFirst());         linkList.addFirst(new Integer(1000));// insert element at beginning of list         System.out.println("8: linkList.addFirst(new Integer(1000)) = " + linkList);         linkList.offer(new Integer(1000)); // adds as tail element         System.out.println("9: linkList.offer(new Integer(1000)) = " + linkList);         arrayList.addAll(linkList);// add to arraylist         System.out.println("10: arrayList.addAll(linkList) = " + arrayList);         List<Integer> subList = arrayList.subList(5, 11);// new list from arraylist         System.out.println("11: arrayList.containsAll(subList) = " + arrayList.containsAll(subList));         System.out.println("12: subList = " + subList);         Collections.sort(subList); //sort in ascending order         System.out.println("13: Collections.sort(subList) = " + subList);         Collections.shuffle(subList); // random permutations         System.out.println("14: Collections.shuffle(subList) = " + subList);     } } /* Output 1: arrayList = [0, 93, 92, 291, 324, 115, 546, 665, 688, 657] 2: arrayList.add(new Integer(500)) = [0, 93, 92, 291, 324, 115, 546, 665, 688, 657, 500] 3: arrayList.contains(new Integer(500)) = true 4: arrayList.remove(new Integer(92)) = true 5: arrayList.indexOf(291) = 2 6: linkList = [80, 180, 168, 352, 70, 594, 56, 640, 477, 380] 7: linkList.getFirst() = 80 8: linkList.addFirst(new Integer(1000)) = [1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380] 9: linkList.offer(new Integer(1000)) = [1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380, 1000] 10: arrayList.addAll(linkList) = [0, 93, 291, 324, 115, 546, 665, 688, 657, 500, 1000, 80, 180, 168, 352, 70, 594, 56, 640, 477, 380, 1000] 11: arrayList.containsAll(subList) = true 12: subList = [546, 665, 688, 657, 500, 1000] 13: Collections.sort(subList) = [500, 546, 657, 665, 688, 1000] 14: Collections.shuffle(subList) = [1000, 657, 665, 546, 500, 688] *// Note that both types of lists store elements in the order in which they are inserted and both constitute a modifiable sequence i.e the quality of being automatically resizable. Line 2 adds an element to the list, line 3 checks if the list contains a particular element, line 4 removes an element from the list and line 5 returns the index of a referenced element. Note that these operations use the equals() method inherited from the root Object to decide if any two objects are equal and as a consequence may behave differently depending on the behaviour of the equals() method. This example uses Integer wrapper classes that define equality as values being of an equivalent primitive type. LinkedList has methods that provide very similar behaviour but have different names to reflect the context of particular usage. For instance, the getFirst(), element() and peek() methods all return the head or first element in the list, while getFirst() and element() throw a NoSuchElementException if the list is empty, the peek() method returns null.  The same applies to the remove() and removeFirst() methods both of which remove and return the head of the list and will throw a NoSuchElementException if a list is found to be empty, while the poll()method provides a similar functionality but will return null in the event of an empty list. Only a few of these methods are demonstrated in the above example.

Set<E> Interface

A Set has only a slightly different interface as a Collection, but produces a different behaviour which does not allow for duplicate elements from among the set. One of the more common uses of a Set is for membership lookup i.e. to test for the existence of an object within the set. A Set determines membership based on the value of an object. Set implementations include HashSet, TreeSet and LinkedHashSet, all of which differ in how they store and process  elements. For example, HashSet uses a hashing function to add speed to it's processing of elements and makes no guarantees as to the iteration order of the set, while TreeSet keeps elements sorted in a red black tree structure and is based on a TreeMap.  Finally, a LinkedHashSet maintains elements in the order of insertion using a LinkedList but also uses hashing for lookup. Here is an example of some operations available to objects that implement the Set interface:- import java.util.*; public class SetOperations {     public static void main(String[] args) {         Set<String> hashset = new HashSet<String>();         HashSet<String> linkhashset = new LinkedHashSet<String>();         Collections.addAll(linkhashset, "A E I O U".split(" "));         Collections.addAll(hashset, "A B C D E F".split(" "));         System.out.println("1: linkhashset = " + linkhashset);         System.out.println("2: hashset = " + hashset);         System.out.println("3: linkhashset.contains(\"X\") = " + linkhashset.contains("X"));// membership lookup         System.out.println("4: linkhashset.containsAll(hashSet2) = " + linkhashset.containsAll(hashset));         Collections.addAll(linkhashset, hashset.toArray(new String[0]));         System.out.println("5: Collections.addAll(linkhashset, hashset) = " + linkhashset);         System.out.println("6: linkhashset.containsAll(hashSet2) = " + linkhashset.containsAll(hashset));         System.out.println("7: hashset.remove(\"E\") = " + hashset.remove("E"));         System.out.println("8: hashset" + hashset);         System.out.println("9: hashset.removeAll(linkhashset) - " + hashset.removeAll(linkhashset));         System.out.println("10: hashset" + hashset);         Collections.addAll(linkhashset, hashset.toArray(new String[0])); // No duplicates         System.out.println("11: linkhashset" + linkhashset);         String v = new String("V");         linkhashset.add(v);         System.out.println("12: linkhashset.add(v) = " + linkhashset);         System.out.println("13: linkhashset.contains(v) = " + linkhashset.contains(v));     } } /* Output 1: linkhashset = [A, E, I, O, U] 2: hashset = [A, B, C, D, E, F] 3: linkhashset.contains("X") = false 4: linkhashset.containsAll(hashSet2) = false 5: Collections.addAll(linkhashset, hashset) = [A, E, I, O, U, B, C, D, F] 6: linkhashset.containsAll(hashSet2) = true 7: hashset.remove("E") = true 8: hashset[A, B, C, D, F] 9: hashset.removeAll(linkhashset) - true 10: hashset[] 11: linkhashset[A, E, I, O, U, B, C, D, F] 12: linkhashset.add(v) = [A, E, I, O, U, B, C, D, F, V] 13: linkhashset.contains(v) = true *// The example upcasts a HashSet object to a Set and a LinkedHashSet to a HashSet. Both containers are populated using the utility Collections.addAll(). The rest of the example demonstrates some of the methods available to subtypes of the Set interface. Further if you are interested in an ordered set of results, you can make use of a SortedSet like so:- SortedSet<Integer> treeSet = new TreeSet<Integer>();

Queue<E> Interface

A Queue is a type of Collection that typically takes a "first-in-first-out" (FIFO) approach to the processing of elements. This is to say elements are retrieved in the same order in which they are inserted with the exception of objects that implement the  priority queue discipline - which is an alternative queuing technique that subscribes to highest priority or greatest need. Queue objects can be used as a reliable means to comfortably transfer objects from one area of your program to another and  they also possess the peculiar feature of including multiple forms for methods that provide a common functionality but behave differently in that whereby one form throws an exception in the event of an operation failure, the other returns some special value given similar circumstances:- import java.util.*; public class QueueOperations {     public static void main(String[] args) {         Queue<Character> qe = new LinkedList<Character>();         for(char c : "Encyclopedia".toCharArray())         qe.offer(c);         System.out.println("Queue.offer() - "+ qe);         qe.poll();         System.out.println("Queue.poll() - "+ qe);         System.out.println("queue.peek() " + qe.peek());         qe.add(new Character('E'));         System.out.println("queue.add() " + qe);     } /* Output fer() - [E, n, c, y, c, l, o, p, e, d, i, a] Queue.poll() - [n, c, y, c, l, o, p, e, d, i, a] queue.peek() n queue.add() [n, c, y, c, l, o, p, e, d, i, a, E] *// The offer() method inserts the specified element into the queue if possible and returns false in the event of a failure. The add() method inherited from the Collection interface performs the same operation which it can only fail by throwing an exception, as a result, the offer() method is the preferred option. The poll() method retrieves and removes the head of the queue, or returns null if the queue is empty. The remove() method performs the same operation but throws an exception if the queue is empty. The peek() and element() methods retrieve but do not remove the head of the queue. While the element() method will  throw an exception if the queue is empty, the peek() method returns nullgiving the same set of circumstances.

Map<K,V> interface

A Map is quite unlike those subtypes of Collection with which we have by now become familiar, in fact it is a very distinct data structure. The Map  interface describes methods that operate on key/value pairs, providing you with the ability to map objects to other objects by using a key to map to at most a single value, and for which duplicate keys are forbidden. Map implementation  include HashMap, TreeMap and LinkedHashMap, all of which provide similar behaviour and performances to those described in the  Set interface subheading. Some of the methods available to Map objects include those for performing basic operations like put(), get(), remove(), size(), containsKey(), containsValue(), et cetera as well as other methods that perform bulk operations and provide collection views:- import java.util.*; public class MapOperations {       public static void main(String[] args) {         Map<String, String> myPets = new HashMap<String, String>();         myPets.put("new Dog ", " woof woof");         myPets.put("new Cat ", " meeow meeow");         myPets.put("new bunnyRabbit ", " honk honk");         System.out.println("myPets: " + myPets);         System.out.println("myPets.containsKey(\"new cat\") = " + myPets.containsKey("new Cat "));         System.out.println("myPets.containsValue(\"honk honk\") = " + myPets.containsValue(" honk honk"));     } } /* Output myPets: {new Cat = meeow meeow, new Dog = woof woof, new bunnyRabbit = honk honk} myPets.containsKey("new cat") = true myPets.containsValue("honk honk") = true *// The above code is a simple example of how to look up objects and values in a Map using the containsKey() and containsValue() method. A Map provides a very powerful abstraction that simplify very many programming problems, for instance, here is a program that tracks the pseudo-random nature of Java's Random class, where the number produced by the Random is assigned as the key and the  number of times that number is produced is taken to be the value. It would be necessary to generate very many random numbers restricted to a small subset of numbers:- import java.util.*; public class MapOperations2 {       public static void main(String[] args) {         Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>();         Random rand = new Random(25);         for (int i = 0; i < 2000; i++) {             int x = rand.nextInt(10);             Integer freq = map.get(x);             map.put(x, freq == null ? 1 : freq + 1);         }         System.out.println(map);       } } /* Output {1=200, 8=218, 7=194, 5=195, 6=198, 4=188, 0=198, 9=191, 2=220, 3=198} *// In this example, a ternary if/else operator is used to test and increment the frequency a particular number has been randomly generated.  Because Maps do not accept duplicate keys there is little chance of a particular key occurring more than once. Maps can also be expanded to include multiple dimensions by including other  maps whose values also happen to be other containers or even further made up of other maps. A Map may return a Collection of its values, a Set of its keys or a Setof its pairs.

Iterator design pattern

An Iterator object provides a way to iterate over the elements in a sequence without exposing its underlying implementation. It comes under the category of a behavioural design pattern and any discourse on Java's containers is incomplete without affording it adequate attention, since you may have perceived before now that most containers within the Java's collection framework implement the Iterable interface, which is a prerequisite for accessing an Iterator. A Map on the other hand produces a Set view of it's elements with the entrySet() method which proves sufficient for iteration purposes. An Iterator object provides you with a number of very useful methods that rest easily beside the concept of a container, like for instance the next() method which is a call to get the next element in the sequence, the hasNext() method which returns either of true or false according to whether the sequence remains empty or not, and the remove() method which removes the last element returned by the iterator:- import java.util.*; public class Iteration {     public static void main(String[] args) {         List<Integer> arraylist = new ArrayList<Integer>();         Random rand = new Random(27);         for(int i = 0; i < 8; i++)             arraylist.add((Integer)rand.nextInt(20));         System.out.println("arraylist: " + arraylist);         Iterator sequence = arraylist.iterator();         while(sequence.hasNext()) {             Integer next = sequence.next();             System.out.println("The double value for " + next + " is " + next.doubleValue());         }         sequence.remove();         System.out.println("arraylist: " + arraylist);     } } } /* Output arraylist: [10, 12, 17, 18, 11, 16, 10, 14] The double value for 10 is 10.0 The double value for 12 is 12.0 The double value for 17 is 17.0 The double value for 18 is 18.0 The double value for 11 is 11.0 The double value for 16 is 16.0 The double value for 10 is 10.0 The double value for 14 is 14.0 arraylist: [10, 12, 17, 18, 11, 16, 10] *// In this example, the iterator object sequence steps through the container sequentially, so long as the test condition in the while clause evaluates to true, printing the each element to screen. The example also demonstrates the use of the remove() method which removes the last element returned by the iterator from the underlying collection. Here is a method that uses an iterator to step through a sequence providing a view of the elements within a variety of containers:- import java.util.*; public class Iteration2 {     static void view(Iterator<Character> it) {         while(it.hasNext()) {             Character p = it.next();             System.out.print("[ " + p + " " + " ]");         }         System.out.println();     }     public static void main(String[] args) {         char[] cc = {'d', 'e', 'c', 'x', 'd'};         Random rand = new Random();         ArrayList<Character> list = new ArrayList<Character>();         LinkedList<Character> list2 = new LinkedList<Character>();         HashSet<Character> set = new HashSet<Character>();         for(int i = 0; i < cc.length; i++) {             list.add(cc[rand.nextInt(cc.length)]);             list2.add(cc[rand.nextInt(cc.length)]);             set.add(cc[rand.nextInt(cc.length)]);         }         view(list.iterator());         view(list2.iterator());         view(set.iterator());     } } /* Output [ d  ][ d  ][ c  ][ d  ][ c  ] [ e  ][ c  ][ e  ][ e  ][ d  ] [ d  ][ x  ] *// The view() method in this example has no knowledge of the underlying container or the type of sequence it is traversing, and therein lies the real value of the iterator design pattern - it provides you with the ability to separate the operation of traversing a sequence from the underlying implementation of the said sequence. An Iterator is limited only by it's ability to move in one direction only - forward through a sequence. A ListIterator is a subtype of Iterator that can only be produced by List subtypes and that has the unique quality of not only being bidirectional, meaning it can move forward and backward through a list, but it can also replace the most recently visited element using it's set() method, in addition to being able to produce the indexes of the next and previous elements relative to it's current position in the list. import java.util.ArrayList; import java.util.List; import java.util.ListIterator; class Element {     private static long counter = 0;     private final long id = counter++;     public String toString() {         return this.getClass().getSimpleName() + " " + id;     } } public class LisIteration {     static void listIterator(List list) {         ListIterator listIterator = list.listIterator(list.size());         while(listIterator.hasPrevious())             System.out.print("The " + (listIterator.previousIndex() == 1 ? "1st" :                                         (listIterator.previousIndex() == 2 ? "2nd" :                                           (listIterator.previousIndex() == 3 ? "3rd" :                                             (listIterator.previousIndex() == 4 ? "4th" :                                               (listIterator.previousIndex() == 5 ? "5th" : "0")))))                                                   +  " element is " + listIterator.previous() + "\n");         listIterator.set(new Element());     }     public static void main(String[] args) {         List<Element> l1 = new ArrayList<Element>();         for(int i = 0; i < 6; i++) {             l1.add(new Element());         }         listIterator(l1);         System.out.print(l1);     } } /* Output The 5th element is Element 5 The 4th element is Element 4 The 3rd element is Element 3 The 2nd element is Element 2 The 1st element is Element 1 The 0 element is Element 0 [Element 6, Element 1, Element 2, Element 3, Element 4, Element 5] *// The above example uses some rather elaborate code to print out the elements within a container while iterating backwards through the sequence and then replaces the most recently selected element using the set() method.  You may have noticed that unlike arrays, you can produce a printable representation of the elements within a container without the need for an additional API to parse the output like the Arrays.toString() method. Also unlike arrays, containers do not hold primitives, and must rely on wrapper classes to perform the necessary conversion using the autoboxing and autounboxing mechanism.

Interfaces are completely abstract classes in Java that provide you with a uniform way to properly delineate the structure or inner workings of your program from its publicly available interface, with the consequence being a greater amount of flexibility and reusable code as well as more control over how you create and interact with other classes. More precisely, they are a special construct in Java with the additional characteristic that allow you to perform a kind of multiple inheritance i.e. classes that can be upcast to more than one class; a technique from which you are severely restricted from undertaking (and with good reason) when working exclusively with classes. To create an interface in Java, you simply use the special interface keyword like this:- interface Transaction { ... } You may include the public access identifier to the left of the interface keyword if the interface is defined in a file of the same name. Without the public keyword, the interface defaults to package access. Interfaces have no implementation and therefore relieve you of any concerns pertaining to storage; this is to say your interface can only be implemented in a concrete class. When you create an interface, you may determine method names, arguments types as well as return types, but your methods will have no body because that is left to the imagination of those classes that implement a particular interface. A class is said to conform to an interface when it uses the special implements keyword in relation to a specific interface:-   class Account implements Transaction { ... } Once you implement an interface in a class, it becomes usable as you would any other class. The methods you declare in an interface must be implemented in your inheriting classes and must be declared public. Interfaces may also include fields which are implicitly static and final. For instance, you could create different types of bank accounts to conform to a Transaction interface in the following way:- package kingsley.java interface Transaction {     int BALANCE = 500;     Object transaction(Object input); } class CurrentAccount implements Transaction {     int bal;     public Object transaction(Object input) {         this.bal = BALANCE - (int)input;         return bal;     }     public String toString() { return "Current acc"; } } class SavingsAccount implements Transaction {     int bal;     public Object transaction(Object input) {         this.bal = BALANCE + (int)input;         return bal;     }     public String toString() { return "Savings acc"; } } public class Account {       public static void payment(Transaction t, Object input) {         System.out.println(t + " is debited:  " +  t.transaction(input));     }     public static void deposit(Transaction t, Object input) {         System.out.println(t + " is credited:  " +  t.transaction(input));     }     public static void main(String[] args) {         Integer input = new Integer(600);         deposit(new SavingsAccount(), input);         payment(new CurrentAccount(), input);       } /* Output Savings acc is debited:  1100 Current acc is credited:  -100 *// Observe how both implementing classes CurrentAccount and SavingsAccount are automatically upcast in methods within the Account class that accept a Transaction interface. The payment() and deposit() methods utilise what we call a Strategy design pattern and represent an instance of the complete decoupling of interface from implementation. Strategy design pattern allows method to vary independently from the clients that use it. Theoretically, you can adapt any class to use these methods by simply making them conform to the Transaction interface. Interfaces give you a considerable amount of flexibility, and release you from the sort of constraints inherent in using particular data types and their subclasses. Note the BALANCE field in the Transaction interface which is a constant and is implicitly static and final. Finally, note that methods declared in interfaces have no body. One way to understand the utility of interfaces is to imagine how you might be able to utilise methods that accept interfaces within your own classes or how they might make it possible for others to make use of your own methods without having access to specific knowledge of its implementation, effectively keeping that part hidden. For example, imagine that a part of a program that allowed you to track the business activities of a property management company looked something like this:-  package kingsley.java public class Activity {     String name;     public Property transact(Property input) { return input; }     public String getName() { return name; }     public static void main(String[] args) {         System.out.println(new Sale(2).transact(new Property("1 Easy Street")));         System.out.println(new Purchase(8).transact(new Property("5 Main Street")));     } } class Property {     private static long counter;     private long id = counter++;     private String address;     public Property(String address) { this.address = address;  }     public String toString() { return "Property " + id + " at " + address; } } class Sale extends Activity {     int id;     String name = "Sale acc";     public Sale(int i) { this.id = i; }     public Property transact(Property input) {           return input; // Dummy transaction     }     public String getName() { return name; } } class Purchase extends Activity {     int id;     String name = "Purchase acc";     public Purchase(int i) { this.id = i; }     public Property transact(Property input) { return input; }     public String getName() { return name; } } /* Output Property 0 at 1 Easy Street Property 1 at 5 Main Street *// The purpose of this example is to demonstrate one of the ways by which one may reuse the previous Transaction interface within a class that was perhaps written by a completely different individual. The Activity class represents certain business transactions that would be relevant to some property development company. On closer  examination, you might notice that the Activity class contains some of the same elements as our earlier Transaction interface. This gives us some sign that it might be possible to make use of the Transaction interface to undertake some of those transactions defined as part of the public interface of the Account class and which might be relevant to activities implemented in the Activity class. One way to do this, would be to make use of the Adapter design pattern to create an adapter that would allow us to quickly add value to our program. An implementation of this idea would look something like this:- package kingsley.java public class Activity {     String name;     public Property transact(Property input) {         return input;       }     public String getName() {         return name;     }     public static void main(String[] args) {         Account.deposit(new ActivityAdapter(new Sale(3)), new Property("1 Easy Street"));         Account.payment(new ActivityAdapter(new Purchase(6)), new Property("5 Main Street"));     } } class ActivityAdapter implements Transaction {     Activity activity;     public ActivityAdapter(Activity activity) {         this.activity = activity;     }     public Property transaction(Object input) {         return activity.transact((Property)input);     }     public String toString() {         return activity.getName();     } } /* Output Sale acc is credited Property 0 at 1 Easy Street Purchase acc is debited Property 1 at 5 Main Street *// The result has a more intuitive feel to it. Notice how the ActivityAdapter class takes an Activity object in the constructor and produces an object that has the Transaction interface as a part of it. This is the a classic example of the Adapter design pattern without which it would not be possible for Activity and Accountclasses to work together. Adapter makes it possible for classes with incompatible interfaces to work together

Multiple Inheritance

When you work with classes, you are limited to inheriting from only one base class. Interfaces relax this constraint somewhat by allowing you undertake a kind of multiple inheritance by combining multiple interfaces within a class. To do this, you simply place interface names in sequence following the implements keyword separated by commas:- package kingsley.java interface Forward { void drive(); } interface Stop { void park(); } interface Speed {     void turbo(); } class GearBox { public void move() { } } class Automatic extends GearBox implements Forward, Stop, Speed {     public void drive() { System.out.println("drive()"); }     public void park() {  System.out.println("park()");}     public void turbo() {  System.out.println("turbo()"); }     public void move() { System.out.println("move()"); } } public class Car  {     public static void cruise(Forward x) { x.drive(); }     public static void park(Stop x) { x.park(); }     public static void race(Speed x) { x.turbo(); }     public static void move(GearBox x) { x.move(); }     public static void main(String[] args) {         Automatic auto = new Automatic();         cruise(auto); // Interface Forward         park(auto); // Interface Stop         race(auto); // Interface Speed         move(auto); // class GearBox     } } /* Output drive() park() turbo() move() *// In the preceding example, note the way by which the Automatic class implements multiple interfaces but inherits from only one class. Java will not allow you to inherit from more than one class, but you may implement as many interfaces as you need. The value in this example is in how an object of the Automatic class can be upcast to multiple types, as demonstrated in the main(), and hence my earlier reference to the concept of multiple inheritance. It is also possible to extend interfaces with inheritance in the same way you do classes by including new fields and methods. Unlike classes though, you can combine several interfaces into a new interface with inheritance. The result is a new interface with much of the same characteristics as those of its base interfaces. package kingsley.java interface SuperHero {     void powers(); } interface Alien {     void planet(); } interface SuperMan extends Alien, SuperHero {     void xRayVision(); } interface Human {     void normal(); } interface Monster extends Alien {     void killHuman(); } class Skrull implements  Monster {     void shapeShift() {}     public void killHuman() {}     public void planet() {} } class ClarkKent implements SuperMan, Human {     public void normal() {}     public void planet() {}     public void xRayVision() {}     public void powers() {} } class Hulk implements Human, SuperHero {     void thunderClap() {};     public void normal() {}     public void powers() {} } public class Earth {     static Alien invasion(Monster mt) {         return mt;     }     static SuperMan change(ClarkKent ck) {         return ck;     }     static void battle(SuperHero sh, Monster m) {         sh.powers();         m.planet();         m.killHuman();     }     public static void main(String[] args) {         Skrull ogre = new Skrull();         invasion(ogre);         ClarkKent christopherReeve = new ClarkKent();         SuperMan superMan = change(christopherReeve);         battle(superMan, ogre);         battle(new Hulk(), ogre);     } } One may also choose to nest interfaces within classes and other interfaces with very interesting results. package kingsley.java class OuterClass {     interface Inner1 {         void d();         interface Inner2 { void d1(); }     }     public class InnerClass1 implements Inner1.Inner2 {         public void d1() { }     }     public interface Inner3 {         void d();     }     private interface Inner4 {         void d();     }     private class InnerClass2 implements Inner4 {         public void d() {}     }     public class InnerClass3 implements Inner4 {         public void d() {}     }     public Inner4 getInner4() { return new InnerClass3(); }     private Inner4 i4;     public void getInner4(Inner4 in4) {         i4 = in4;         i4.d();     } } interface Outer1 {     void x();     interface Outer2 {         void d();     }     // Invalid identifier. Can only be public     // within interface     //!  private interface Outer3 { } } public class NestingInterfaces {     public class Class1 implements OuterClass.Inner1.Inner2 {         public void d1() { }     }     class Class2 implements OuterClass.Inner3 {         public void d() {}     }     //  private interface not visible     //  from outside implementing class     //! class Class3 implements OuterClass.Inner4 {     //!      public void d() { }     //! }     class Class3 implements Outer1 {         public void x() {}         class Class4 implements Outer1.Outer2 {             public void d() {}         }     }     public static void main(String[] args) {         OuterClass oc = new OuterClass();         //  Error can't access private interface         //! OuterClass.Inner4 = oc.getInner4();         //  Error can't access private interface members         //! oc.getInner4().d();         //  To get to a nested private interface         //  use another OuterClass         OuterClass oc2 = new OuterClass();         oc2.getInner4(oc.getInner4());     } } The example demonstrates some of the features available when working with nested interfaces. As you may observe for instance, it is possible to nest interfaces within interfaces which may have public or package access visibility same as non-nested interfaces do. Calling nested interfaces would then be a simple matter of placing a dot next to the surrounding class or interface, before making a call to the nested interface. Matters get a little complicated however with private interfaces, which provide a way to force the definition of methods without adding the benefit of type. In the main(), accessing private nested interface is not quite so straightforward, as attempts to use a returned reference to the private interface are unsuccessful. This is because in the first instance we are not able to access the private interface directly and secondly we can not access a member of that interface. We however can access the interface by handing the return value to an object that has permission to use it, in this case another OuterClass object. It is important to note that in implementing an interface, one is not required to implement any interfaces nested within and private interfaces can not be implemented outside of their defining classes.

Factory Methods

Interfaces have the added benefit of allowing you to make multiple implementations using the Factory Method design pattern. The Factory pattern allows you to define an interface for creating an object, but defer instantiation to implementing classes, making it so that your code is completely isolated from the interface implementation. This method is useful when creating a framework to be used by multiple types. Here is an example that uses a ticket factory to create the various types of tickets people might be interested to buy:- package kingsley.java; interface Ticket {     String type();     int price();     } interface TicketFactory { Ticket getTicket(); } class AdultTicket implements Ticket {     int PRICE = 500;     public String type() { return "Adult Ticket"; }     public int price() {return PRICE;} } class AdultTicketFactory implements TicketFactory {     public Ticket getTicket() { return new AdultTicket(); } } class ChildTicket implements Ticket {     int PRICE = 40;     public String type() { return "Child Ticket"; }     public int price() { return PRICE; } } class ChildTicketFactory implements TicketFactory {     public Ticket getTicket() { return new ChildTicket(); } } public class Tickets {     public static void buyTicket(TicketFactory tf) {         Ticket t = tf.getTicket();         System.out.println("Paid - " + "1 " + t.type() + "

In object oriented programming, polymorphism is a feature that allows you to provide a single interface to varying entities of the same type. This is analogous to the interpretation of the same concept in the field of Biology. To understand how this works in Java, we must consider inheritance and the ways by which the Java programming language makes method calls. When you create a class in Java, you implicitly inherit the fields and methods of the root Object class even when you do not explicitly inherit from some other class. This ability allows you to substitute an object for its base class and is proof of the saying - "in Java everything is an object". To demonstrate, we consider the simple example of Shape objects:-     class Shape {          public String toString() {               return " a Shape";          }     }     class Triangle extends Shape {          public String toString() {               return "a Triangle";          }     }     public class DrawShape {         /**         * @param args         */         static void draw(Shape s) {             System.out.println("Drawing " + s);         }         public static void main(String[] args) {             Triangle t = new Triangle();             draw(t);             // TODO Auto-generated method stub        }    }    /* Output    Drawing a Triangle    *// What is interesting about this example is how in the main(), we pass a Triangle reference to the draw() method that expects a Shape reference. What is even more interesting is how the compiler accepts this without complaint and Java is able to make the correct method call at run time and without the need for upcasting. This is essentially how polymorphism works. Because the draw() is a dynamically bound method (as are all normal methods in Java), a programmer is able to ignore types and write methods that takes a base class as argument confident in the knowledge that such methods can also be applied to derived classes. Here is a slightly modified version of the example to better elucidate my point:-     class Shape {          public void draw() {               System.out.println("Drawing a Shape");          }     }     class Triangle extends Shape {          public void draw() {               System.out.println("Drawing a Triangle");          }     }     public class DrawShape2 {         /**         * @param args         */         public static void main(String[] args) {            Shape s = new Triangle();             s.draw();             // TODO Auto-generated method stub        }    }    /* Output    Drawing a Triangle    *// In this example, we assign a Triangle object to a Shape reference. A call to the overloaded draw() method produces the correct behaviour, when it might be reasonable to expect that the draw() method in the Shape object might be bound to the call; afterall, we are speaking of a Shape reference. However on closer inspection, the output makes sense because a Triangle object is a kind of Shape, a fact concretised by the use of the extends keyword that denotes the use of inheritance. You might wonder how it is that this is possible? I mean how does Java know what method to call  in order to produce the correct behavior at run time? This is essentially what polymorphism is designed to achieve. To get a better understanding of how it works we might consider the concept of binding which refers to the process of connecting a method call to a method body. In programming, early binding references the point when the binding process is performed before the program is run. This is typically done by the compiler and is synonymous with some procedural languages. In the above example, it is clear that the compiler can not know which method to call when it only has a Shape reference from which we have derived at least one other type. To overcome this, Java uses the concept of late binding or dynamic binding, which allows binding to occur at run time. The term dynamic binding is often used to refer to polymorphism. When we say all method calls in Java happen polymorphically, we may correctly imagine the implementation of some mechanism that allows the correct object type to be determined at run time. The mechanism of this invention however, is not of itself of any interest to us, but the ways by which it might be perceived.       

Polymorphism and constructors.

Constructors in Java are not known to be polymorphic and there is disagreement as to whether they constitute static methods or not. Be that as it may, it has been suggested in other well regarded text that constructors are indeed implicitly static and we are happy to retain this view in the absence of anything to suggest the contrary. In the previous example, we demonstrated how polymorphism allows us to substitute a simple Triangle object for its base class. In this section we aim to explain how polymorphism effects a more complex type and the order of construction of such objects. The example below gives an idea of what a complex class looks like:-     class Books {         Books() {            System.out.println("Books");     }     class Computers {         Computers() {             System.out.println("Computers");         }     }     class Address {         Address() {             System.out.println("Address");         }     }     class Building extends Address {         Building() {             System.out.println("Building");         }     }     public class Library extends Building {          /**          * @param args          */          private Books bs = new Books();          private Computers cp = new Computers();          public Library() {              System.out.println("Library");          }          public static void main(String[] args) {              // TODO Auto-generated method stub              new Library();         }      }     /* Output     Address     Building     Books     Computers     Library      *// The example demonstrates the effect of polymorphism on the order of constructor calls in Java. The Library class is an example of a  more complex type reflecting at least two levels of inheritance as well as being composed of a number of other objects. Notice how a call to the Library() constructor results in a call to its base classes in a sort of recursive manner as can be evidence by the output. The logic of this is inherent in the fact that for a derived class to be properly constructed, the base classes from which it is derived must first be properly initialised. In other words, an inherited class must know all about its base class or classes and be able to access all of its public and protected elements. What we are trying to say is when you have a complex class that makes use of composition and inheritance, the order of constructor calls begins by first calling the base class constructor at the root of the hierarchy, followed by other constructors within the hierarchy in a sort of recursive and sequential manner. It is only after this process has been completed that individual members within the class are initialised in the order in which they are written, after which the derived class constructor may then be called. There is sufficient evidence of this in the above output. As mentioned previously, Java applies late binding to all normal method calls. This means that all methods with the exception of constructors are polymorphic by default. It is important to remember that this has an impact when you try to call a dynamically bound method from within a class constructor. In these circumstances, the overridden method may be called before the object is fully constructed making it more likely that you might end up using an unintialised variable, which might result in hard to find bugs in your program. The best way to avoid such a scenario is to do as little as possible within your constructors to get the object into a proper state. However if you must call a dynamically bound method within your constructor, the only safe methods to call are those declared final and private which cannot be overridden. When you declare a method final you effectively place a lock on it and prevent inheriting classes from changing its meaning. This is of course a design consideration. By the same token, methods declared private are implicitly final and therefore can not be accessed or overridden by inheriting classes.


In this post we have identified the effect of polymorphism on objects of derived classes, how such classes can be substituted for their base classes and as a consequence the order of constructor calls on objects of classes composed by means of composition and inheritance. Polymorphism is an essential construct in any OOP language as it works with essential features like inheritance and encapsulation and provides you with the ability to use the same interface with different forms. Having a proper understanding of how polymorphism works helps improve your code design with several desirable characteristics such as extensibility, readability and better code organisation. contact me @ kaseosime@btinternet.com
There are mainly two ways by which one may reuse classes in Java. The first is by way of composition. Composition provides a way to compose your classes from objects of existing classes, essentially making use of the objects' functionality as opposed to its form. The second method is by what we call inheritance, which describes how one may derive a new class as a type of an existing class. With inheritance you make use of not only the functionality of an existing class, but more importantly its form.


To make use of composition in your class, for non-primitives, you simply create a reference to that object; however for primitives you must define them directly. Here is an example of a class using composition:- class Dog {     Dog() {         System.out.println( "Dog()" );     } } public class Kennel {     private int i;     private double d;     private String Dog1, Dog2, Dog3, Dog4, Dog5, Dog6;     private Dog poddle = new Dog();     public String toString() {         return            "Dog1 = " + Dog1 + " " +            "Dog1 = " + Dog1 + " " +            "Dog1 = " + Dog1 + " " +            "Dog1 = " + Dog1 + " " +            "Dog1 = " + Dog1 + " " +            "Dog1 = " + Dog1 + " " + "\n" +            "i = " + i + " " + "d = " + d;      }     public static void main(String[] args) {         Kennel kn = new Kennel();         System.out.print(kn);     } } /* Output Dog() Dog1 = null Dog1 = null Dog1 = null Dog1 = null Dog1 = null Dog1 = null i = 0 d = 0.0 *// The Kennel class in this example is composed using primitives as well as non-primitives like the String and Dog object. Primitives that are fields in a class are automatically initialised to zero as can be gleaned from the output, while object references are initialised to null. As you may observe it is possible to print a null reference without throwing an exception, however an attempt to call a method on an uninitialised variable will induce the relevant compiler error. Further, take note of the special toString() method in the Kennel class which comes as standard in every non-primitive object and is useful in special situations when the compiler wants a string but has only an object. Composition is generally best suited to those situations where you require the functionality of an existing class inside of your new class but not its interface. In other words, composition allows you to embed an object in order to use it to implement features in your new class. To achieve this, you simply embed private objects of an existing class inside your new class.


Inheritance on the other hand,  is a way of taking one class and deriving from it, another class of the same type. The relationship between the two classes can be described as one class being like another or a type of another class. For instance, consider the relationship between a vehicle and a car. We could say, a car is a type of vehicle and our reasoning would make sense to most people. This is essentially how inheritance is designed to work. In Java, all classes you create implicitly inherit from the standard root class Object, from which all objects are ultimately derived. To make use of inheritance, you add the extends keyword followed by the name of the base class:- class Pet {     private String s = "Pet";     public void append(String a) { s += a; }     public void cuddle() { append(" cuddle()");  }           public void run() { append("run()");    }     public void Jump() { append(" jump()");    }     public String toString() { return s; }     public static void main(String[] args) {         Pet p = new Pet();         p.cuddle(); p.run(); p.Jump();         System.out.print(p);     }    } public class Cat extends Pet {       //change a method       public void Jump() {         append(" Pet.jump()");         super.Jump();     }     //add new members to interface     public void purr() {         append(" purr()");     }     public static void main(String[] args) {         Cat c = new Cat();         c.cuddle();         c.run();         c.Jump();         c.purr();         System.out.println(c);         System.out.println("Test base class:");         Pet.main(args);     } } /* Output Pet cuddle() run() Pet.jump() jump() purr() Test base class: Pet cuddle() run() jump() *// In the above example, the Cat class extends or otherwise inherits the members of the Pet class and adds new members as you can see with the purr() method. It is also possible to observe within this example, how both classes include a main() method which is a way to allow for the easy testing of your classes. It is possible to include a main() method in every one of the classes in your program without breaking any rule. In such situations only the main() for the class invoked from the command line will be called though in this case, the Pet.main() method is invoked from the main() of the Cat class. Inheritance is clearly demonstrated in this example because the Cat class, by making use of the extends keyword, ensures Cat objects automatically get all the methods defined in the Pet class - even if not explicitly defined -  which to all intents is considered to be its base class. This explains why the Cat class is able to casually make a call to the append() method of its base class from within the jump() and purr() methods The example also demonstrates how to modify a method already defined in the base class, within the derived class as is demonstrated by the jump() method. The super keyword is used to call the base class version of the jump() method from within the same method in the Cat class. Further, it should be noted how all methods within the Pet class are declared as public access. This is important because the Pet class defaults to package access as is expected of any class for which you do not specify any access specifier and failure to make the methods public might make them inaccessible to inheriting classes from other packages.

Base class initialisation

On the subject of inheritance, it is worth noting that when you create an object of a derived class, it automatically contains a sub-object of the base class within it. This is possible because Java automatically inserts a call to the base class constructor from within the derived class constructor. Here is an example that demonstrates my meaning:- class Hat {     Hat() { System.out.println("Hat constructor"); } } class Fedora extends Hat {     Fedora() { System.out.println("Fedora constructor"); } } public class Stetson extends Fedora {     Stetson() { System.out.println("Stetson constructor"); }     public static void main(String[] args) {         Stetson st = new Stetson();     } } /* Output Hat constructor Fedora constructor Stetson constructor *// The preceding  example demonstrates how, when you use inheritance, the base class is always initialised before the derived class constructors are able to access it. In other words construction happens inside-out from the base class. This is how Java ensures the base-class subobject is initialised correctly and avoids many of the problems experienced in other programming languages. Note also that this example uses the default no args constructor. If however, your base class included only constructors with arguments, you would be forced in those circumstances to make an explicit call to the base class constructor using the super keyword. In addition, the call to the base class would have to be the first thing you do in the derived class constructor.


Upcasting is a term that refers to the direction of movement from a derived type to a base type up the inheritance chain. It is based on the way class inheritance diagrams have traditionally been drawn i.e. with the root or base class at the top of the page, and extending downward. Upcasting is very relevant to inheritance, the most important aspect of which is the relationship expressed between the new class and the base class, which can be summarised by saying "the new class is a type of this existing class". It is normally considered a safe operation because you are going from a more specific type to a more general type with very little chance of compromising your data. The derived class is said to be a superset of the base class and consequently might contain more methods than the base class, but it must contain at least the methods in the base class. Consider the following example:-   class Instrument {     public void play() {}     static void tune(Instrument i) {       i.play;     }   }   public class Piano extends Instrument {     public static void main(String[] args) {        Piano grandPiano = new Piano();        Instrument.tune(grandpiano); //upcasting     }   } The interesting thing about this example is that the tune() method, which accepts an Instrument object reference is passed a Piano object reference in the main(). How is this possible? You might well observe that an object of the Piano class is also a type of Instrument by virtue of the fact that it inherits all the methods of the Instrument class, and therefore has access to the tune() method of its base class. The act of converting a Piano object into an Instrument reference is what we refer to as upcasting. Understanding when you might need to upcast in your code allows you to make an informed decision about whether to use composition or inheritance when designing your classes. If you will ever need to upcast in your program, then inheritance is probably necessary, but if not, you should consider carefully whether you need inheritance as it is only really useful when there is a clear need for it. Finally, it should be well understood that inheritance has some implication for how Java loads and initialises your classes particularly when dealing with statics; 

Combining composition and inheritance

More often, one may combine both composition and inheritance to derive a more complex type. The following example demonstrates the use of both methods:- class Beverage {     Beverage(int i) {         System.out.println("Beverage constructor");     } } class OrangeJuice extends Beverage {     OrangeJuice(int i) {         super(i);         System.out.println("OrangeJuice constructor");     } } class Beer extends Beverage {     Beer(int i) {         super(i);         System.out.println("Beer constructor");           } } class Food {     Food(int i) {         System.out.println("Food constructor");           } } class Potatoes extends Food {     Potatoes(int i) {         super(i);         System.out.println("Potato constructor");     } } class Chicken extends Food {     Chicken(int i) {         super(i);         System.out.println("Chicken constructor");     } } class Dessert {     Dessert(int i) {         System.out.println("Dessert constructor");     } } class Cake extends Dessert {     Cake(int i) {         super(i);         System.out.println("Cake constructor");     } } class Dinner {     Dinner(int i) {         System.out.println("Dinner constructor");     } } public class Meal extends Dinner {     private OrangeJuice oj;     private Beer br;     private Potatoes pt;     private Chicken chk;     private Cake ck;     public Meal(int i) {         super(i + 1);         oj = new OrangeJuice(i + 1);         br = new Beer(i + 2);         pt = new Potatoes(i + 10);         chk = new Chicken(i + 1);         ck = new Cake(i + 1);     }       public static void main(String[] args) {         Meal ml = new Meal(1);     } } /* Output Dinner constructor Beverage constructor OrangeJuice constructor Beverage constructor Beer constructor Food constructor Potato constructor Food constructor Chicken constructor Dessert constructor Cake constructor *// The Meal class is constructed using both composition and inheritance and the example further demonstrates the importance of calling the base class constructor as the first thing you do in the derived class constructor using the super keyword. This is particularly necessary when you are working with constructors that accept any number of arguments.


In this post, we have discussed the important subject of code reuse in Java as a mechanism by which one may quickly and easily add functionality to the classes one creates. We have also distinguished between two main ways by which this possible - composition and inheritance. Finally, we looked briefly at the manifestation of the inheritance mechanism in Java and its effects within constructor initialisation, upcasting and in the loading and initialisation of objects. contact me @ kaseosime@btinternet.com