When to use interface and abstract class in Java?
This is very popular interview
question for the beginners as well for experienced. So, Now lets
talk about the interface and abstract
class.
What is
interface?
Interface is used when you just want to define the
contract only and you don't know anything about implementation. (So here it is fully
abstraction as you don't know anything.). That’s mean, in interface you can
only define the methods and the implantation of these methods will be define somewhere
else.
What is Abstract
class?
Abstract
class is used when you know something and depend upon other for you don’t know.
By using abstract class, you can achieve partial abstraction.
So, Now
lets understand the difference in Realtime example.
When to use Interface
Consider we want to start a service like "makemytrip.com" or "expedia.com", where we are
responsible for displaying the flights from various flight service company and
place an order from customer.
Lets keep our service as simple as,
Lets keep our service as simple as,
- Displaying flights available from vendors like
"airasia", "british airways" and "emirates".
- Place and order for seat to respective vendor.
In this
scenario, interface is useful or abstract class?
Remember, In this application, we don't own any
flight. we are just a middle man/aggregator and our task is to first
enquire "airasia", then enquire "british airways" and at
last enquire "emirates" about the list of flights available and later
if customer opts for booking then inform the respective flight vendor to do
booking.
For this, first we need to tell "airasia", "british airways" and "emirates" to give us list of flights, internally how they are giving the list that we don't care.
For this, first we need to tell "airasia", "british airways" and "emirates" to give us list of flights, internally how they are giving the list that we don't care.
- This means I only care for method name
"getAllAvailableFlights()"
"getAllAvailableFlights()" from "airasia" may have used SOAP service to return list of flights.
"getAllAvailableFlights()" from "british airways" may have used REST service to return list of flights.
"getAllAvailableFlights()" from "emirates" may have used CORBA service to return list of flights.
but we don't care how it is internally implemented and what we care is the contract method "getAllAvailableFlights" that all the flight vendor should provide and return list of flights.
- Similarly, for booking I only care for method name
"booking()" that all vendors should have, internally how this
vendors are doing booking that I don't care.
To conclude: We know contract.
So we can say that we know the contract that irrespective of who the Flight vendor is, you need "getAllAvailableFlights()" and "booking()" method from them to run our aggregator service.
In
this situation, Interface is useful because we are not aware of the
implementation of all the 2 methods required, and what we know is the contract
methods that vendor(implementer) should provide. so due to this total
abstraction and for defining the contract, interface is useful in this place.
Technically,
we need to design our interface somewhat like below,
FlightOpeartions.java(Contract)
interface FlightOpeartions{ void getAllAvailableFlights(); void booking(BookingObject bookingObj); }
BookingObject.java
class BookingObject{}
BritishAirways.java
(Vendor 1)
class BritishAirways implements FlightOpeartions{ public void getAllAvailableFlights(){ //get british airways flights in the way //they told us to fetch flight details. } public void booking(BookingObject flightDetails){ //place booking order in a way British airways //told us to place order for seat. } }
Emirates.java (Vendor
2)
class Emirates implements FlightOpeartions{ public void getAllAvailableFlights(){ //get Emirates flights in the way //they told us to fetch flight details. } public void booking(BookingObject flightDetails){ //place booking order in a way Emirates airways //told us to place order for seat. } }
How Interface
achieve Polymorphism.
Note:
Interface just speak about the contract capabilities and don't know anything about implementation.
Example:
Interface can very well say that "I can get all available flights", "I can do booking" because they have that capability, but they don't know "How exactly to get all available flights", "How exactly to do booking" and this is the job of class that accepted Interface contract in other words it is the job of class that implements that interface.
Interface just speak about the contract capabilities and don't know anything about implementation.
Example:
Interface can very well say that "I can get all available flights", "I can do booking" because they have that capability, but they don't know "How exactly to get all available flights", "How exactly to do booking" and this is the job of class that accepted Interface contract in other words it is the job of class that implements that interface.
Interface
helps in achieving dynamic Polymorphism because it focus only on capabilities
and don't care about implementation which implemented class MUST take care of
as define in interface contract.
Interface very well knows what methods it is
capable of calling, and it is sure that class that implements this interface
definitely has given the body to those methods, so it blindly calls
"interfaceReference.capableMethods()",
(in our example: flightOperationsReference.getAllAvailableFlights())
It doesn't care, what object has been assigned to "interfaceReference", (it can be of any class that implemented it), but when interface calls "interfaceReference.capableMethods()", "capableMethods()" method will definitely be called on class whose object has been assigned to "interfaceReference" and that is the contract that every implementer of interface should provide body to methods defined in interface.
"interfaceReference.capableMethods()",
(in our example: flightOperationsReference.getAllAvailableFlights())
It doesn't care, what object has been assigned to "interfaceReference", (it can be of any class that implemented it), but when interface calls "interfaceReference.capableMethods()", "capableMethods()" method will definitely be called on class whose object has been assigned to "interfaceReference" and that is the contract that every implementer of interface should provide body to methods defined in interface.
When to
use Abstract class
Scenario,
Consider we want to start a service like Bulk SMS sender, where we take orders from various telecom vendors like Airtel, France Telecom, Vodafone etc.
For this, we don't have to setup your own infrastructure for sending SMS like Mobile towers but we need to take care of government rules like after 9PM, we should not send promotional SMS, we should also not send SMS to users registered under Do Not Disturb(DND) service etc. Remember, we need to take care of government rules for all the countries where we are sending SMS.
Note: for infrastructure like towers, we will be relying on vendor who is going to give us order.
Example, In case of,
Vodafone request us for bulk messaging, in that case we will use Vodafine towers to send SMS.
Airtel request us for bulk messaging, in that case we will use Airtel towers to send SMS.
What our job is to manage Telecom Regulations for different countries where we are sending SMS.
So what all methods we require would be somewhat like below,
Consider we want to start a service like Bulk SMS sender, where we take orders from various telecom vendors like Airtel, France Telecom, Vodafone etc.
For this, we don't have to setup your own infrastructure for sending SMS like Mobile towers but we need to take care of government rules like after 9PM, we should not send promotional SMS, we should also not send SMS to users registered under Do Not Disturb(DND) service etc. Remember, we need to take care of government rules for all the countries where we are sending SMS.
Note: for infrastructure like towers, we will be relying on vendor who is going to give us order.
Example, In case of,
Vodafone request us for bulk messaging, in that case we will use Vodafine towers to send SMS.
Airtel request us for bulk messaging, in that case we will use Airtel towers to send SMS.
What our job is to manage Telecom Regulations for different countries where we are sending SMS.
So what all methods we require would be somewhat like below,
public void eastablishConnectionWithYourTower(){ //connect using vendor way. //we don't know how, candidate for abstract method } public void sendSMS(){ eastablishConnectionWithYourTower(); checkForDND(); checkForTelecomRules(); //sending SMS to numbers...numbers. destroyConnectionWithYourTower() } public void destroyConnectionWithYourTower(){ //disconnect using vendor way. //we don't know how, candidate for abstract method } public void checkForDND(){ //check for number present in DND. } public void checkForTelecomRules(){ //Check for telecom rules. }
Out of above 5
methods,
- Methods we know is "sendSMS()", "checkForDND()",
"checkForTelecomRules()".
- Methods we don't know is
"eastablishConnectionWithYourTower()",
"destroyConnectionWithYourTower()".
we know how to check government rules for
sending SMS as that is what our job is but
we don't how to eastablish connection with tower and how to destroy connection with tower because this is purely customer specific, airtel has its own way, vodafone has its own way etc.
So in the given scenario, we know some methods but there also exist some methods which are unknown and depends on customers.
In this case, what will be helpful, abstarct class or interface?
we don't how to eastablish connection with tower and how to destroy connection with tower because this is purely customer specific, airtel has its own way, vodafone has its own way etc.
So in the given scenario, we know some methods but there also exist some methods which are unknown and depends on customers.
In this case, what will be helpful, abstarct class or interface?
In
this case, Abstract class will be helpful, because you know partial things like
"checkForDND()", "checkForTelecomRules()" for sending sms
to users but we don't know how to eastablishConnectionWithTower() and
destroyConnectionWithTower() and need to depend on vendor specific way to
connect and destroy connection from their towers.
Let's see how our class will look like,
abstract class SMSSender{ abstract public void eastablishConnectionWithYourTower(); public void sendSMS(){ /*eastablishConnectionWithYourTower(); checkForDND(); checkForTelecomRules(); sending SMS to numbers...numbers.*/ } abstract public void destroyConnectionWithYourTower(); public void checkForDND(){ //check for number present in DND. } public void checkForTelecomRules(){ //Check for telecom rules } } class Vodafone extends SMSSender{ @Override public void eastablishConnectionWithYourTower() { //connecting using Vodafone way } @Override public void destroyConnectionWithYourTower() { //destroying connection using Vodafone way } } class Airtel extends SMSSender{ @Override public void eastablishConnectionWithYourTower() { //connecting using Airtel way } @Override public void destroyConnectionWithYourTower() { //destroying connection using Airtel way } }
Other
differences between interface and abstract class in Java.
No
|
abstract
class
|
interface
|
1
|
Abstract
class can have both abstract methods (incomplele. methods without body) and
non-abstract methods(complete. methods with body).
|
Interface
can only have abstract methods till Java 7.
In Java 8, Interface can have non-abstract default and static methods. |
2
|
Abstract
class can extends only one class and can implements multiple interfaces.
|
Interface
can only extends other interfaces.
|
No comments:
Post a Comment