Java Chapter 4 (3)
Java Chapter 4 (3)
OOP Concepts
Objective
Encapsulation
Polymorphism
• Other concepts:
Method overriding
Accessing Superclass
Members
Interfaces
General objective of OOP concept
With abstraction we hide the details and complexity and show only the
essentials. Again this technique also reduce complexity and isolate the
impact of changes in the code (easier program maintenance).
• As private field can’t be access outside the class, and variables of a class will
be hidden and can be accessed only through the methods of their current
class. Therefore, it is also known as data hiding. (Abstraction in action)
– Provide public setter and getter methods to modify and view the variables.
Why need Encapsulation?
• Combining data and how it's manipulated in one place :
– This is achieved through the state (the private fields) and the
behaviours (the public methods) of an object.
• Only allowing the state of an object to be accessed and modified
through behaviours:
– The values contained within an object's state can then be strictly
controlled.
• Benefits
– Simpler interface
– Reduce the impact of change
Inheritance
• Inheritance in Java is a mechanism in which one object acquires all the
properties and behaviors of a parent object.
• It is one of the cornerstones of OOP because it allows the creation of
hierarchical classifications.
• The idea behind inheritance is that you can create new classes that are
built upon existing classes.
• When you inherit from an existing class, you can reuse methods and
fields of the parent class.
• The class that is inherited is called the parent class, the base class, or
the superclass.
• The class that inherits is called the child class, the derived class, or the
subclass.
• Therefore, a subclass is a specialized version of a superclass:
• Syntax:
class SubClass extends SuperClass {
//methods and fields
}
Types of inheritance in java
• On the basis of class, there can be three types of inheritance in java:
single, multilevel and hierarchical consider the figure below.
How Inheritance is work ??
A superclass’s public members are accessible anywhere in its subclass
types.
A superclass’s private members are accessible only in methods of that
superclass i.e. they are not accessible in the subclasses.
private members are generally not inherited.
A superclass’s protected access members serve as an intermediate level
of protection between public and private access.
A superclass’s protected members are accessible in the superclass, in
the subclasses and other classes in the same package.
Why multiple inheritances is not supported in java?
To reduce the complexity and simplify the language, multiple inheritance
is not supported in java.
Consider a scenario where A, B, and C are three classes.
The C class inherits A and B classes.
If A and B classes have the same method and you call it from child class
object, there will be ambiguity to call the method of A or B class.
Since compile-time errors are better than runtime errors, Java renders
compile-time error if you inherit 2 classes.
So whether you have same method or different, there will be compile time
error.
Method Overloading
Method overloading is a part of class has multiple methods having
same name but different in parameters.
Is used to increases the readability of the program, that means, If we
have to perform only one operation, having same name of the methods
increases the readability of the program.
So, we perform method overloading to figure out the program quickly.
To call overload methods, it is must to define the type and number of
arguments to determine which version of overload method is be called.
Return type may or may not be same
Constructors can also be overloaded.
Method Overloading
Method Overloading is not possible by changing the return type of
method only.
Because,
• In java, method overloading is not possible by changing the return
type of the method only because of ambiguity.
• Let's see how ambiguity may occur in next slide.
class Adder{
static int add(int a, int b) Output:
return a + b;
• Compile Time Error:
static double add(int a, int b)
method add(int,int) is
return a + b;
already defined in class
}
Adder
class Main{
public static void main (String[] args) { • Here, how can java
System.out.println(Adder.add(11, 11)); determine which add()
} method should be called?
}
Method Overloading
Can we overload java main() method?
• Yes, by method overloading.
• You can have any number of main methods in a class by method
overloading.
• But JVM calls main() method which receives string array as
arguments only.
class TestMain{
public static void main (String args) {
System.out.println(“Main method with String”);
}
public static void main (String[] args) {
System.out.println(“Main method with String []”);
}
public static void main () {
System.out.println(Main method without String []”);
}
} Output: main with String[]
Method Overloading and Type Promotion
• One type is promoted to another implicitly if no matching datatype is found.
• Let's understand the concept by the figure given below:
class OverloadingCalculation1{
void sum (int a, long b) {
System.out.println(a + b);
}
void sum (int a, int b, int c) {
System.out.println(a + b + c);
}
public static void main (String[] args) {
OverloadingCalculation1 obj = new OverloadingCalculation1;
obj.sum(20, 20); //now second int literal will be promoted to long
obj.sum(20, 20, 20);
}
Output: 40
} 60
Note: If there are matching type arguments in the method, type promotion is not
performed.
void sum(int a,int b){}
void sum(long a, long b){}
Method Overloading with TypePromotion Ambiguity
If there are no matching type arguments in the method, and each method
promotes similar number of arguments, there will be ambiguity.
class OverloadingCalculation1{
void sum (int a, long b) {
System.out.println(a + b);
}
void sum (long a, int b) {
System.out.println(a + b);
}
public static void main (String[] args) {
OverloadingCalculation1 obj = new OverloadingCalculation1;
obj.sum(20, 20); //now ambiguity
}
}
• The class must extend the class that defines the method you want to
override.
• The method must be declared in the base class with public or protected
access. You can’t override a private method.
• If the superclass method is declared public then the overriding method in
the sub class cannot be private or protected.
• The method in the subclass must have the same signature as the
method in the base class. In other words, the name of the method and
the parameter types must be the same.
• A method declared final, static or private cannot be override.
• A method declared static cannot be overridden but can re-declared.
Polymorphism
Polymorphism is a concept by which we can perform a single action in
different ways.
Polymorphism is derived from Greek words: poly (many) and morphs
(forms).
class Animal{
public void eat() {
System.out.println(“Animal Eating…”);
}
}
class Dog extends Animal{
public void eat() {
System.out.println(“Dog Eating…”);
}
}
RULES of polymorphism
• Reference variable Own class Object
• Reference variable Child class Object //Upcasting
• Reference variable can’t point to Parent class Object
Upcasting
If the reference variable of Parent class refers to the object of Child class,
it is known as upcasting. For example:
– class A{}
B IS-A A
interface I{}
B IS-A I
• Since Object is the root class of all classes in Java, so we can write B
class B extends A implements I{} IS-A Object.
Example #1: Runtime Polymorphism
In this example, we are creating two classes Bike and Splendor.
Splendor class extends Bike class and overrides its run() method.
We are calling the run method by the reference variable of Parent class.
Since it refers to the subclass object and subclass method overrides the
Parent class method, the subclass method is invoked at runtime.
class Bike{
void run () {
System.out.println(“Running”);
}
}
class Splendor extends Bike{
void run () {
System.out.println(“Running safely with 60km”);
}
public static void main(String[] args) {
Bike b = new Splendor(); //upcasting
b.run();
}
} // Output: Running safely with 60km
Runtime Polymorphism Example 2: Bank
Consider a scenario where Bank is a class that provides a method to get
the rate of interest.
However, the rate of interest may differ according to banks. For example,
SBI, ICICI, and AXIS banks are providing 8.4%, 7.3%, and 9.7% rate of
interest respectively.
Sample Solution
class Bank {
float getRateOfInterest() { return 0; }
}
class SBI extends Bank{
float getRateOfInterest() { return 8.4f;}
Output
}
class ICICI extends Bank{ SBI Rate of Interest: 8.4
float getRateOfInterest() { return 7.3f;}
ICICI Rate of Interest: 7.3
}
class ICICI extends Bank{ AXIS Rate of Interest: 9.7
float getRateOfInterest() { return 9.7f;}
}
class TestPolymorphism {
public static void main(String args[]) {
Bank b = new SBI();
System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());
b=new ICICI();
System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());
b=new AXIS();
System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());
}
}
Runtime Polymorphism with Data Member
A method is overridden, not the data members, so runtime polymorphism
can't be achieved by data members.
In the example given below, both the classes have a data member
speedlimit.
We are accessing the data member by the reference variable of Parent
class which refers to the subclass object.
Since we are accessing the data member which is not overridden, hence it
will access the data member of the Parent class always.
class Bike{
int speedlimit = 90;
}
class Honda extends Bike{
int speedlimit = 150;
public static void main(String[] args) {
Bike obj = new Honda();
System.out.println(obj.speedlimit); // 90
}
}
Java Runtime Polymorphism with Multilevel Inheritance
class Animal{
void eat() {
System.out.println(“eating”);
}
}
class Dog extends Animal{
void eat() {
System.out.println(“eating meat”);
}
}
class BabyDog extends Dog{
void eat() {
System.out.println(“drinking milk”);
}
public static void main(String[] args) {
Animal a1 = new Animal();
Animal a2 = new Dog();
Out put:
Animal a3 = new BabyDog();
eating
}
eating meat
}
drinking milk
Accessing Superclass Members
• Sometimes, it may be necessary to access superclass members directly.
• For example, if your method overrides one of its superclass's methods,
you can invoke the overridden method in the superclass.
• This can be done through the use of the super keyword.
class Animal {
abstract void animalSound(); Output: compile time error
}
• If you are extending an abstract class that has an abstract method, you
must either provide the implementation of the method or make this class
abstract.
– But you can declare a variable using an abstract class as its type.
– Then, use the variable to refer to an instance of any of the
subclasses of the abstract class.
}
2. Interface
• An interface is a blueprint of a class.
• It is a mechanism to achieve abstraction and multiple inheritances.
• We use interface to build loosely-coupled, extensible, testable
application.
• An interface is similar to an abstract class.
• In the Java programming language, an interface is a reference type
• it can only include abstract methods and final fields (constants), but
there are no method bodies,
Interfaces cannot be instantiated and
also it can’t be used as a base class.
Instead, they can only be implemented by classes or extended by
other interfaces.
Why use Java interface?
• There are reasons to use interface.
i.e. Interfaces are easier to work with than inheritance, because you
don’t have to worry about providing any implementation details in
the interface.
A class can extend only one other class, but it can implement as
many interfaces as you need.
How to declare an interface?
An interface is declared by using the interface keyword.
interface Printable {
void print();
}
class A6 implements Printable {
public void print() {
System.out.println("Hello");
}
public void show() {
System.out.println(“Welcome");
}
public static void main(String[] args) {
A6 obj = new A6();
obj.print();
}
} Output: Hello
Interface Example #2: Drawable
In this example, the Drawable interface has only one method.
Its implementation is provided by Rectangle and Circle classes.
In a real scenario, an interface is defined by someone else, but its
implementation is provided by different implementation providers.
Moreover, it is used by someone else. The implementation part is hidden
by the user who uses the interface.
Sample Solution
interface Printable {
void print();
}
interface Showable {
void print();
}
class TestInterface implements Printable, Showable {
public void print() {
System.out.println("Hello");
}
public static void main(String[] args) {
TestInterface obj = new TestInterface();
obj.print();
}
} Output: Hello
• As you can see in this example, Printable and Showable interface have same
methods
• but its implementation is provided by class TestTnterface, so there is no
ambiguity.
Interface inheritance
Interface Drawable {
void draw();
static int cube(int x) {
return x*x*x;
}
}
class Rectangle implements Drawable { Output:
public void draw() { drawing rectangle
System.out.println("drawing rectangle");
} 27
}
class TestInterfaceStatic {
public static void main(String[] args) {
Drawable d = new Rectangle();
d.draw();
System.out.println(Drawable.cube(3));
}
}
Nested Interface in Java
• Note: An interface can have another interface which is known as a
nested interface.
• For example: interface printable {
void print();
interface MessagePrintable {
void msg();
}
}
Difference between abstract class and interface.
Abstract class can have final, non- Interface has only static and final
final, static and non-static variables variables.
The enum data type (also known as Enumerated Data Type) is a data
type which contains a fixed set of constants (a variable that does not
change).
class EnumExample1 {
//defining the enum inside the class
public enum Season {WINTER, SPRING, SUMMER, FALL}
//main method Output:
public static void main (String[] args) {
// traversing the enum WINTER
for (Season s : Season.values()); SPRING
System.out.println(s);
} SUMMER
}
FALL