Is JVM Platform independent?
What is Inheritance in Java ?
Answer is No, JVM is
platform dependent.
JVM depends on the operating system – so if you are running Mac OS X you will have a different JVM than if you are running Windows or some other operating system. This fact can be verified by trying to download the JVM for your particular machine – when trying to download it, you will be given a list of JVM’s corresponding to different operating systems, and you will obviously pick whichever JVM is targeted for the operating system that you are running.What is Inheritance in Java ?
Inheritance is a mechanism that allows a class to inherit property of
another class. When a Class extends another class it inherits all non-private
members including fields and methods.
Inheritance is-a
relationship between a Super class and its Sub class. extends and implements
keywords are used to describe inheritance in Java.
class Vehicle.
{
......
}
class Car extends
Vehicle
{
.......
//extends the property of vehicle class.
}
Now based on
above example. In OOPs term we can say that,
Vehicle is super class
of Car.
Car is sub class
of Vehicle.
Car IS-A Vehicle.
Purpose of
Inheritance
Purpose of Inheritance is :
To promote code
reuse.
To use
Polymorphism.
Why multiple inheritance is not supported in Java?
To remove
ambiguity.
To provide more maintainable
and clear design.
What is Polymorphism in Java?
Polymorphism is the ability to create a reference
variables, a function, or an object that has more than one form.”
An example of
polymorphism is referring the instance of subclass, with reference variable of
super-class. e.g.
Object o = new
Object(); //o can hold the reference of any subtype
Object o = new
String();
Object o = new
Integer();
Here, String is
subclass of Object class. This is basic example of polymorphism.
In java language, polymorphism is essentially
considered into two versions.
1. Compile time polymorphism (static binding or
method overloading)
2. Runtime polymorphism (dynamic binding or
method overriding)
Compile time polymorphism (static binding or
method overloading)
In method
overloading, an object can have two or more methods with same name, BUT, with
their method parameters different. These parameters may be different on two
bases:
1) Parameter type: Type of method parameters can be different.
e.g. java.util.Math.max() function comes with following versions:
public static
double Math.max(double a, double b){..}
public static
float Math.max(float a, float b){..}
public static int
Math.max(int a, int b){..}
public static
long Math.max(long a, long b){..}
The actual method
to be called is decided on compile time based on parameters passed to function
in program.
2) Parameter count: Functions accepting different number of
parameters. e.g. in employee management application, a factory can have these
methods:
EmployeeFactory.create(String
firstName, String lastName){...}
EmployeeFactory.create(Integer
id, String firstName, String lastName){...}
Both methods have
same name “create” but actual method invoked will be based on parameters passed
in program.
Runtime polymorphism (dynamic binding or
method overriding)
Runtime
polymorphism is essentially referred as method overriding. Method overriding is
a feature which you get when you implement inheritance in your program. Child class has the same method as of base
class. In such cases child class overrides the parent class method without even
touching the source code of the base class. This feature is known as method
overriding.
A simple example
can be from real world e.g. Animal. An application can have Animal class, and
its specialized sub classes like Cat and Dog. These subclasses will override
the default behavior provided by Animal class + some of its own specific
behavior.
public class
Animal {
public void makeNoise()
{
System.out.println("Some
sound");
}
}
class Dog extends
Animal{
public void makeNoise()
{
System.out.println("Bark");
}
}
class Cat extends
Animal{
public void makeNoise()
{
System.out.println("Meawoo");
}
}
Now which
makeNoise() method will be called, depends on type of actual instance created
on runtime e.g.
public class Demo
{
public static void main(String[] args) {
Animal a1 = new Cat();
a1.makeNoise(); //Prints Meowoo
Animal a2 = new Dog();
a2.makeNoise(); //Prints Bark
}
}
Rules for Method Overloading
Overloading can
take place in the same class or in its sub-class.
Constructor in
Java can be overloaded
Overloaded
methods must have a different argument list.
Overloaded method
should always be the part of the same class (can also take place in sub class),
with same name but different parameters.
The parameters
may differ in their type or number, or in both.
They may have the
same or different return types.
It is also known
as compile time polymorphism.
Rules for Method Overriding:
Applies only to
inherited methods
object type (NOT
reference variable type) determines which overridden method will be used at
runtime
Overriding method
can have different return type (refer this)
Overriding method
must not have more restrictive access modifier
Abstract methods
must be overridden
Static and final
methods cannot be overridden
Constructors
cannot be overridden
It is also known
as Runtime polymorphism.
Constructor Inheritance
Constructors are
inherited like other methods, and in fact when you construct a child object,
the default constructor of its parent is called automatically first.
class Fruit {
Fruit() {
System.out.println("Fruit
constructed");
}
}
class Banana
extends Fruit {
Banana() {
System.out.println("Banana
constructed");
}
}
public class
Application {
public static void main(String[] args) {
Banana banana = new Banana();
}
}
Fruit constructed
Banana constructed
If there is no
default constructor in the parent class, you must define a constructor
explicitly in the child class. If you want, you can then call the appropriate
constructor in the parent class using the super keyword.
class Fruit {
Fruit(String name) {
System.out.println("Fruit
constructed with name: " + name);
}
}
class Banana
extends Fruit {
Banana() {
super("Banana");
}
}
public class
Application {
public static void main(String[] args) {
Banana banana = new Banana();
}
}
Fruit constructed
with name: Banana
Instance Variable Inheritance
It might occur to
you to wonder what happens with instance variables. If the superclass has some
instance variables, do the child classes also have access to these variables?
This depends on
whether you define the instance variables in the parent class using the public,
private or protected access specifiers, or with none at all.
As long as
instance variables are not private, they can be accessed by subclasses.
Let's see an
example. Here I've placed all relevant code in one file to make it easier to read.
class Fruit {
String name;
Fruit() {
name = "Fruit";
}
public String getName() {
return name;
}
}
class Banana
extends Fruit {
Banana() {
name = "Banana";
}
}
public class
Application {
public static void main(String[] args) {
Fruit fruit = new Fruit();
Banana banana = new Banana();
System.out.println(fruit.getName());
System.out.println(banana.getName());
}
}
The constructors
of both classes set the name instance variable. The Banana class extends the
Fruit class (i.e. inherits from it); its constructor also has access to the
name instance variable, which it sets. Then when name is retrieved from either
class using the getName() method, an appropriate name is returned and
displayed.
Fruit
Banana
Abstraction:
Abstraction
captures only those details about an object that are relevant to the current
perspective.
In simple words i
can say: "Abstraction implies providing something, but not
everything".
By using abstract
classes or interfaces , we can achieve abstraction in Java.
As we know that
abstract classes, interfaces contains abstract methods (ofcourse abstract
classes may or may not contain) i.e , only method declarations.
By looking at the
method declaration we can estimate what exactly the method is doing, what it is
going to return. But we don't know how exactly the abstract method will be
implemented.
We came to know
about the implementation, once we provided the method implementation in the
classes which implement the corresponding abstract class or interface.
Example for the above illustration:
Let us consider
an interface (you can take abstract class also) Addicted.
public interface Addicted {
public
String[] getAddictedListOfPersons();
}
In the above
interface, getAddictedListOfPersons() is the abstract method (by default all
the methods in an interface are public abstract ) which returns list of all the
addicted persons. By looking at the method declaration we can infer this.
But we don't know
how exactly the method will be implemented in it's (interface) implementation
classes.
Following are the implementation classes for
the interface Addicted.
public class AddictedToJava implements
Addicted{
@Override
public
String[] getAddictedListOfPersons() {
// here we will provide implementation
(getting list of persons who were addicted to Java)
return null;
}
}
The class AddictedToJava is providing
implementation to the abstract method which returns the list of persons who
were addicted to Java.
public class AddictedToAndroid implements
Addicted {
@Override
//
here we will provide implementation (getting list of persons who were addicted
to Android)
return
null;
}
}
The class AddictedToAndroid is providing
implementation to the abstract method which returns the list of persons who
were addicted to Android.
Now , by looking at
these implementations we came to know that the implementation is different in
both of the implementation classes for the interface(Addicted).
Only after
providing implementation, we came to know how exactly the method was
implemented.
Encapsulation
is a practice to bind related functionality (Methods) & Data (Variables) in
a protective wrapper (Class) with required access modifiers (public, private,
default & protected) so that the code can be saved from unauthorized access
by outer world and can be made easy to maintain.
We can achieve
complete encapsulation in java by making members of a class private and access
them outside the class only through getters and setters. Although a lesser
degree of encapsulation can be achieved by making the members public or
protected.
As we know a
private access specifier specifies access with in the class (local access), the
data can't be exposed to the other classes (in same application or different
application).
Let me elaborate
this with an example.
CapsulateData is
the class with some variables as given below.
public class
CapsulateData {
public String branchName;
private long accountNumber;
private String accountName;
public String getBranchName() {
return branchName;
}
public void setBranchName(String
branchName) {
this.branchName = branchName;
}
public long getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(long
accountNumber) {
this.accountNumber = accountNumber;
}
public void setAccountNumber(int
accountNumber) {
this.accountNumber = accountNumber;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String
accountName) {
this.accountName = accountName;
}
}
As accountNumber,
accountName are private variables they can't be accessed outside the class.
If we try to do
so, following will be the result.
Abstraction
is more about ‘What‘ a
class can do. [Idea]
– Encapsulation is more about ‘How‘ to achieve that functionality. [Implementation]
– Encapsulation is more about ‘How‘ to achieve that functionality. [Implementation]
Relation Between Abstraction and Encapsulation?
I will take
example of our well known class HashMap. This class is responsible for storing
key-value pair, searching based on key and do more things. From outside, client
code only knows the method names and their behavior. It calls these methods and
live happily. This is actually what abstraction guidelines are.
Abstraction says
that client code should call a method to add key-value pair, a method to
retrieve value based on key and so on. How it should be done? is not business
of abstraction.
And here comes
encapsulation, when you start writing actual code. You write HashMap.Entry
class and create variable table of type Entry[]. Then you declare all such
things private and give public access to only put() and get() methods etc. This
is actually encapsulation.
Abstraction : Things to Remember
1) Use
abstraction if you know something needs to be in class but the implementation
of that varies. Abstraction is actually resulting of thought process and it
really need good experience of both domain and Object oriented analysis and
design to come up with good abstraction for your project.
2) In Java, you
cannot create an instance of the abstract class using the new operator, its
compiler error. Though abstract class can have a constructor.
3) abstract is a
keyword in Java, which can be used with both class and method. Abstract class can contain both abstract and
concrete method. An abstract method doesn't have the body, just declaration.
4) A class
automatically becomes abstract class when any of its methods declared as
abstract.
5) abstract
method doesn't have method body.
6) In Java, a
variable cannot be made abstract , its only class or methods which would be
abstract.
7) If a class
extends an abstract class or interface it has to provide implementation to all
its abstract method to be a concrete class. Alternatively, this class can also
be abstract.
Difference between Abstraction and Encapsulation:
1) First
difference between Abstraction and Encapsulation is that, Abstraction is
implemented in Java using interface and abstract class while Encapsulation is
implemented using private, package-private and protected access modifier.
2) Encapsulation
is also called data hiding.


No comments:
Post a Comment