OOP - Data Abstraction - Abstract Classes

OOP - Data Abstraction - Abstract Classes
Data Abstraction is one of the concept of Object Oriented Java Programming, By Data Abstraction we can able to show the services provided by the application to the outside by hiding the internal implementation.
For Example, If you go to Facebook, We chat, We post stuff in the timelines, We like, We share the posts. all these are services provided by the Facebook, but Facebook is hiding the background implementation to the end user. (i.e, what code it is executing if we click on like button, what code is executing we share etc).


In Java, Abstraction can be done in two ways.

1. Abstract Classes (Partial abstraction).
2. Interfaces (complete abstraction).

Abstract Classes : In Java when a class is declared with keyword abstarct then class is declared as an abstract class.

If a class is having at least on abstract method then for sure class will be abstract, that is we have only method defined but not implemented.


Sample Abstract class is as below.

package com.learning.partialAbstraction;

public abstract class SampleAbstractClass {
 public void getSampleMethodwithReturnVoid() {
  System.out.println("Sample Abstract Class");
 }
 abstract void getSampleAbstractMethod();
}

From the above class,
abstract void getSampleAbstractMethod();

is the abstract method as there is no method implimentation, and the abstract class can also contain concrete method
public void getSampleMethodwithReturnVoid() {
  System.out.println("Sample Abstract Class");
 }

 We can also declare instance variable to  be public,privatc, static, final  etc, there are no restrictions on using access modifiers on instance variables in the abstract class,

but abstract methods cannot be final,static and private because, implementation logic of the abstract method should be done by its sub classes,Most  importantly you cannot instantiate an abstract class.

abstract methods can have three levels of access modifiers,
1. no access modifier (will be treated as default) -- only (abstract can be extended by the classes of same package.
2. public - you have universal access of this abstract.
3. protected -  classes of the same package and outside package of same work space.
 

Why Abstract Classes? this is the question which is asked by many.
 Abstract Classes are introduced because, if your not sure of the complete requirement.




In other words, when we talk about abstract classes, we talk about how an object behaves, we are providing the characteristics of the object type.

 For example: Lets take an example of a Man (note:Its not gender biasing on women :))

1. A Man has to Sleep, Its a common feature,
2. A Man has to Work, But we are not sure what kind of work,

so the common feature will be the concrete method, the working feature we are not sure, so we are making it Abstract.
  Below is the representation of the example.

package com.learning.partialAbstraction;

public abstract class AbstractManClass {

 public String sleepMethod() {
  return "on an average a man sleeps for 8 hours";
 }
 public abstract String typeOfWork();
}

there are different type  of work a man can do. lets see how the abstract classes are extended and implement the abstract typeOfWork() method.

Lets take two classes ManA.java and ManB.java

package com.learning.partialAbstraction;

public class ManA extends AbstractManClass{
 public String typeOfWork() {
  return "Is a JAVA PROGRAMMER";
 }
}


package com.learning.partialAbstraction;

public class ManB extends AbstractManClass {
 public String typeOfWork() {
  return "Is a TESTER";
 }
}


Now lets the classes,


package com.learning.partialAbstraction;

public class TestingAbstractClass {

 public static void main(String[] args) {
  ManA a = new ManA();
  System.out.println("------------------------------------");
  System.out.println("Man A " + a.sleepMethod());
  System.out.println("Man A " + a.typeOfWork());
  ManB b = new ManB();
  System.out.println("------------------------------------");
  System.out.println("Man B " + b.sleepMethod());
  System.out.println("Man B " + b.typeOfWork());
  System.out.println("------------------------------------");
 }
}

Output:
------------------------------------
Man A on an average sleeps for 8 hours
Man A Is a JAVA PROGRAMMER
------------------------------------
Man B on an average sleeps for 8 hours
Man B Is a TESTER
------------------------------------

So in the above example we can see, there two different Man classes, both the classes has one common thing which is sleep,  and the other work is different. 

One more interesting topic of abstract classes are the,
Generic Abstract Classes, if we want to enforce the return type of the abstract method, we go for generic abstract type.

Lets create an Abstract class GenericAbstractClass.java

package com.learning.inheritance;

public abstract class GenericAbstractClass<Type> {
 public abstract Type abstractMethod();
}

Here Type may be return type, so when we extend this class, We have to pass the Return type while extending, such that the implemented method strictly follows the same return type.

Lets take a class Subclass.java extending the GenericAbstractClass

package com.learning.inheritance;

public class SubClass extends GenericAbstractClass<Void>{
 @Override
 public Void abstractMethod() {
  return null;
 }
}


Void here is not a keyword, its a class available in java.lang. package, which returns a value null. as in Generics keywords are not accepted.

example for Ineteger gereric type

package com.learning.inheritance;

public class SubClass extends GenericAbstractClass<Integer>{
 @Override
 public Integer abstractMethod() {
  return null;
 }
}

These Generic Abstract classes widely used in the Command Pattern (will discuss more on this pattern when we cover design patterns).

Java Inheritance

Java Inheritance
Inheritance is a mechanism in java which makes the properties of a class available to it subs classes.

Why Inheritance?

1. We can modify the existing implementation of a class in your sub class, in technical terms ro achieve run time Polymorphism. (Method overriding).

2. Code Re-usability.

How many Inheritance does java supports?

