[Go to site: main page, start]

0% found this document useful (0 votes)
3 views36 pages

JavaMod 3

The document provides an overview of inheritance in Java, explaining its significance in object-oriented programming, including concepts like code reusability, method overriding, and abstraction. It details key terminologies, syntax for implementing inheritance, and various types of inheritance such as single, multilevel, and hierarchical. Additionally, it discusses the advantages and disadvantages of inheritance, along with examples demonstrating method overriding and the use of the 'super' keyword.

Uploaded by

georgewatson9899
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views36 pages

JavaMod 3

The document provides an overview of inheritance in Java, explaining its significance in object-oriented programming, including concepts like code reusability, method overriding, and abstraction. It details key terminologies, syntax for implementing inheritance, and various types of inheritance such as single, multilevel, and hierarchical. Additionally, it discusses the advantages and disadvantages of inheritance, along with examples demonstrating method overriding and the use of the 'super' keyword.

Uploaded by

georgewatson9899
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

MODULE 3

Inheritance in Java
Java Inheritance is a fundamental concept in OOP(Object-Oriented Programming). It is the
mechanism in Java by which one class is allowed to inherit the features(fields and methods)
of another class. In Java, Inheritance means creating new classes based on existing ones. A
class that inherits from another class can reuse the methods and fields of that class.

Why Use Inheritance in Java?

• Code Reusability: The code written in the Superclass is common to all subclasses.
Child classes can directly use the parent class code.

• Method Overriding: Method Overriding is achievable only through Inheritance. It is


one of the ways by which Java achieves Run Time Polymorphism.

• Abstraction: The concept of abstraction where we do not have to provide all details,
is achieved through inheritance. Abstraction only shows the functionality to the user.
Key Terminologies Used in Java Inheritance
• Class: Class is a set of objects that share common characteristics/ behavior and
common properties/ attributes. Class is not a real-world entity. It is just a template or
blueprint or prototype from which objects are created.

• Super Class/Parent Class: The class whose features are inherited is known as a
superclass(or a base class or a parent class).

• Sub Class/Child Class: The class that inherits the other class is known as a
subclass(or a derived class, extended class or child class). The subclass can add its
own fields and methods in addition to the superclass fields and methods.

• Extends Keyword: This keyword is used to inherit properties from a superclass.

Syntax to implement inheritance

Consider the syntax below to implement (use) inheritance in Java:

class Super {
.....
.....
}
class Sub extends Super {
.....
.....
}
Example: In the following example, Animal is the base class and Dog, Cat and Cow are
derived classes that extend the Animal class.

Janhavi Nandish, CSD, ATMECE


Implementation:

// Parent class
class Animal {
void sound() {
[Link]("Animal makes a sound");
}
}

// Child class
class Dog extends Animal {
void sound() {
[Link]("Dog barks");
}
}

// Child class
class Cat extends Animal {
void sound() {
[Link]("Cat meows");
}
}

// Child class
class Cow extends Animal {
void sound() {
[Link]("Cow moos");
}
}

// Main class
public class Geeks {
public static void main(String[] args) {
Animal a;
a = new Dog();
[Link]();

a = new Cat();
[Link]();

a = new Cow();
[Link]();
}
}

Janhavi Nandish, CSD, ATMECE


Output

Dog barks

Cat meows

Cow moos

Explanation:

• Animal is the base class.


• Dog, Cat and Cow are derived classes that extend Animal class and provide specific
implementations of the sound() method.

• The Geeks class is the driver class that creates objects and demonstrates runtime
polymorphism using method overriding.

Note: In practice, inheritance and polymorphism are used together in Java to achieve fast
performance and readability of code.

Note: In Java, inheritance is implemented using the extends keyword. The class that inherits
is called the subclass (child class) and the class being inherited from is called the superclass
(parent class).

How Inheritance Works in Java?

The extends keyword is used for inheritance in Java. It enables the subclass to inherit the
fields and methods of the superclass. When a class extends another class, it means it inherits
all the non-primitive members (fields and methods) of the parent class and the subclass can
also override or add new functionality to them.

Note: The extends keyword establishes an "is-a" relationship between the child class and the
parent class. This allows a child class to have all the behavior of the parent class.

Java Inheritance: The super Keyword


The super keyword is similar to this keyword. Following are the scenarios where the super
keyword is used.

• It is used to differentiate the members of superclass from the members of subclass,


if they have same names.

• It is used to invoke the superclass constructor from subclass.

Differentiating the Members

If a class is inheriting the properties of another class. And if the members of the superclass
have the names same as the sub class, to differentiate these variables we use super keyword
as shown below.
[Link]
Janhavi Nandish, CSD, ATMECE
[Link]();

This section provides you a program that demonstrates the usage of the super keyword.

In the given program, you have two classes namely Sub_class and Super_class, both have a
method named display() with different implementations, and a variable named num with
different values. We are invoking display() method of both classes and printing the value of
the variable num of both classes. Here you can observe that we have used super keyword to
differentiate the members of superclass from subclass.
Copy and paste the program in a file with name Sub_class.java.

