Java Module 2
Java Module 2
Inheritance:
A new class (called a subclass or child class) inherit the properties (fields) and
behaviors (methods) of an existing class (called a superclass or parent class) is called
inheritance.
Parent class: The class whose properties and behaviors inherited.
Child class: The class inherite the properties and behaviors from base class.
Use of Inheritance:
Reuse code from the parent class.
Code Reusability
Extending Functionality
Reducing Redundancy
Supporting Dynamic Method Overriding
Syntax:
class parentclass{
//methods and fields;
}
Class childclass extends parentclass{
//methods and fields;
}
Types of inheritance:
1. Single Inheritance
2. Hierarchal Inheritance
3. Multilevel Inheritance
4. Hybrid Inheritance
5. Multiple Inheritance
1. Single Inheritance: One class inherits from a single base class.
void displayInfo() {
System.out.println("Brand: " + brand);
System.out.println("Colour: " + colour);
System.out.println("Fuel Type: " + fuelType);
System.out.println("Speed: " + speed + " km/h");
}
}
void displayCarInfo() {
displayInfo();
System.out.println("Wheels: " + wheels);
System.out.println("This car can carry 6 passengers.");
}
}
void displayInfo() {
System.out.println("Brand: " + brand);
System.out.println("Colour: " + colour);
System.out.println("Fuel Type: " + fuelType);
System.out.println("Speed: " + speed + " km/h");
}
}
void displayCarInfo() {
displayInfo();
System.out.println("Wheels: " + wheels);
System.out.println("This car can carry 6 passengers.");
}
}
// Child Class 2: Bike
class Bike extends Vehicle {
boolean hasHelmet;
void displayBikeInfo() {
displayInfo();
System.out.println("Has Helmet: " + hasHelmet);
System.out.println("This bike can carry 2 passengers.");
}
}
3. Multilevel Inheritance: A class inherits from a derived class, which in turn inherits from
a base class.
Example: Class C inherits from class B, and class B inherits from class A.
void displayInfo() {
System.out.println("Brand: " + brand);
System.out.println("Colour: " + colour);
System.out.println("Fuel Type: " + fuelType);
System.out.println("Speed: " + speed + " km/h");
}
}
void displayCarInfo() {
displayInfo();
System.out.println("Wheels: " + wheels);
System.out.println("This car can carry 6 passengers.");
}
}
void displayElectricCarInfo() {
displayCarInfo();
System.out.println("Battery Capacity: " + batteryCapacity + " kWh");
System.out.println("This electric car can carry 4 passengers.");
}
}
void displayInfo() {
System.out.println("Brand: " + brand);
System.out.println("Colour: " + colour);
System.out.println("Fuel Type: " + fuelType);
System.out.println("Speed: " + speed + " km/h");
}
void displayCarInfo() {
displayInfo();
System.out.println("Wheels: " + wheels);
displayPassengerCapacity("Car");
}
}
void displayBikeInfo() {
displayInfo();
System.out.println("Has Helmet: " + hasHelmet);
displayPassengerCapacity("Bike");
}
}
void displayBusInfo() {
displayInfo();
System.out.println("Seating Capacity: " + seatingCapacity);
displayPassengerCapacity("Bus");
}
}
5. Multiple Inheritance (Java does not support multiple inheritance through classes,
but it can be achieved using interfaces):
A class inherits from more than one base class (Java does not allow multiple
inheritance through classes to avoid ambiguity, but it allows multiple inheritance
through interfaces).
Example:
class Vehicle {
public String brand;
private String fuelType; // Private member: can only be accessed within the Vehicle class
protected int speed; // Protected member: can be accessed by subclasses
int wheels; // Default access: can only be accessed within the same package
super keyword:
The super keyword in Java is used to refer to the superclass (parent class) of the current
object. It can be used in a few contexts:
1. Accessing Superclass Fields: You can use super to access fields of the superclass if
the subclass has a field with the same name.
2. Accessing Superclass Methods: When a subclass overrides a method, you can use
super to call the method from the superclass.
3. Accessing Superclass Constructor: It can be used to call a constructor of the
superclass from the subclass constructor.
1. super can be used to refer immediate parent class instance variable
We can use super keyword to access the data member or field of parent class. It is used if
parent class and child class have same fields.
Example:
class Vehicle {
String brand = "Toyota"; // Parent class instance variable
}
class Car extends Vehicle {
String brand = "Honda"; // Child class instance variable
void display() {
System.out.println("Car Brand: " + brand); // Display the child's own brand
System.out.println("Vehicle Brand: " + super.brand); // Access the parent class's brand using super
}
}
public class TestSuper {
public static void main(String[] args) {
Car car = new Car();
car.display();
}
}
Output:
Car Brand: Honda
Vehicle Brand: Toyota
To access the brand from the Vehicle class (parent), we use super.brand.
Inside the display() method, super.start() calls the start() method of the Vehicle class,
while just calling start() invokes the start() method from the Car class.
Example:
class Vehicle {
Vehicle(String brand) {
System.out.println("Vehicle Brand: " + brand);
}
}
class Car extends Vehicle {
Car() {
super("Toyota");// Call the constructor of the parent class using super()
System.out.println("Car is ready!");
}
}
public class TestSuper {
public static void main(String[] args) {
Car car = new Car();
}
}
Output:
Vehicle Brand: Toyota
Car is ready!
The Car class has a constructor that calls the parent class constructor using
super("Toyota") to pass the brand value to the Vehicle class constructor.
Polymorphism:
Polymorphism in Java is the ability of an object to take many forms. It means that you
can use the same method or class in different ways, depending on the context.
There are two types of polymorphism:
1. Method Overloading (Compile-time Polymorphism):
o When you have multiple methods with the same name but different
parameters.
o The method to be called is determined at compile time.
2. Method Overriding (Runtime Polymorphism):
o When a subclass provides its own implementation of a method that is already
defined in the superclass.
o The method to be called is determined at runtime based on the object type.
Method Overriding:
The primary purpose of method overriding is to allow the subclass to provide a specific
behavior for a method that is already defined in the superclass, essentially "overriding" the
inherited behavior.
Key Points:
1. Same method signature: The method in the subclass must have the same method
signature (name, parameters, return type) as the method in the superclass.
2. Runtime polymorphism: Method overriding is a type of runtime polymorphism
(also known as dynamic method dispatch). The method that gets called is determined
at runtime, based on the object type, not the reference type.
3. Inheritance: The subclass must inherit from the superclass in order to override a
method.
4. Access Modifiers: The overridden method in the subclass cannot have a more
restrictive access modifier than the method in the superclass. For example, if the
superclass method is public, the subclass method must also be public (or more
permissive, like protected).
Syntax:
class Superclass {
// Method in the superclass
returnType methodName(parameters) {
// method body
}
}
class Subclass extends Superclass {
// Overriding the method in the subclass
@Override
returnType methodName(parameters) {
// subclass specific implementation
}
}
Example:
class Employee {
double baseSalary = 50000;
void calculateSalary() {
System.out.println("Calculating salary for a general employee...");
}
}
class Manager extends Employee {
void calculateSalary() {// Overriding the calculateSalary method in Manager class
double bonus = 20000;
double totalSalary = baseSalary + bonus;
System.out.println("Manager's Salary with bonus: " + totalSalary);
}
}
class Engineer extends Employee {
void calculateSalary() {// Overriding the calculateSalary method in Engineer class
double bonus = 10000;
double totalSalary = baseSalary + bonus;
System.out.println("Engineer's Salary with bonus: " + totalSalary);
}
}
public class Test {
public static void main(String[] args) {
Employee emp1 = new Manager(); // Reference to Employee but object is Manager
Employee emp2 = new Engineer(); // Reference to Employee but object is Engineer
emp1.calculateSalary(); // Calls Manager's overridden method
emp2.calculateSalary(); // Calls Engineer's overridden method
}
}
Output:
Manager's Salary with bonus: 70000.0
Engineer's Salary with bonus: 60000.0
Differences between Method Overloading and Method Overriding
final keyword:
The final keyword is used to define constants, prevent method overriding, and prevent
class inheritance. It is a way to "restrict" certain features of a class, method, or variable.
Final Variable: Once assigned, the value cannot be changed.
Final Method: The method cannot be overridden by subclasses.
Final Class: The class cannot be inherited.
1. Final Variable:
When you declare a variable as final, its value cannot be changed once it is initialized.
Essentially, it becomes a constant.
Syntax:
final dataType variableName = value;
Example:
class Sample {
final int a = 10;
Sample() {
a = 20; // Error: cannot assign a value to final variable
}
}
class Test {
public static void main(String args[]) {
Sample obj = new Sample();
}
}
Explanation: In this case, a is declared as a final variable. In the constructor, we attempt to
change its value, but since it's a final variable, this results in a compilation error. Once a final
variable is assigned a value, it cannot be changed.
2. Final Method
When a method is declared as final, it cannot be overridden by any subclass. This is useful
when you want to ensure that a method’s behavior is preserved in subclasses.
Syntax:
final returnType methodName() {
// method body
}
Example:
class Base {
final void show() {
System.out.println("show() in Base Class");
}
}
Abstract Class:
An abstract class in Java is a class that cannot be instantiated directly. It is meant to
be subclassed by other classes. Abstract classes can contain both abstract methods (methods
without implementation) and concrete methods (methods with implementation). Abstract
methods must be implemented by subclasses, but concrete methods can be inherited as-is or
overridden.
Key Points About Abstract Classes in Java:
1. Abstract class cannot be instantiated.
2. It can contain abstract methods (methods without implementation).
3. It can also contain concrete methods (methods with implementation).
4. A subclass of an abstract class must implement all the abstract methods, or it must be
declared abstract itself.
Syntax for Abstract Class in Java:
abstract class abstractClassname {
abstract void abstractMethod();// Abstract method (no implementation)
}
Class childclass extends abstractclassname{
void concreteMethod() {// Concrete method (with implementation)
System.out.println("This is a concrete method.");
}
How to Define an Abstract Class:
1. Use the abstract keyword before the class declaration.
2. Declare abstract methods (methods without body) using the abstract keyword.
3. Optionally, you can include concrete methods that have a method body.
Example:
abstract class PaymentMethod {
// Abstract method (must be implemented by subclasses)
abstract void processPayment(double amount);
}
Interface:
An interface is a blueprint for a class in programming. It defines a contract of methods
(without implementation) that a class must implement. An interface only specifies what
methods a class should have, but not how they should be implemented.
Conditions for Using an Interface:
1. No Implementation: Methods in an interface are abstract by default (i.e., no method
body).
2. Multiple Implementation: A class can implement multiple interfaces, providing
flexibility in design.
3. Access Modifiers: Methods in an interface are public by default. You cannot have
private or protected methods in an interface.
4. Variables in Interfaces: Any variables defined in an interface are implicitly public,
static, and final (constants). They must be initialized when declared.
5. Interface Inheritance: An interface can extend another interface, allowing it to inherit
abstract methods from the parent interface.
1. Syntax of an Interface
In Java, the syntax for defining an interface looks like this:
interface InterfaceName {
// abstract methods (methods without implementation)
returnType methodName1(parameterList);
returnType methodName2(parameterList);
}
InterfaceName: Name of the interface.
Abstract Methods: These methods are declared without bodies, i.e., no
implementation is provided in the interface itself.
2. Defining an Interface
To define an interface in Java, we use the interface keyword. For example, let's consider an
interface for a vehicle:
interface Vehicle {
// Abstract method
void start();
void stop();
}
Here, the Vehicle interface declares two abstract methods, start() and stop(), without defining
how these methods work.
3. Implementing an Interface
To use the interface, a class must implement it. The implements keyword is used to indicate
that a class is implementing an interface. It is mandatory for the implementing class to
provide concrete implementations for all abstract methods defined in the interface.
For example:
class Car implements Vehicle {
// Providing implementation of start() method
public void start() {
System.out.println("Car is starting");
}
// Fuelable Interface
interface Fuelable {
void fuelUp(); // Method for fueling behavior
}
In this example, both Drivable and Fuelable interfaces have one method each (drive() and
fuelUp(), respectively).
2. Extending the Interfaces:
Now, let's create a Vehicle interface that extends both the Drivable and Fuelable interfaces.
This interface combines the functionality of both interfaces, and any class that implements
Vehicle must provide implementations for both drive() and fuelUp() methods.
// Vehicle Interface extending both Drivable and Fuelable interfaces
interface Vehicle extends Drivable, Fuelable {
void startEngine(); // Additional method specific to vehicles
}
Now, the Vehicle interface has inherited both the drive() method from Drivable and the
fuelUp() method from Fuelable, and it also adds its own method startEngine().
3. Implementing the Extended Interface:
Let’s implement the Vehicle interface in a class, say, for a Car:
class Car implements Vehicle {
public void drive() {
System.out.println("The car is driving.");
}
Packages in Java
A package in Java is a namespace used to group related classes, interfaces, and sub-
packages. It is used to organize the code in a hierarchical structure, making it easier to manage
large codebases, avoid name conflicts, and control access. A package is a way of grouping
related classes and interfaces together.
Packages are essential for:
1. Code organization – They group related classes into namespaces, which makes the
code easy to manage.
2. Access control – Packages provide access protection using access modifiers.
3. Avoiding name conflicts – Classes with the same name can exist in different
packages without conflict.
4. Reusability – Code in one package can be reused by importing it into other programs.
Types of Packages
1. Built-in Packages: These are pre-defined packages provided by the Java API (e.g.,
java.util, java.io).
2. User-defined Packages: These are custom packages created by the user to organize
their code.
Syntax for Defining a Package
To define a package in Java, you use the package keyword at the top of your Java source file.
Here's the syntax:
package package_name;
Access Control in Packages
Java provides access control mechanisms that determine which classes, methods, and fields
are accessible. These are controlled using access modifiers:
1. public: The class, method, or field is accessible from any other class.
2. protected: The method or field is accessible within the same package and by
subclasses.
3. private: The method or field is only accessible within the same class.
4. Default (no modifier): The method or field is accessible only within classes in the
same package.
Example: library management system that consists of multiple modules, such as a book
management module, user management, and payment management. You can organize
these modules into different packages for better code structure.
Directory Structure:
library-management/
├── books/
| Book.java
| BookManager.java
├── users/
| User.java
| UserManager.java
├── payment/
| Payment.java
| PaymentProcessor.java
└── Main.java
Book.java (inside the books package):
package books;
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
BookManager.java (inside the books package):
package books;
import users.User;
public class BookManager {
public void lendBook(Book book, User user) {
System.out.println(user.getName() + " has borrowed the book: " + book.getTitle());
}
}
User.java (inside the users package):
package users;
public class User {
private String name;
public User(String name) {
this.name = name;
}