There are three kinds of inheritances supported in java.

1. Single inheritance.
2. Multilevel inheritance
3. Hierarchical inheritance. 

Inheritance in Java has two subtopics

1. Is-A Relationship
2. Has-A Relationship.

Is-A RelationShip :

Is-A Relationship is concept of providing, the properties of a class inherited another class. this can be done using extends keyword.

Lets do a simple POC on this concept. Lets create a parent class  ParentClass.java

package com.learning.inheritance;
public class ParentClass {
 public String getName() {
  return "My Name is Ravi kanth";
 }
}

Now lets extend the parent class to a class ChildClass.java and lets try to access getName() of the parent class in child class.


package com.learning.inheritance;

public class ChildClass extends ParentClass {
 public static void main(String[] args) {
  ChildClass childClass = new ChildClass();
  System.out.println(childClass.getName());
 }
}


Lets run the ChildClass.java and see the output

Output:

My Name is Ravi Kanth


You can clearly see the output, that child class object can use parents properties.

Now lets create a method which same and return type in ChildClass.java


package com.learning.inheritance;

public class ChildClass extends ParentClass {
 public static void main(String[] args) {
  ChildClass childClass = new ChildClass();
  System.out.println(childClass.getName());
 }

 public String getName() {
  return "My Name is John";
 }
}


Lets run the ChildClass.java and see the result:

Output:

My Name is John


you can see the it is printing the method of the childClass but not parent class, so you are overriding the methods of the parent class. This is called Method Overriding.

Points to be noted in a Is-A  Relationship.

1. By default all the Public and protected properties of the parent class is available to the sub classes.
2. We can always override the methods which are provided by the parent class to the subclasses until and unless if the methods are not declared as final
3.  You can hold parents reference in the child Object.


Has-A Relationship :

If a class have entity relationship of another class is called Aggregation or Composition. So Aggregation in java represents the Has-A relationship.

Lets do a simple POC on this concept.

Lets create a employee class Employee.java


package com.learning.inheritance;

public class Employee {
 
 private String firstName;
 private String lastName;
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 } 
}

But Employee information is incomplete, Employee working in a company has may other parameters like Employee Address, Employee Bank Details.

I have already  two classes which holds that information, which is as below.
  
EmployeeAddressInformation.java

package com.learning.inheritance;

public class EmployeeAddressInformation {

 private String houseNumber;
 private String streetName;
 private String city;
 private String state;
 private String country;
 private String pinCode;

 public String getHouseNumber() {
  return houseNumber;
 }

 public void setHouseNumber(String houseNumber) {
  this.houseNumber = houseNumber;
 }

 public String getStreetName() {
  return streetName;
 }

 public void setStreetName(String streetName) {
  this.streetName = streetName;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public String getState() {
  return state;
 }

 public void setState(String state) {
  this.state = state;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 public String getPinCode() {
  return pinCode;
 }

 public void setPinCode(String pinCode) {
  this.pinCode = pinCode;
 }

}

EmployeeBankInformation.java


package com.learning.inheritance;

public class EmployeeBankInformation {

 private String bankName;
 private String employeeNameinBankAccount;
 private String bankAccountNo;
 private String bankAddress;
 private String bankBranch;
 private String bankIfscNumber;

 public String getBankName() {
  return bankName;
 }

 public void setBankName(String bankName) {
  this.bankName = bankName;
 }

 public String getEmployeeNameinBankAccount() {
  return employeeNameinBankAccount;
 }

 public void setEmployeeNameinBankAccount(String employeeNameinBankAccount) {
  this.employeeNameinBankAccount = employeeNameinBankAccount;
 }

 public String getBankAccountNo() {
  return bankAccountNo;
 }

 public void setBankAccountNo(String bankAccountNo) {
  this.bankAccountNo = bankAccountNo;
 }

 public String getBankAddress() {
  return bankAddress;
 }

 public void setBankAddress(String bankAddress) {
  this.bankAddress = bankAddress;
 }

 public String getBankBranch() {
  return bankBranch;
 }

 public void setBankBranch(String bankBranch) {
  this.bankBranch = bankBranch;
 }

 public String getBankIfscNumber() {
  return bankIfscNumber;
 }

 public void setBankIfscNumber(String bankIfscNumber) {
  this.bankIfscNumber = bankIfscNumber;
 }

}

In the Employee Class. Instead of again adding the parameters which holds the details of the employee information, we can use the existing classes references  in your Employee class.  which is below.

package com.learning.inheritance;

public class Employee {

 private String firstName;
 private String lastName;
 private EmployeeAddressInformation addressInformation;
 private EmployeeBankInformation employeeBankInformation;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public EmployeeAddressInformation getAddressInformation() {
  return addressInformation;
 }

 public void setAddressInformation(EmployeeAddressInformation addressInformation) {
  this.addressInformation = addressInformation;
 }

 public EmployeeBankInformation getEmployeeBankInformation() {
  return employeeBankInformation;
 }

 public void setEmployeeBankInformation(EmployeeBankInformation employeeBankInformation) {
  this.employeeBankInformation = employeeBankInformation;
 }

}

Now Employee Class Has -A Relationship with EmployeeAddressInformation and EmployeeBankInformation classes.

The Major Advantage of Has-A Relationship is code re-usablility.