Example

class Super_class {
int num = 20;

// display method of superclass


public void display() {
[Link]("This is the display method of superclass");
}
}

public class Sub_class extends Super_class {


int num = 10;

// display method of sub class


public void display() {
[Link]("This is the display method of subclass");
}
public void my_method() {
// Instantiating subclass
Sub_class sub = new Sub_class();

// Invoking the display() method of sub class


[Link]();

// Invoking the display() method of superclass


[Link]();

// printing the value of variable num of subclass


[Link]("value of the variable named num in sub class:"+ [Link]);

// printing the value of variable num of superclass


[Link]("value of the variable named num in super class:"+ [Link]);
}

Janhavi Nandish, CSD, ATMECE


public static void main(String args[]) {
Sub_class obj = new Sub_class();

obj.my_method();
}
}

Output

This is the display method of subclass

This is the display method of superclass

value of the variable named num in sub class:10

value of the variable named num in super class:20

Invoking Superclass Constructor


If a class is inheriting the properties of another class, the subclass automatically acquires the
default constructor of the superclass. But if you want to call a parameterized constructor of
the superclass, you need to use the super keyword as shown below.

super(values);

Sample Code

The program given in this section demonstrates how to use the super keyword to invoke the
parametrized constructor of the superclass. This program contains a superclass and a
subclass, where the superclass contains a parameterized constructor which accepts a integer
value, and we used the super keyword to invoke the parameterized constructor of the
superclass.

class Superclass {
int age;

Superclass(int age) {
[Link] = age;
}

public void getAge() {


[Link]("The value of the variable named age in super class is: " +age);
}
}

public class Subclass extends Superclass {

Janhavi Nandish, CSD, ATMECE


Subclass(int age) {
super(age);
}
public static void main(String args[]) {
Subclass s = new Subclass(24);
[Link]();
}
}
Output:

The value of the variable named age in super class is: 24

Types of Inheritance in Java

Types of Inheritance in Java

Below are the different types of inheritance which are supported by Java.

• Single Inheritance

• Multilevel Inheritance

• Hierarchical Inheritance

• Multiple Inheritance

• Hybrid Inheritance

1. Single Inheritance

In single inheritance, a subclass is derived from only one superclass. It inherits the properties
and behavior of a single-parent class. Sometimes, it is also known as simple inheritance.
Single Inheritance

Example:

Janhavi Nandish, CSD, ATMECE


//Super class
class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}

// Subclass
class Car extends Vehicle {
Car() {
[Link]("This Vehicle is Car");
}
}

public class Test {


public static void main(String[] args) {
// Creating object of subclass invokes base class constructor
Car obj = new Car();
}
}

Output

This is a Vehicle

This Vehicle is Car

2. Multilevel Inheritance

In Multilevel Inheritance, a derived class will be inheriting a base class and as well as the
derived class also acts as the base class for other classes.

Multilevel Inheritance

Example:

class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}
class FourWheeler extends Vehicle {
FourWheeler() {
[Link]("4 Wheeler Vehicles");
}
}
class Car extends FourWheeler {

Janhavi Nandish, CSD, ATMECE


Car() {
[Link]("This 4 Wheeler Vehicle is a Car");
}
}
public class Geeks {
public static void main(String[] args) {
Car obj = new Car(); // Triggers all constructors in order
}
}

Output

This is a Vehicle

4 Wheeler Vehicles

This 4 Wheeler Vehicle is a Car


3. Hierarchical Inheritance

In hierarchical inheritance, more than one subclass is inherited from a single base class. i.e.
more than one derived class is created from a single base class. For example, cars and buses
both are vehicle

Hierarchical Inheritance
Example:

class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}

class Car extends Vehicle {


Car() {
[Link]("This Vehicle is Car");
}
}

class Bus extends Vehicle {


Bus() {
[Link]("This Vehicle is Bus");
}
}

public class Test {

Janhavi Nandish, CSD, ATMECE


public static void main(String[] args) {
Car obj1 = new Car();
Bus obj2 = new Bus();
}
}

Output
This is a Vehicle
This Vehicle is Car
This is a Vehicle
This Vehicle is Bus

What Can Be Done in a Subclass?

In sub-classes we can inherit members as is, replace them, hide them or supplement them
with new members:
• The inherited fields can be used directly, just like any other fields.

• We can declare new fields in the subclass that are not in the superclass.

• The inherited methods can be used directly as they are.

• We can write a new instance method in the subclass that has the same signature as the
one in the superclass, thus overriding it (as in the example above, toString() method is
overridden).

• We can write a new static method in the subclass that has the same signature as the
one in the superclass, thus hiding it.

• We can declare new methods in the subclass that are not in the superclass.
• We can write a subclass constructor that invokes the constructor of the superclass,
either implicitly or by using the keyword super.

Advantages of Inheritance in Java

• Code Reusability: Inheritance allows for code reuse and reduces the amount of code
that needs to be written. The subclass can reuse the properties and methods of the
superclass, reducing duplication of code.

