John Cooper John Cooper - 1 month ago 6
Java Question

Abstraction in Java?

Today i heard from my friend, that encapsulation is not only achieving information hiding but also abstraction. How does it achieve?

public class employee {

private String name;
private int id;

public void setName(String name){
this.name = name;
}

public String getName(){
return name;
}
}


The above example achieves encapsulation where i am allowing the class to access my public method rather than private members, but where does the abstraction come into picture here? Can anyone explain me on abstraction in a bit clear manner.

Answer

There's two different things, information hiding and abstraction.

Information hiding makes abstraction possible, but it is something different. For example, using your code

public class employee {

     private String name;
     private int id;

     public void setName(String name) {
         this.name = name;
     }

     public String getName(){
         return name;
     }
}

The id field is actually hidden. This allows one to handle ids in a manner that is decoupled from the rest of the program. Your name field is actually hidden too, as you don't access the name field directly, but the code in getName and setName does.

Once you hide the structure of the data from the rest of the code, forcing access through methods, it is possible to create a number of replaceable implementations of an item. For example, an employee is a conceptual kind of person, so you could rewrite the above like so:

public interface Person {
     public abstract String getName();
}

public class Employee implements Person {

     private String name;
     private int id;

     public void setName(String name){
         this.name = name;
     }

     public String getName(){
         return name;
     }
}

Now your code can deal with the Employee as a Person. After rewriting the rest of the code that doesn't explicitly deal with Employees to deal with Persons, you could implement other kinds of Persons and leverage the non-Employee specific tasks that are now Person tasks.

public Customer implements Person {
     private String name;
     private integer moneySpent;

     public String getName() {
          return name;
     }
}

So a person searching routine, as long as it only indexes Person objects can now include searches of both Employees and Customers. This is because the code dealing with Person objects is actually dealing with a higher level abstraction that both Employee and Customer objects share.

When dealing with Objects on an abstract level, the names of the methods are shared across the abstraction; but, the actual code executed depends on the unmentioned underlying type of the object. In other words, if you ask a Person (who happens to be an employee) getName() then it will respond with the Employee.getName() function, while a Customer will respond with a Customer.getName() function. Since the code calling getName() is operating on Persons it has no idea which type of person it will be handling, but the apparent change in behavior (the selection of the right block of code on a per-object basis) still happens. This phenomena is known as Polymorphisim, and if you are first hitting these concepts, you'll hear Polymorphisim as a word used a lot.

An example of polymorpic behavior:

 public interface Animal {
     public abstract String makeSound();
 }

 public class Cow implements Animal {
     public String makeSound() {
         return "Moo Moo!";
     }
 }

 public class Dog implements Animal {
     public String makeSound() {
         return "Ruff Ruff!";
     }
 }

 public class Sheep implements Animal {
    public String makeSound() {
         return "Baa Baa!";
    }
 }

 // this class demonstrates the polymorphic behavior

 public class Farm {
    public static void main(String[] args) {
       ArrayList<Animal> animals = new ArrayList<Animal>();
       animals.add(new Cow());
       animals.add(new Sheep());
       animals.add(new Dog());

       for (Animal animal : animals) {
          // this is where the polymorphisim occurs
          // each animal will make a different sound
          // because the makeSound method is getting
          // bound to different blocks of code based
          // on the exact type of animal class hiding
          // under the Animal abstraction.
          System.out.println(animal.makeSound());
       }
    }
 }

expected output:

 Moo Moo!
 Baa Baa!
 Ruff Ruff!

even though we never explicitly changed classes, and we never explicitly changed methods. It was the binding of the abstract method to the explicit subclass that was changing, which is something that only happens in systems that support polymorphisim.

Comments