.
Multiple Inheritance (Through Interfaces)
In Multiple inheritances, one class can have more
than one superclass and inherit features from all
parent classes. Please note that Java does not
support multiple inheritances with classes. In Java,
we can achieve multiple inheritances only through
Interfaces. In the image below, Class C is derived
from interfaces A and B.
. Hybrid Inheritance
It is a mix of two or more of the above types
of inheritance.
Since Java doesn’t support multiple
inheritances with classes, hybrid inheritance
involving multiple inheritance is also not
possible with classes.
In Java, we can achieve hybrid inheritance
only through Interfaces if we want to involve
multiple inheritaance to implement Hybrid
inheritance.
It is important to note that Hybrid inheritance
does not necessarily require the use of
Multiple Inheritance exclusively.
It can be achieved through a combination of
Multilevel Inheritance and Hierarchical
Inheritance with classes, Hierarchical and
Single Inheritance with classes. Therefore, it is
indeed possible to implement Hybrid
inheritance using classes alone, without
relying on multiple inheritance type.
class C
public void disp()
System.out.println("C"); }
class A extends C
public void disp()
System.out.println("A"); }
}
class B extends C
public void disp() { System.out.println("B"); }
class D extends A
public void disp()
{ System.out.println("D"); }
public static void main(String args[]){ D obj = new
D(); obj.disp(); }
Output:
D
Access Modifiers in Java provides a restriction on the scope of the class,
instance variables, methods, and constructors.
There are four Access modifiers in Java- Default, Private, Protected, and Public.
In Java, access modifiers control visibility.
private :restricts access, like keeping personal salary details within the family.
public :allows unrestricted access, akin to everyone knowing your name.
Protected: is similar to public but with some limitations.
Default: serves as a baseline, accessible within its package. These modifiers
manage visibility, for instance, variables, constructors, and methods.
member access rules in java
Member access rules in Java
In Java, member access rules are enforced using access modifiers (also known as access
specifiers or visibility modifiers). These keywords control the visibility and accessibility of
classes, fields (variables), and methods.
Here's a breakdown of the four access modifiers:
1. Private
Keyword: private
Accessibility: Accessible only within the same class where it's declared.
Use Case: Primarily used for encapsulation, to protect sensitive data and internal
implementation details from being accessed or modified directly from outside the class.
Example: A BankAccount class might have a private balance variable to prevent direct
manipulation, with controlled access through public methods like deposit() and
withdraw().
2. Default (package-private)
Keyword: No keyword is used; it's the default if no other access modifier is specified.
Accessibility: Accessible only within the same package.
Use Case: Suitable for classes, methods, or variables that are closely related and should
only be accessed by other classes within the same package.
Example: In a library management system, classes like Book, Library, and Librarian might
use default access for their members if they are meant to be accessed only within the
library package.
3. Protected
Keyword: protected
Accessibility: Accessible within the same package and by subclasses (even if in different
packages).
Use Case: Used in inheritance scenarios, where you want to allow child classes to access
and potentially modify or reuse certain members of the parent class, while still limiting
access from unrelated classes.
Example: A Vehicle superclass might have a protected brand variable that can be accessed
and set by a Car subclass even if they are in different packages, according to Hero Vired.
4. Public
Keyword: public
Accessibility: Accessible from anywhere in the program, regardless of the package or class.
Use Case: Typically used for exposing functionality or data that needs to be accessed
globally, such as entry-point methods (like main()) or APIs that are part of a library or
framework.
Example: Public methods in a REST API controller that handle client requests,
Java this Keyword:
The this keyword in Java refers to the current object in a method
or constructor.
The this keyword is often used to avoid confusion when class
attributes have the same name as method or constructor
parameters.
Accessing Class Attributes
Sometimes a constructor or method has a parameter with the
same name as a class variable. When this happens, the
parameter temporarily hides the class variable inside that
method or constructor.
To refer to the class variable and not the parameter, you can use
the this keyword.
public class Main {
int x; // Class variable x
// Constructor with one parameter x
public Main(int x)
{
this.x = x; // refers to the class variable x
}
public static void main(String[] args)
{
// Create an object of Main and pass the value 5 to the constructor
Main myObj = new Main(5);
System.out.println("Value of x = " + myObj.x);
}
}
Output:
Value of x = 5
Tip: Think of this.x = x; as: "this.x (the class variable) gets the value of x
(the parameter)."
Without this, the code above x = x; would set the parameter x equal to
itself, and the class variable would stay uninitialized (0).
Java super
The super keyword in Java is used in subclasses to
access superclass members (attributes,
constructors and methods).
Uses of super keyword
To call methods of the superclass that is
overridden in the subclass.
To access attributes (fields) of the superclass if
both superclass and subclass have attributes with
the same name.
To explicitly call superclass no-arg (default) or
parameterized constructor from the subclass
constructor.
class Animal
{ // Superclass (parent)
public void animalSound()
{
System.out.println("The animal makes
sound");
}
}
class Dog extends Animal
{ // Subclass (child)
public void animalSound()
{
super.animalSound(); // Call the
superclass method
System.out.println ("The dog says: bow
wow");
}
}
public class Main {
public static void main(String args[])
{
Dog myDog = new Dog(); // Create a
Dog object
myDog.animalSound(); // Call the
method on the Dog object
Method Overloading
With method overloading, multiple
methods can have the same name with
different parameters.
void func() { ... }
void func(int a) { ... }
float func(double a) { ... }
float func(int a, float b) { ... }
Here, the func() method is overloaded.
These methods have the same name
but accept different arguments.
class MethodOverloading
{
private static void display(int a)
{
System.out.println("Arguments:
" + a);
}
private static void display(int a, int
b){
System.out.println("Arguments: Arguments:
" + a + " and " + b); 1
} Arguments:
1 and 4
public static void main(String[]
args)
{
display(1);
display(1, 4);
}
}
class MethodOverloading
{
// this method accepts int
private static void display(int a)
Here, both overloaded
{
methods accept one argument.
System.out.println("Got Integer
However, one accepts the
data.");
argument of type int whereas
}
other accepts String object.
// this method accepts String object
private static void display(String a) Got Integer data.
{ Got String object.
System.out.println("Got String
object.");
}
public static void main(String[] args)
{
display(1);
display("Hello");
}
}
class HelperService
{
private String formatNumber(int value)
{
return String.format("%d", value);
}
private String formatNumber(double value)
{
return String.format("%.3f", value);
}
private String formatNumber(String value)
{ 500
return String.format("%.2f", 89.993
Double.parseDouble(value)); 550.00
}
public static void main(String[] args)
{
HelperService hs = new HelperService();
System.out.println(hs.formatNumber(500));
System.out.println(hs.formatNumber(89.9934));
System.out.println(hs.formatNumber("550"));
}
}
What is Method Overriding?
Method Overriding in Java means redefining a method of
the superclass in the subclass to provide a specific
implementation.
It enables runtime polymorphism, where the method
that gets called is determined by the object type at
runtime.
Syntax:
class Parent {
void show() {
System.out.println("This is the parent class");
}
}
class Child extends Parent {
//Override
void show() {
System.out.println("This is the child class");
}
class Animal {
void sound() { The object a is of type Animal, but it
actually refers to an instance of Dog.
System.out.println("Animal
Because the sound() method is
makes a sound"); overridden in the Dog class, and Java
} uses dynamic method dispatch, the
} overridden method in Dog is called at
runtime.
class Dog extends Animal {
//Override This demonstrates runtime
void sound() { polymorphism in action.
System.out.println("Dog
barks");
}
}
public class Main {
public static void
main(String[] args) {
Animal a = new Dog(); //
Upcasting
a.sound(); // Outputs: Dog
Abstract Classes and Methods:
Data abstraction is the process of hiding certain
details and showing only essential information to the
user.
Abstraction can be achieved with either abstract
classes or interfaces (which you will learn more about
in the next chapter).
The abstract keyword is a non-access modifier, used
for classes and methods:
Abstract class: is a restricted class that cannot be used
to create objects (to access it, it must be inherited
from another class).
Abstract method: can only be used in an abstract
class, and it does not have a body. The body is
provided by the subclass (inherited from).
An abstract class can have both abstract and regular
methods.
abstract class Animal
{
public abstract void animalSound();
public void sleep()
{
System.out.println("Zzz");
}
}
From the example above, it is not possible to create an
object of the Animal class:
Animal myObj = new Animal(); // will generate an error
To access the abstract class, it must be inherited from
another class. Let's convert the Animal class we used in
the Polymorphism chapter to an abstract class:
// Abstract class
abstract class Animal {
// Abstract method (does not have a body)o/p
public abstract void animalSound(); The pig says: wee wee
// Regular method Zzz
public void sleep() {
System.out.println("Zzz"); Why And When To Use
} Abstract Classes and
} Methods?
To achieve security - hide
// Subclass (inherit from Animal) certain details and only
class Pig extends Animal { show the important details
public void animalSound() { of an object.
// The body of animalSound() is provided
here
System.out.println("The pig says: wee
wee");
}
}
class Main {
public static void main(String[] args) {
Pig myPig = new Pig(); // Create a Pig
object
DYNAMIC METHOD DISPATCH or RUN
TIME POLYMORPHISM
Definition:
Dynamic Method Dispatch is the process
by which a call to an overridden method
is resolved at runtime, rather than at
compile time.
It is a key feature of runtime
polymorphism in Java.
How It Works:
When a superclass reference variable
refers to a subclass object, and a
method is overridden in the subclass,
the overridden method is called based
on the object, not the reference type.
This decision happens at
runtime, not during
compilation.
class Animal {
void sound() {
System.out.println("Animal makes a
sound");
}}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Cat meows");
}}
public class Main {
public static void main(String[] args) {
Animal a; // Reference of superclass
a = new Dog(); // Object of subclass Dog
a.sound(); // Output: Dog barks
a = new Cat(); // Object of subclass Cat
a.sound(); // Output: Cat meows
}
The final keyword in Java is used to 2. Final MethodA final method
restrict modification. Depending on cannot be overridden by any
how it is used, it can apply to: subclass.
class Parent {
Variables (prevent reassignment) final void show() {
Methods (prevent overriding) System.out.println("This is
Classes (prevent inheritance) final method");
}
}
1. Final Variable:
A variable declared final cannot be class Child extends Parent {
reassigned after initialization. // void show() { ... } ❌ Error:
cannot override final method
final int x = 10; }
x = 20; // ❌ Error: cannot assign a Ensures the method's behavior
value to final variable remains unchanged in subclasses.
You must initialize it once, either at
declaration or in the constructor
(for instance variables).
3. Final ClassA final class cannot be extended (inherited)
final class Animal {
void sound() {
System.out.println("Animal sound");
}
}
// class Dog extends Animal ❌ Error: cannot subclass final
class
Use Effect
Value cannot be changed
final variable
(constant)
Cannot be overridden in
final method
subclasses
Cannot be extended (no
final class
subclasses)
Java Packages:
What is a Package in Java?
A package in Java is a namespace that organizes classes and interfaces. Think
of it like a folder in a file system—it groups related files (in Java's case, classes).
It helps in:
Avoiding name conflicts
Managing code easily
Controlling access with protected/default access
Type Example Description
Built-in java.util, java.io Provided by Java API
Created by the Custom grouping of
User-defined
developer your classes
Creating a Package (User-defined) Java's Built-in Packages
Step 1: Declare package at the top of the (Examples)
Java file.
| Package | Description
package mypackage; |
| ----------- |
public class MyClass { --------------------------------- |
public void display() { | `java.lang` | Core classes
System.out.println("Hello from (String, Math, etc.) |
MyClass in mypackage"); | `java.util` | Collections, Date,
} Random, etc. |
} | `java.io` | Input and Output
(File handling) |
Step 2: Save the file in a folder named | `java.net` | Networking classes
mypackage |
Step 3: Use the class from another | `java.sql` | Database
package programming (JDBC) |
import mypackage.MyClass; Note: java.lang is automatically
imported in every Java program.
public class Test {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.display();
Subcl
Acces
Same ass Other Benefits of Packages:
s Same
Packa (othe Packa
Modif Class
ge r ges Modularity: Code is easier
ier
pkg) to maintain and scale.
publi Reusability:
✅ ✅ ✅ ✅
c Classes in packages can be
reused.
prote
✅ ✅ ✅ ❌
cted Encapsulation: Helps
control visibility and access.
defau
lt (no Namespace management:
✅ ✅ ❌ ❌ Avoids class name conflicts.
modif
ier)
priva
✅ ❌ ❌ ❌
te
Java Interface:
An interface is a completely "abstract class" that is
used to group related methods with empty bodies.
An interface in Java is like a contract. It defines what
a class should do, but not how it should do it. Think
of it as a set of method declarations without any
implementation.
Why Use Interfaces?
To achieve abstraction.
To support multiple inheritance (Java does not
support multiple inheritance with classes, but
interfaces solve this).
To define a common behavior that multiple classes
can implement.
Defining an Interface
interface Animal {
void makeSound(); // abstract method (no body)
void eat();
Defining an Interface Using the Interface:
public class Main {
interface Animal { public static void main(String[] args)
void makeSound(); // abstract {
method (no body) Dog myDog = new Dog(); // Creating
void eat(); Dog object directly
} myDog.makeSound(); // Calls
By default, all methods in Dog's implementation
interfaces are public and abstract myDog.eat(); // Calls Dog's
(unless they are static or default). implementation
}
Implementing an Interface: }
class Dog implements Animal
{
public void makeSound()
{
System.out.println("Woof!");
}
public void eat()
{
System.out.println("Dog is
eating.");
// Define interface A // Main class to run the program
interface A
{ public class InterfaceExample
void show(); // Abstract method to {
be implemented by any class that public static void main(String[]
implements A args)
} {
// Define interface B MyClass obj = new
interface B MyClass(); // Create object of
{ MyClass
void display(); // Abstract method
to be implemented by any class that obj.show(); // Call method
implements B from interface A
} obj.display(); // Call method
// Class implementing both interfaces from interface B
A and B }
class MyClass implements A, B }
{
// Implement show() from interface
A
public void show() {
System.out.println("Show from
A");
}
EXTENDING INTERFACES: (INHERITING INTERFACES)
Just like classes can extend other classes, interfaces
in Java can extend other interfaces.
🟢 Purpose: It allows an interface to inherit method
declarations from another interface and optionally
add more methods.
interface A
{
void methodA();
}
interface B extends A
{
void methodB();
}
Here, interface B extends interface A.So any class that
implements B must implement both methodA() and
methodB().
interface Animal {
void eat();
}
interface Dog extends Animal {
void bark();
}
class Labrador implements Dog {
public void eat() {
System.out.println("Labrador
eats food.");
}
public void bark() {
System.out.println("Labrador
barks.");
}
}
public class Main {
public static void main(String[]
args) {
Labrador lab = new Labrador();
lab.eat(); // from Animal
interface
lab.bark(); // from Dog
interface
}
Concept Description
Used to inherit methods from
extends
another interface.
Interface can extend another
Multi-level Inheritance
extended interface.
An interface can extend multiple
Multiple Inheritance
interfaces!
interface A {
void methodA();
}
interface B {
void methodB();
}
interface C extends A, B {
void methodC();
}
class MyClass implements C {
public void methodA() {
System.out.println("Method A");
}
public void methodB() {
System.out.println("Method B");
}
public void methodC() {
System.out.println("Method C");
}}