• Abstraction: Inheritance allows for the creation of abstract classes that define a
common interface for a group of related classes. This promotes abstraction and
encapsulation, making the code easier to maintain and extend.

• Class Hierarchy: Inheritance allows for the creation of a class hierarchy, which can
be used to model real-world objects and their relationships.

Janhavi Nandish, CSD, ATMECE


• Polymorphism: Inheritance allows for polymorphism, which is the ability of an
object to take on multiple forms. Subclasses can override the methods of the
superclass, which allows them to change their behavior in different ways.

Disadvantages of Inheritance in Java


• Complexity: Inheritance can make the code more complex and harder to understand.
This is especially true if the inheritance hierarchy is deep or if multiple inheritances is
used.
• Tight Coupling: Inheritance creates a tight coupling between the superclass and
subclass, making it difficult to make changes to the superclass without affecting the
subclass.

Java Method Overriding


Method overriding allows us to achieve run-time polymorphism and is used for writing
specific definitions of a subclass method that is already defined in the superclass.
The method is superclass and overridden method in the subclass should have the same
declaration signature such as parameters list, type, and return type.

Usage of Java Method Overriding

Following are the two important usages of method overriding in Java:

• Method overriding is used for achieving run-time polymorphism.

• Method overriding is used for writing specific definition of a subclass method (this
method is known as the overridden method).

Example of Method Overriding in Java

class Animal {
public void move() {
[Link]("Animals can move");
}
}

class Dog extends Animal {


public void move() {
[Link]("Dogs can walk and run");
}
}

public class TestDog {

public static void main(String args[]) {


Animal a = new Animal(); // Animal reference and object

Janhavi Nandish, CSD, ATMECE


Animal b = new Dog();
[Link](); // runs the method in Animal class
[Link](); // runs the method in Dog class
}
}
Output
Animals can move
Dogs can walk and run

Method Overriding
1. Definition
• When a method in a subclass has the same name and same type signature as a
method in its superclass, the subclass method overrides the superclass method.
• When the overridden method is called from a subclass object, the subclass version
executes, and the superclass version is hidden.

2. Key Points
• Overriding occurs only when:
o Method name is the same.
o Method parameter list (type signature) is identical.
• If the parameter list is different → it becomes method overloading, not overriding.
• Overridden methods enable runtime polymorphism.

3. Accessing Superclass Method


• You can call the superclass version of an overridden method using:
• [Link]();
• This allows the subclass to use the original behavior along with its own.

4. Overriding vs Overloading
• Overriding: same name + same signature → defined in different classes (super +
sub)
• Overloading: same name + different signature → defined in the same or different
classes

Examples / Programs from Given Text

Program 1: Basic Method Overriding


// Method overriding.
class A {
int i, j;

A(int a, int b) {
i = a;

Janhavi Nandish, CSD, ATMECE


j = b;
}

// display i and j
void show() {
[Link]("i and j: " + i + " " + j);
}
}

class B extends A {
int k;

B(int a, int b, int c) {


super(a, b);
k = c;
}

// display k – this overrides show() in A


void show() {
[Link]("k: " + k);
}
}

class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
[Link](); // calls B's show()
}
}
Output
k: 3

Program 2: Calling Superclass Method Using super


class B extends A {
int k;

B(int a, int b, int c) {


super(a, b);
k = c;
}

void show() {
[Link](); // calls A's show()

Janhavi Nandish, CSD, ATMECE


[Link]("k: " + k);
}
}
Output
i and j: 1 2
k: 3

Program 3: Overloading (Not Overriding)


// Methods with differing type signatures are overloaded – not overridden.
class A {
int i, j;

A(int a, int b) {
i = a;
j = b;
}

// display i and j
void show() {
[Link]("i and j: " + i + " " + j);
}
}

// Create a subclass by extending class A.


class B extends A {
int k;

B(int a, int b, int c) {


super(a, b);
k = c;
}

// overload show()
void show(String msg) {
[Link](msg + k);
}
}

class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
[Link]("This is k: "); // calls B's overloaded show()
[Link](); // calls A's show()

Janhavi Nandish, CSD, ATMECE


}
}
Output
This is k: 3
i and j: 1 2

Rules for Method Overriding


• The argument list should be exactly the same as that of the overridden method.
• The return type should be the same or a subtype of the return type declared in the
original overridden method in the superclass.
• The access level cannot be more restrictive than the overridden method's access level.
For example: If the superclass method is declared public then the overridding method
in the sub class cannot be either private or protected.
• Instance methods can be overridden only if they are inherited by the subclass.
• A method declared final cannot be overridden.
• A method declared static cannot be overridden but can be re-declared.
• If a method cannot be inherited, then it cannot be overridden.
• A subclass within the same package as the instance's superclass can override any
superclass method that is not declared private or final.
• A subclass in a different package can only override the non-final methods declared
public or protected.
• An overriding method can throw any uncheck exceptions, regardless of whether the
overridden method throws exceptions or not. However, the overriding method should
not throw checked exceptions that are new or broader than the ones declared by the
overridden method. The overriding method can throw narrower or fewer exceptions
than the overridden method.
• Constructors cannot be overridden.

