- Abstraction
- Encapsulation
- Inheritance
- Polymorphism
Abstraction:
Abstraction
is a process that hides the implementation and displays only the information
needed. In other words “hide the internal
implementation and shows the functionality".
We can
achieve abstraction using abstract classes and interfaces.
Abstraction
helps in reducing programming complexity and efforts.
In the below
example users can choose payment option and amount, he doesn’t know the how the
payment is done internally.
public class Application {
public static void main(String[] args) {
// pay option and pay amount choose by
user
String payOption = "netbanking";
double payAmount = 1000.00;
if(payOption.equals("credit")){
Payment payment = new CreditCard();
payment.payAmount(payAmount);
}else if(payOption.equals("netbanking")){
Payment payment = new NetBanking();
payment.payAmount(payAmount);
}
}
}
/**
* Output:
* pay amount through net-banking :
1000.0
*/
public interface Payment {
void payAmount(double payAmount);
}
public class CreditCard implements Payment{
@Override
public void payAmount(double payAmount) {
System.out.println("pay amount using credit card :
"+ payAmount);
}
}
public class NetBanking implements Payment{
@Override
public void payAmount(double payAmount) {
System.out.println("pay amount through net-banking :
"+payAmount);
}
}
Encapsulation:
The encapsulation binds the data and code together into a single unit. Hence, it is also
known as data hiding.
Encapsulation
acts as a protective wrapper that prevents the code and data from being
accessed by outsiders.
We can
achieve this by Java bean is the fully encapsulated class because all the data
members are private here and we can access by the setter and getter methods.
We can make
the class read-only or write-only by the getter or setter methods.
Suppose if
we don't provide setter methods then the outside person can't set the value.
public class Item {
private String item = "pen";
private int quantity = 10;
public String getItem() {
return item;
}
public int getQuantity() {
return quantity;
}
}
We can
control the data by adding restrictions in the setter methods. In the below
example outsiders can set the quantity if it is <= 10
public class Item {
private String item = "pen";
private int quantity = 10;
public String getItem() {
return item;
}
public int getQuantity() {
return quantity;
}
public void setItem(String item) {
this.item = item;
}
public void setQuantity(int quantity) {
if(quantity <= 10){
this.quantity = quantity;
}
}
}
public class Application {
public static void main(String[] args) {
Item item = new Item();
item.setQuantity(5);
System.out.println(item.getQuantity());
}
}
/**
* Output:
* 5
*/
Inheritance:
One object
acquires/inherits another object’s properties and behavior.
We can
create a new class by extending the parent class then we can reuse methods and fields
of the parent class.
Inheritance
represents hierarchical classification.
Loan.java is Abstract class, which extends by HomeLoan class and PersonalLoan class
public abstract class Loan {
abstract void loanType();
}
public class HomeLoan extends Loan{ @Override void loanType() { System.out.println("Home loan"); } }
public class PersonalLoan extends Loan{ @Override void loanType() { System.out.println("Personal Loan"); } }
public class Application { public static void main(String[] args) { Loan loan = new HomeLoan(); loan.loanType(); } }
/** * Output: * Home loan */
Polymorphism:
Polymorphism
means many forms, it performs a single action in different ways.
Two
different types:
1. Compile-time polymorphism
It is
resolved at compile-time which is achieved through Method Overloading.
public class Application {
public static void main(String[] args) {
Employee employee = new Employee();
employee.getEmployeeDetails(101);
employee.getEmployeeDetails("narendar");
}
}
/**
* Output:
* get details by employee Id : 101
* get details by employee Name :
narendar
*/
class
Employee{
public void getEmployeeDetails(Integer employeeId){
System.out.println("get details by employee Id :
"+employeeId);
}
public void getEmployeeDetails(String
employeeName){
System.out.println("get details by employee Name :
"+employeeName);
}
public void getEmployeeDetails(Integer employeeId,
String employeeName){
System.out.println("get details by employee Id and
Name : "+employeeId+" , "+employeeName);
}
}
2. Runtime polymorphism.
It is
resolved at run-time which is achieved through Method Overriding.
public class Application {
public static void main(String[] args) {
DeveloperDept developerDept = new DeveloperDept();
developerDept.getEmployeeDetails();
HrDept hrDept = new HrDept();
hrDept.getEmployeeDetails(101);
hrDept.getEmployeeDetails();
}
}
/**
* Output:
* get developer details
* get details by employee Id : 101
* get HR details
*/
class
Employee{
public void getEmployeeDetails(Integer employeeId){
System.out.println("get details : "+employeeId);
}
public void getEmployeeDetails(){
System.out.println("get details");
}
}
class DeveloperDept extends Employee{
@Override
public void getEmployeeDetails(){
System.out.println("get developer details");
}
}
class HrDept extends Employee{
@Override
public void getEmployeeDetails(){
System.out.println("get HR details");
}
@Override
public void getEmployeeDetails(Integer employeeId){
System.out.println("get details by employee Id :
"+employeeId);
}
}