Core Java Questions And Answers -Part-1

Is JVM Platform independent?
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
      public String[] getAddictedListOfPersons() {
           
            // 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]


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