Dynamic Method Dispatch in Java


Introduction
Dynamic Method Dispatch, also known as Runtime Polymorphism, is one of the most
powerful concepts in Java's object-oriented programming. It allows Java to determine which
method to invoke at runtime rather than compile time. This feature is fundamental in
achieving method overriding and is widely used in real-world applications.
Understanding Dynamic Method Dispatch
In Java, method calls are resolved dynamically at runtime using Dynamic Method Dispatch.
This mechanism enables a superclass reference variable to refer to a subclass object, and
Java determines which overridden method to execute based on the actual object type.
Key Points:
• It enables runtime polymorphism.
• Method invocation is determined by the object that the reference variable refers to
(not the type of reference itself).
• It allows for flexible and maintainable code by supporting method overriding.

Janhavi Nandish, CSD, ATMECE


Example: Dynamic Method Dispatch
class Animal {
public void move() {
[Link]("Animals can move");
}
}

class Dog extends Animal {


public void move() {
[Link]("Dogs can walk and run");
}
}

public class TestDog {

public static void main(String args[]) {

Animal a = new Animal(); // Animal reference and object


Animal b = new Dog(); // Animal reference but Dog object

[Link](); // runs the method in Animal class


[Link](); // runs the method in Dog class
}
}
This will produce the following result −
Output
Animals can move
Dogs can walk and run

In the above example, you can see that even though b is a type of Animal it runs the move
method in the Dog class. The reason for this is: In compile time, the check is made on the
reference type. However, in the runtime, JVM figures out the object type and would run the
method that belongs to that particular object.
Therefore, in the above example, the program will compile properly since Animal class has
the method move. Then, at the runtime, it runs the method specific for that object.

Why Use Dynamic Method Dispatch?


• Achieves Runtime Polymorphism: Allows the program to be more flexible and
scalable.
• Enhances Code Reusability: A superclass reference can be used for multiple
subclass objects.
• Improves Maintainability: Reduces dependencies between different parts of the
code.

Janhavi Nandish, CSD, ATMECE


Below are clean, concise notes prepared only from the given data, without adding extra
points.

Abstract Classes in Java


1. Purpose of Abstract Classes
• A superclass may define the structure of an abstraction without implementing all
methods.
• Some methods in the superclass may not have a meaningful implementation.
• Subclasses must provide complete implementation for such methods.

2. When to Use Abstract Methods


• Used when a method cannot be meaningfully defined in the parent class.
• Example: area() in class Figure—the superclass cannot compute area since shapes
differ.
• Such methods become subclass responsibility.

3. Declaring an Abstract Method


• Use the abstract keyword.
• It contains no method body.
• abstract return-type methodName(parameter-list);

4. Abstract Class Rules


• A class containing an abstract method must be declared abstract.
• Abstract classes cannot be instantiated using new.
• Abstract classes can still have:
o Concrete (normal) methods
o Constructors (but not abstract constructors)
• Abstract classes cannot contain abstract static methods.
• Any subclass must:
o Implement all abstract methods OR
o Be declared abstract itself.

5. Simple Demonstration of Abstract Class


// A Simple demonstration of abstract.
abstract class A {
abstract void callme(); // abstract method

// concrete method allowed in abstract class


void callmetoo() {
[Link]("This is a concrete method.");
}
}

Janhavi Nandish, CSD, ATMECE


class B extends A {
void callme() {
[Link]("B's implementation of callme.");
}
}

public class AbstractDemo {


public static void main(String args[]) {
B b = new B();
[Link]();
[Link]();
}
}

Example Summary (Class A and B)


• A is abstract and contains:
o An abstract method callme().
o A concrete method callmetoo().
• B extends A and implements callme().
• Objects of A cannot be created.
• Abstract classes can still declare references pointing to subclass objects.

[Link] Abstract Methods and Classes (Figure Example)


// Using abstract methods and classes.
abstract class Figure {
double dim1;
double dim2;

Figure(double a, double b) {
dim1 = a;
dim2 = b;
}

// area is now an abstract method


abstract double area();
}

class Rectangle extends Figure {


Rectangle(double a, double b) {
super(a, b);
}

// override area for rectangle

Janhavi Nandish, CSD, ATMECE


double area() {
[Link]("Inside Area for Rectangle.");
return dim1 * dim2;
}
}

class Triangle extends Figure {


Triangle(double a, double b) {
super(a, b);
}

// override area for triangle


double area() {
[Link]("Inside Area for Triangle.");
return (dim1 * dim2) / 2;
}
}

public class AbstractAreas {


public static void main(String args[]) {

// Figure f = new Figure(10, 10); // illegal now

Rectangle r = new Rectangle(9, 5);


Triangle t = new Triangle(10, 8);

Figure figref; // reference to abstract class allowed

figref = r;
[Link]("Area is " + [Link]());

figref = t;
[Link]("Area is " + [Link]());
}
}

Improving the Figure Example


• Figure is made abstract since area has no general meaning.
• area() is declared abstract in class Figure.
• Subclasses Rectangle and Triangle override area() with proper implementations.
• You cannot create:
• Figure f = new Figure(10, 10); // illegal
• But you can create:

Janhavi Nandish, CSD, ATMECE


• Figure figref;
• figref = new Rectangle(...);

7. Use of Abstract Class Reference


• Abstract classes cannot create objects, but:
o They can create reference variables.
o These references can point to subclass objects.
• Enables runtime polymorphism using superclass references.

Local Variable Type Inference


Local Variable Type Inference is one of the most evident change to language available from
Java 10 onwards. It allows to define a variable using var and without specifying the type of it.
The compiler infers the type of the variable using the value provided. This type inference is
restricted to local variables.

Old way of declaring local variable:


String name = "Welcome to ATMECE";
New Way of declaring local variable:
var name = "Welcome to ATMECE";
Now compiler infers the type of name variable as String by inspecting the value provided.

points
• No type inference in case of member variable, method parameters, return values.
• Local variable should be initialized at time of declaration otherwise compiler will not
be infer and will throw error.
• Local variable inference is available inside initialization block of loop statements.
• No runtime overhead. As compiler infers the type based on value provided, there is no
performance loss.
• No dynamic type change. Once type of local variable is inferred it cannot be changed.
• Complex boilerplate code can be reduced using local variable type inference.

Map<Integer, String> mapNames = new HashMap<>();

var mapNames1 = new HashMap<Integer, String>();


Example
Following Program shows the use of Local Variable Type Inference in JAVA 10.

import [Link];

public class Tester {


public static void main(String[] args) {
var names = [Link]("Julie", "Robert", "Chris", "Joseph");
for (var name : names) {
Janhavi Nandish, CSD, ATMECE
[Link](name);
}
[Link]("");
for (var i = 0; i < [Link](); i++) {
[Link]([Link](i));
}
}
}
Output

Julie
Robert
Chris
Joseph

Julie
Robert
Chris
Joseph

The Object Class


1. Object Class Overview
• Object is a special class in Java.
• It is the superclass of all classes.
• Every class in Java directly or indirectly inherits from Object.
• Therefore, every object created in Java has all the methods defined in the Object
class.

2. Object Reference Flexibility


• A reference variable of type Object can refer to an object of any class.
o Example:
Object obj = new String("Hello");
• Because arrays in Java are implemented as objects, an Object reference can also refer
to any array.

3. Methods Defined in Object Class


The following methods are available in every Java object because all classes inherit them:
Method Purpose
Object clone() Creates and returns a copy of the object.
boolean equals(Object object) Determines if one object is equal to another.

Janhavi Nandish, CSD, ATMECE


Method Purpose
Called before an unused object is garbage
void finalize()
collected.
Class<?> getClass() Returns the runtime class of the object.
int hashCode() Returns the hash code of the invoking object.
Wakes up one thread waiting on the object's
void notify()
monitor.
Wakes up all threads waiting on the object's
void notifyAll()
monitor.
String toString() Returns a string representation of the object.
void wait() Causes current thread to wait until notified.
Makes the thread wait for given time unless
void wait(long milliseconds)
notified.
void wait(long milliseconds, int
More precise timed wait.
nanoseconds)

4. Methods Declared as final


The following methods in Object are declared final, meaning subclasses cannot override
them:
• getClass()
• notify()
• notifyAll()
• wait() (all three versions)
These methods maintain the integrity of Java’s synchronization and reflection features.

5. Methods Commonly Overridden


Some Object methods are frequently overridden in user-defined classes:
equals(Object obj)
• Used to compare two objects for equality.
• The definition of equality depends on the object's class.
• Example: String class overrides equals() to compare text, not reference.
toString()
• Returns a text description of an object.
• Automatically called when an object is passed to println().
Example:
[Link](someObject);
Internally calls:
[Link]();
• Classes often override this method to provide meaningful object descriptions.

Janhavi Nandish, CSD, ATMECE


6. finalize()
• Called just before garbage collection.
• Used for cleanup tasks (rarely used in modern Java).

7. Note About getClass() Return Type


• The syntax Class<?> in the return type relates to Java Generics.
• It means the method returns a class object of an unknown type.
• Generics are explained in Chapter 14 (as mentioned in your text).

Interfaces in Java
1. Introduction to Interfaces
• In Java, the keyword interface allows you to fully abstract a class’s interface from
its implementation.
• An interface specifies what a class must do, not how it does it.
• Interfaces:
o Cannot have instance variables.
o Methods normally have no body (i.e., abstract methods).
o Can be implemented by any number of classes.
o A single class can implement multiple interfaces.
Purpose
• To support polymorphism (“one interface, multiple implementations”).
• To avoid forcing all functionality into class hierarchies.
• To allow unrelated classes to implement the same interface.

2. Interface Characteristics
Before JDK 8
• Interfaces contained:
o Only abstract methods
o Only public static final constants
From JDK 8
• Interfaces can also contain default methods (methods with a body).
• However, typically interfaces still only define method signatures.
Important Points
• Interface variables are:
o Implicitly public, static, final
• Interface methods are:
o Implicitly public and abstract (unless default)

3. General Syntax of an Interface


access interface name {
return-type method1(parameter-list);
return-type method2(parameter-list);

Janhavi Nandish, CSD, ATMECE


type final_var1 = value;
...
}
• If public, the file name must match the interface name.
• Without access modifier → default access within package.

4. Example: Simple Interface


interface Callback {
void callback(int param);
}

5. Implementing an Interface
To implement an interface → use implements.
General Form
class classname [extends superclass] [implements interface1, interface2 ...] {
// class-body
}
Key Rule
• All interface methods must be declared public in the implementing class.
Example
class Client implements Callback {
public void callback(int p) {
[Link]("callback called with " + p);
}
}
This class implements the Callback interface, and provides the actual behavior of the
callback() method.
It demonstrates how a class must override all interface methods and how the method
becomes public when implemented.

6. Interface with Additional Class Members


A class may implement an interface and have its own members.
class Client implements Callback {
public void callback(int p) {
[Link]("callback called with " + p);
}

void nonIfaceMeth() {
[Link]("Classes that implement interfaces may also define other
members.");
}
}

Janhavi Nandish, CSD, ATMECE


7. Accessing Implementation via Interface Reference
class TestIface {
public static void main(String args[]) {
Callback c = new Client();
[Link](42);
}
}
• Only interface methods are accessible.
• Class-specific methods like nonIfaceMeth() are not accessible via interface reference.
This program shows that you can create a reference of interface type and assign an object
of the implementing class.
It demonstrates runtime polymorphism, meaning the method executed depends on the
actual object.

8. Polymorphism with Interfaces


Second implementation:
class AnotherClient implements Callback {
public void callback(int p) {
[Link]("Another version of callback");
[Link]("p squared is " + (p*p));
}
}
Test example:
class TestIface2 {
public static void main(String args[]) {
Callback c = new Client();
AnotherClient ob = new AnotherClient();
[Link](42);
c = ob;
[Link](42);
}
}
Shows runtime method dispatch —
the interface reference can point to different objects at different times, and the appropriate
implementation is called automatically.

9. Partial Implementations
If a class does not implement all interface methods → it must be abstract.
abstract class Incomplete implements Callback {
int a, b;
void show() {
[Link](a + " " + b);
}

Janhavi Nandish, CSD, ATMECE


}

10. Nested Interfaces


Interfaces can be declared inside classes or other interfaces.
Example
class A {
public interface NestedIF {
boolean isNotNegative(int x);
}
}

class B implements [Link] {


public boolean isNotNegative(int x) {
return x < 0 ? false : true;
}
}
Using nested interface:
class NestedIFDemo {
public static void main(String args[]) {
[Link] nif = new B();
if([Link](10))
[Link]("10 is not negative");
}
}
Shows that an interface can be declared inside another class.
The implementing class must use the syntax [Link].
Demonstrates scoping and organization of interfaces.

11. Applying Interfaces: Stack Example


Stack Interface
interface IntStack {
void push(int item);
int pop();
}
Defines an interface for stack operations.
Shows real-life use of interfaces to specify behavior rules.

12. Fixed-Size Stack Implementation


class FixedStack implements IntStack {
private int stck[];
private int tos;

Janhavi Nandish, CSD, ATMECE


FixedStack(int size) {
stck = new int[size];
tos = -1;
}

public void push(int item) {


if(tos==[Link]-1)
[Link]("Stack is full.");
else
stck[++tos] = item;
}

public int pop() {


if(tos < 0) {
[Link]("Stack underflow.");
return 0;
}
else
return stck[tos--];
}
}

Implements the IntStack interface using a fixed-size array.


Demonstrates:
• implementing multiple interface methods
• stack overflow check
• stack underflow check
It is an example of a concrete implementation of an interface.

Test
class IFTest {
public static void main(String args[]) {
FixedStack mystack1 = new FixedStack(5);
FixedStack mystack2 = new FixedStack(8);

for(int i=0; i<5; i++) [Link](i);


for(int i=0; i<8; i++) [Link](i);

[Link]("Stack in mystack1:");
for(int i=0; i<5; i++)
[Link]([Link]());

Janhavi Nandish, CSD, ATMECE


[Link]("Stack in mystack2:");
for(int i=0; i<8; i++)
[Link]([Link]());
}
}
Pushes values into a stack, then removes them, showing how the implemented stack works.

13. Dynamic/Growable Stack


class DynStack implements IntStack {
private int stck[];
private int tos;

DynStack(int size) {
stck = new int[size];
tos = -1;
}

public void push(int item) {


if(tos==[Link]-1) {
int temp[] = new int[[Link] * 2];
for(int i=0; i<[Link]; i++) temp[i] = stck[i];
stck = temp;
}
stck[++tos] = item;
}

public int pop() {


if(tos < 0) {
[Link]("Stack underflow.");
return 0;
}
else
return stck[tos--];
}
}
Description
Implements the stack with dynamic resizing.
When stack becomes full, it:
• creates a new array of double size
• copies old elements
• continues push
Shows how interfaces allow different implementations of same behavior.

Janhavi Nandish, CSD, ATMECE


14. Using Interface Reference for Both Implementations
class IFTest3 {
public static void main(String args[]) {
IntStack mystack;
DynStack ds = new DynStack(5);
FixedStack fs = new FixedStack(8);

mystack = ds;
for(int i=0; i<12; i++) [Link](i);

mystack = fs;
for(int i=0; i<8; i++) [Link](i);

mystack = ds;
[Link]("Values in dynamic stack:");
for(int i=0; i<12; i++)
[Link]([Link]());

mystack = fs;
[Link]("Values in fixed stack:");
for(int i=0; i<8; i++)
[Link]([Link]());
}
}
Demonstrates programming to an interface, meaning:
• Code uses interface type
• Object can be replaced anytime
• Same code works with different implementations
Shows maximum flexibility.

15. Interfaces with Shared Constants


interface SharedConstants {
int NO = 0;
int YES = 1;
int MAYBE = 2;
int LATER = 3;
int SOON = 4;
int NEVER = 5;
}
Using the constants:
class Question implements SharedConstants {
Random rand = new Random();

Janhavi Nandish, CSD, ATMECE


int ask() {
int prob = (int) (100 * [Link]());
if (prob < 30) return NO;
else if (prob < 60) return YES;
else if (prob < 75) return LATER;
else if (prob < 98) return SOON;
else return NEVER;
}
}
Main class:
class AskMe implements SharedConstants {
static void answer(int result) {
switch(result) {
case NO: [Link]("No"); break;
case YES: [Link]("Yes"); break;
case MAYBE: [Link]("Maybe"); break;
case LATER: [Link]("Later"); break;
case SOON: [Link]("Soon"); break;
case NEVER: [Link]("Never"); break;
}
}

public static void main(String args[]) {


Question q = new Question();
answer([Link]());
answer([Link]());
answer([Link]());
answer([Link]());
}
}
Shows that interfaces can be used to store constants.
All constants are automatically:
• public
• static
• final
Useful for common status codes.

16. Interface Inheritance (Extending Interfaces)


interface A {
void meth1();
void meth2();
}

Janhavi Nandish, CSD, ATMECE


interface B extends A {
void meth3();
}

class MyClass implements B {


public void meth1() { [Link]("Implement meth1()."); }
public void meth2() { [Link]("Implement meth2()."); }
public void meth3() { [Link]("Implement meth3()."); }
}

class IFExtend {
public static void main(String arg[]) {
MyClass ob = new MyClass();
ob.meth1();
ob.meth2();
ob.meth3();
}
}
Shows that interfaces can extend other interfaces, allowing hierarchical design.
A class implementing B must:
• implement methods of A
• implement method of B
Demonstrates interface-level inheritance.
Provides implementation for all methods inherited from interface A and interface B.
Shows how interface extension works in real code.

Default Interface Methods

1. Introduction to Default Interface Methods


Before JDK 8
• Interfaces could not define any implementation.
• All interface methods were abstract and had no method body.
• Every implementing class was required to provide implementations for all methods.
After JDK 8
• Java added a new feature: default methods.
• A default method allows an interface to provide a method body.
• During development, these were also called extension methods.

2. Why Default Methods Were Introduced?


(A) To Expand Interfaces Without Breaking Old Code
• If a new method was added to a widely used interface (before JDK 8),
all old classes would break, since they lacked implementation.

Janhavi Nandish, CSD, ATMECE


• Default methods solve this problem by providing a built-in implementation.
• Thus:
o The interface can evolve,
o Preexisting code continues to work.
(B) To Support Optional Methods
• Some interface methods may be optional, depending on usage.
• Example given:
o A remove() method might be optional for nonmodifiable sequences.
• Without default methods:
o Classes had to implement a do-nothing or empty method.
• With default methods:
o The interface itself can provide a default version.

3. What Default Methods Do Not Change


Default methods do not convert interfaces into classes.
Important restrictions are unchanged:
✔ Interfaces still cannot have instance variables.
✔ Interfaces still cannot maintain state.
✔ You cannot create objects of an interface, even with default methods.
✔ A class is still required to implement the interface.
Thus:
• Classes = define state + behavior
• Interfaces = define behavior only, even after JDK 8.

4. Default Methods Are Special-Purpose


• Interfaces will still be used primarily to describe what must be done,
not how it is done.
• Default methods provide additional, optional flexibility.

5. Default Method Fundamentals


Syntax
To define a default method inside an interface:
default returnType methodName() {
// method body
}
Example from text
public interface MyIF {
int getNumber(); // normal abstract method

default String getString() {


return "Default String"; // default implementation
}
}

Janhavi Nandish, CSD, ATMECE


Rules:
• Only methods marked with default can have a body.
• Implementing classes may override default methods, but are not required to.

6. Using Default Methods (From Given Text)


Case 1: A class that does NOT override the default method
class MyIFImp implements MyIF {
public int getNumber() {
return 100;
}
// getString() is inherited with default implementation
}
Output when used:
100
Default String

Explanation
• getNumber() must be implemented because it is abstract.
• getString() is optional because the interface provides a default version.
• When called:
o getNumber() returns 100.
o getString() returns "Default String" (as defined in interface).

Case 2: A Class That Overrides the Default Method


Code (from your provided text)
class MyIFImp2 implements MyIF {
public int getNumber() {
return 200; // required
}

public String getString() {


return "This is a different String."; // overridden default method
}
}
Explanation
• The class provides its own implementation of getString().
• Now the default version is ignored.
• When used:
o getNumber() → returns 200
o getString() → returns “This is a different String.”

Static Methods in Interfaces (As per Provided Text)


• Java allows interfaces to include static methods.

Janhavi Nandish, CSD, ATMECE


• These methods must have a body.
• They are not inherited by implementing classes.
• They are called using the interface name, not the object.
Example (from text)
public interface MyIF {
static int getDefaultNumber() {
return 0;
}
}
Call using
int x = [Link]();

Multiple Inheritance and Default Methods


Diamond Problem Solution
• If a class implements two interfaces that contain default methods with the same
name, Java forces the class to explicitly override it.
• This prevents ambiguity.
Example from text:
interface A {
default void show() {
[Link]("A");
}
}

interface B {
default void show() {
[Link]("B");
}
}

class C implements A, B {
public void show() {
[Link](); // or [Link]()
}
}
Explanation
• Since both interfaces provide show() default method:
o Class must override the method.
o Inside it, you may call the specific interface version using
[Link]().

✔ Benefits of Default Methods (Summary based on your text only)


• Allow adding new methods to interfaces without breaking old code.

Janhavi Nandish, CSD, ATMECE


• Help support optional methods in interfaces.
• Offer controlled flexibility while still keeping interfaces lightweight and stateless.
• Enhance interface capabilities but do not change their fundamental nature.

Static Methods in an Interface

1. Introduction to Static Methods in Interfaces


• Starting from JDK 8, Java allows static methods to be declared inside interfaces.
• These methods operate just like static methods in classes.
• They belong to the interface itself, not to any object.

2. Purpose and Behavior


✔ No Object Required
• A static interface method can be called without creating an instance of the interface.
• It also does not require any class to implement the interface.
✔ Called with Interface Name
The calling syntax is:
[Link]
This is identical to calling static methods in classes.

3. General Form
[Link]
Example from explanation:
int defNum = [Link]();

4. Example from the Given Text


Interface with Static Method
public interface MyIF {
// Normal abstract method (no default implementation)
int getNumber();

// Default method with implementation


default String getString() {
return "Default String";
}

// Static interface method


static int getDefaultNumber() {
return 0;
}
}
Explanation
Janhavi Nandish, CSD, ATMECE
• getNumber() → abstract method (must be implemented by classes).
• getString() → default method (optional to override).
• getDefaultNumber() → static method:
o Has a body.
o Can be called without any object or implementation of MyIF.

5. Calling the Static Interface Method


int defNum = [Link]();
✔ Key Point:
No object of the interface is needed.
No implementing class is required.

6. Important Rule: Static Methods Are Not Inherited


• Static methods inside an interface are NOT inherited by:
o Implementing classes
o Subinterfaces
Meaning:
• Implementing classes cannot call the static method using [Link]().
• Subinterfaces do not gain the static method automatically.
They can only be accessed using:
[Link]()

Private Interface Methods

Private and static private interface methods were introduced in Java 9. Being a private
method, such a method cannot be accessed via implementing class or sub-interface. This
methods were introduced to allow encapsulation where the implementation of certain method
will be kept in interface only. It helps to reduce the duplicity, increase maintainablity and to
write clean code.
Prior to Java 8, interface can have only abstract method and constant variables. So
implementing class has to implement the same. See the below example.

package demo;

interface util {
public int sum(int a, int b);
}

public class Tester implements util {


public static void main(String[] args) {
Tester tester = new Tester();
[Link]([Link](2, 3));
}

Janhavi Nandish, CSD, ATMECE


@Override
public int sum(int a, int b) {
return a + b;
}
}
Output
5

In the above example, we can see that the implementing class has to implement the method as
it implements the interface. With Java 8, default methods were introduced, where we can
provide the default implementation of the method, and the implementing class does not need
to implement the same. This feature was introduced to facilitate lambda expressions where
the existing collection framework can work with newly introduced functional interfaces
without implementing all the methods of the interfaces. This helped in avoiding the rewriting
of the collection framework. See the example below –

package demo;

interface util {
public default int sum(int a, int b) {
return a + b;
}
}

public class Tester implements util {


public static void main(String[] args) {
Tester tester = new Tester();
[Link]([Link](2, 3));
}
}

Output
5

Janhavi Nandish, CSD, ATMECE

You might also like