[go: up one dir, main page]

0% found this document useful (0 votes)
33 views133 pages

OOPS Through JAVA - Unit2

Uploaded by

Gousejan Shaik
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)
33 views133 pages

OOPS Through JAVA - Unit2

Uploaded by

Gousejan Shaik
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
You are on page 1/ 133

Unit 2

SYED MUSTHAFA BYTEXL


1. Class and Object
Introduction to Classes and Objects in Java
In Java, classes and objects are essential components of object-oriented programming (OOP). They allow you to
model real-world entities and their behaviors in a structured way.
What is a Class?
A class serves as a blueprint for creating objects. It defines a set of attributes (fields) and behaviors (methods)
that the objects of the class will possess. You can think of a class as a recipe that outlines the ingredients
(attributes) and the steps (methods) for creating a specific type of object.

Members of a Class:

1. Fields (Attributes): Variables that store data specific to an object. These represent the state or
characteristics of the object.
2. Methods (Functions): Functions that define the actions and behaviors an object can perform. These
represent what the object can do.
3. Constructors: Special methods used to initialize objects when they are created. They set up the initial
state of the object.
4. Nested Classes: Classes defined within another class to improve organization and encapsulation.

Example of a Class - Bank Account:

public class BankAccount {


// Fields (Attributes)
private String accountNumber; // Encapsulation - restrict direct access
private double balance;

// Method (Function) to deposit money


public void deposit(double amount) {
balance += amount;
}

// Method (Function) to withdraw money


public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
} else {
System.out.println("Insufficient funds.");
}
}

// Constructor to initialize account details


public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber; // Use 'this' to refer to current object
this.balance = initialBalance;
}

// Getter method for accountNumber


public String getAccountNumber() {
return accountNumber;
}

// Getter method for balance


public double getBalance() {
return balance;
}

// Main method to run the program


public static void main(String[] args) {
// Creating an instance of BankAccount
BankAccount account = new BankAccount("123456789", 500.0);

// Depositing money
account.deposit(200.0);
System.out.println("New balance after deposit: " + account.getBalance());

// Withdrawing money
account.withdraw(100.0);
System.out.println("New balance after withdrawal: " + account.getBalance());

// Trying to withdraw more than the balance


account.withdraw(1000.0); // Should print "Insufficient funds."
}
}

Explanation:


Fields: accountNumber and balance are attributes that represent the state of the BankAccount object.

Methods: deposit() and withdraw() define the behaviors related to managing the account balance.

Constructor: BankAccount(String accountNumber, double initialBalance) initializes the object with the
provided account number and initial balance.
What is an Object?
An object is an instance of a class. It represents a specific realization of the class with its own unique data and
behaviors. For example, creating a BankAccount object from the BankAccount class is like baking a cake from a
recipe; each cake (object) may have its own unique characteristics.

Creating an Object:

To create an object, you use the new keyword followed by a call to the class's constructor.

Example of Creating a Bank Account Object:

public class Main {


public static void main(String[] args) {
// Create an object (instance) of the BankAccount class
BankAccount account1 = new BankAccount("ABC123", 100.00);

// Call object methods (public methods are accessible)


account1.deposit(50.00);
account1.withdraw(75.00);

// Display the current balance


System.out.println("Current Balance: $" + account1.balance); // Output: $75.00
}
}

Explanation:


account1 is an object of the BankAccount class.

new BankAccount("ABC123", 100.00) creates an instance of BankAccount with the given account number
and initial balance.
• We use deposit() and withdraw() methods to modify the object's state, and the balance is accessed to
display the current amount.
Key Points
• Encapsulation: Classes encapsulate data and methods, ensuring that internal details are hidden and only
accessible through well-defined interfaces.
• Abstraction: Classes abstract complex real-world entities into simplified representations, making it easier
to manage and interact with them.
• Instance Creation: Each object created from a class has its own distinct set of attributes and methods,
allowing for unique interactions.
Benefits of Using Classes and Objects
• Modularity: Code is organized into manageable and reusable units, making it easier to develop and
maintain.
• Reusability: Classes can be reused to create multiple objects, reducing redundancy and improving
efficiency.
• Maintainability: Changes to the class implementation are isolated from other code, making it easier to
manage and update the system.

By understanding and applying these concepts, you can build more structured and efficient Java programs that
effectively model real-world scenarios.

2. Class Declaration

Class Declaration in Java


In Java, a class is a blueprint for creating objects. It encapsulates data and the operations that can be performed
on that data. The class declaration in Java is the starting point for defining the structure and behavior of objects in
an object-oriented program.
Basic Structure of a Class Declaration
A class declaration in Java includes several key components:

1. Access Modifiers (optional): These define the visibility of the class to other classes.
2. Class Keyword: This is used to declare a class.
3. Class Name: A unique identifier for the class.
4. Superclasses and Interfaces (optional): Defines the inheritance and interface implementation.
5. Class Body: Enclosed in curly braces {}, this contains fields, methods, constructors, and nested classes.
Syntax:

[access_modifier] class ClassName [extends SuperClass] [implements Interface1, Interface2, ...] {


// Fields (Attributes)
// Methods (Functions)
// Constructors
// Nested Classes
}
Components of Class Declaration
1. Access Modifiers:

• public: The class is accessible from any other class.


• protected: Not used directly on classes (used for members).
• default (no modifier): The class is accessible only within the same package.
• private: Not used with classes (used for members).

Example:

public class Animal {


// Class content
}

2. class Keyword: It is used to declare a class, which serves as a blueprint for creating objects.

3. Class Name:

• The class name must be a valid Java identifier and follow naming conventions (e.g., Employee,
BankAccount).
• By convention, class names start with an uppercase letter.

Example:

class BankAccount {
// Class content
}

4. Superclasses and Interfaces:

• extends: Used to inherit from a superclass.


• implements: Used to implement one or more interfaces.

Example:

public class SavingsAccount extends BankAccount implements InterestBearing {


// Class content
}

5. Class Body:

• The class body contains the class's fields (attributes), methods (functions), constructors, and any nested
classes.
• Everything inside the class body defines the structure and behavior of the objects created from the class.

Example:

public class Car {


// Fields
private String model;
private String color;
private int year;

// Constructor
public Car(String model, String color, int year) {
this.model = model;
this.color = color;
this.year = year;
}

// Methods
public void startEngine() {
System.out.println("Engine started.");
}

public void drive() {


System.out.println("Car is driving.");
}
}
Access Modifiers for Classes

Access Modifiers for Classes


In Java, access modifiers define the visibility or accessibility of a class to other classes and packages. There are
only two access modifiers available for top-level classes and four for inner classes. The top-level class access
modifiers are:

1. public
2. default (no modifier)

For inner classes, Java allows the use of private and protected access modifiers in addition to public and default.

Let's go into detail:


1. public Access Modifier
• Description: A class marked as public can be accessed from anywhere. This means that any other class,
regardless of package, can access the class.

• Visibility:

• Accessible from within its own package.


• Accessible from any class in any other package.

Example:

// File: Employee.java
public class Employee {
// Class definition
}

If a class is public, it can be accessed by any other class in the same or different packages.

Key points:

• The class must be in a file that has the same name as the class (e.g., Employee.java).
• Only one public class is allowed per source file.

2. default (Package-Private) Access Modifier


• Description: If no access modifier is specified, the class is given default access (also called package-private
access).

• Visibility:

• Accessible by other classes within the same package.


• Not accessible from classes in other packages.
Example:

// File: Employee.java
class Employee {
// Class definition
}

If a class is declared with no modifier, it is accessible only to classes in the same package. Other classes in
different packages cannot see or use this class.

Key points:

• This is useful when you want to encapsulate functionality within the same package.
• No special keyword is used for default access; simply omit the modifier.

3. private Access Modifier (for Inner Classes Only)


• Description: The private access modifier can be used only for inner classes (classes declared inside
another class). A private inner class is accessible only within the enclosing outer class.
• Visibility:
• Accessible only within the enclosing class.

Example:

public class OuterClass {


private class InnerClass {
// Private inner class, accessible only within OuterClass
}
}

Notes:

• It cannot be used for top-level classes.


• A private inner class is hidden from all other classes except the outer class.

4. protected Access Modifier (for Inner Classes Only)


• Description: Like private, the protected access modifier is only applicable to inner classes. A protected
inner class is accessible within the same package and by subclasses in other packages.

• Visibility:

• Accessible by other classes in the same package.


• Accessible by subclasses in other packages.

Example:

public class OuterClass {


protected class InnerClass {
// Protected inner class, accessible in the same package and by subclasses
}
}

Key points:

• Cannot be used for top-level classes.


• Allows visibility to subclasses even in different packages.

Summary of Top-Level Class Access Modifiers:


Modifier Visibility Example

public Accessible from any class in any package. public class Employee

default Accessible only within the same package. class Employee

Summary of Inner Class Access Modifiers:


Modifier Visibility Example

public Accessible from any class in any package. public class Inner

default Accessible only within the same package. class Inner

private Accessible only within the enclosing class. private class Inner

protected Accessible within the same package and subclasses. protected class Inner

Key Takeaways:
• Top-level classes can only use public or default (package-private) access.
• Inner classes can use all four access modifiers (public, protected, default, and private).
• Default access means the class or method is visible only to other classes in the same package.
• Public classes can be accessed from anywhere, but the file name must match the class name.

By controlling the access level of your classes, you can encapsulate your code and maintain its integrity, ensuring
that only the appropriate parts of your program are exposed to external packages.

4. Members

Class members
It refer to the fields (also called instance variables), methods, constructors, and nested classes defined within a
class. These members define the behavior and state of the objects created from the class. Here's a detailed
breakdown of each type of member:
1. Fields (Instance Variables)
Fields are variables that hold the data or state of an object. Each object created from a class has its own copy of
the instance variables.
Syntax:
class ClassName {
// Field declaration
dataType fieldName;
}

Example:
class Car {
String model; // Field (instance variable)
String color; // Field (instance variable)
}

Explanation: In this example, each Car object will have its own model and color.

2. Methods
Methods define the behavior of objects. They contain the logic that manipulates the fields of the object or
performs specific actions.

Syntax:
class ClassName {
// Method declaration
returnType methodName(parameters) {
// Method body
}
}

• Example:

class Car {
String model;
String color;

// Method to display car details


void displayDetails() {
System.out.println("Model: " + model + ", Color: " + color);
}
}

Explanation: The displayDetails() method prints the model and color of the Car object. Methods often
interact with the fields of the class.

3. Constructors
A constructor is a special method used to initialize objects. It is called when an object is created using the new
keyword. Constructors usually set initial values for fields.

Syntax:
class ClassName {
// Constructor declaration
ClassName(parameters) {
// Constructor body
}
}

Example:

class Car {
String model;
String color;

// Constructor to initialize fields


Car(String model, String color) {
this.model = model;
this.color = color;
}
}

Explanation: The constructor Car(String model, String color) is called when an object of Car is created, and it
initializes the model and color fields.

4. Static Members
Static members belong to the class rather than any specific object. Static fields and methods are shared by all
objects of the class.

Static Fields: Shared among all instances of a class.

Static Methods: Can be called without creating an object of the class.

Example:

class Car {
String model;
String color;
static int numberOfCars; // Static field

// Constructor increments static field


Car(String model, String color) {
this.model = model;
this.color = color;
numberOfCars++; // Increments each time a car is created
}

static void displayNumberOfCars() { // Static method


System.out.println("Total Cars: " + numberOfCars);
}
}

Explanation: The numberOfCars field is shared across all instances of the Car class, and the static method
displayNumberOfCars() can be called without creating a Car object.

5. Nested Classes
A class can contain another class inside it. These are called nested classes. Nested classes can be static or non-
static.

Example:

class OuterClass {
int outerField;

class InnerClass { // Non-static nested class (Inner class)


void display() {
System.out.println("Outer Field: " + outerField);
}
}

static class StaticNestedClass { // Static nested class


void staticMethod() {
System.out.println("Static Nested Class");
}
}
}

• Explanation: The InnerClass can access members of the outer class, while the StaticNestedClass behaves
like a regular class but is scoped inside the outer class.

6. Access Modifiers for Members


Members of a class can have different access levels, controlled by access modifiers:

• public: Accessible from any class.


• private: Accessible only within the same class.
• protected: Accessible within the same package or subclasses.
• (default) (no modifier): Accessible within the same package.

Example:

class Car {
public String model; // Public field
private String color; // Private field

// Public method
public void displayDetails() {
System.out.println("Model: " + model);
}

// Private method
private void secretMethod() {
System.out.println("This is a private method.");
}
}

Explanation: The model field and displayDetails() method are accessible anywhere, while the color field and
secretMethod() can only be accessed within the Car class.

5. Objects

Java Objects
In Java, objects are fundamental units of Object-Oriented Programming (OOP) and represent real-life entities.
Objects are instances of classes, embodying both state and behavior, and interact with each other through
methods.
Components of an Object
1. State: Represented by the attributes or properties of the object.
2. Behavior: Represented by the methods or functions of the object.
3. Identity: A unique identifier that distinguishes one object from another.
Example of an Object: Car
Consider a real-life example of a car. Each car object will have properties like make, model, and year (state), and
behaviors like start, stop, and accelerate (methods).
Declaring and Initializing Objects
Declaring Objects
To declare an object in Java, you define a reference variable of the class type. This declaration does not allocate
memory for the object. Memory is allocated when you actually create (instantiate) the object using the new
keyword.

Example:

// Declaring an object of type Car


Car myCar;
Initializing Objects
To create an object, you use the new keyword followed by a constructor. This allocates memory for the object
and invokes the class constructor.

Example:

// Class Declaration
public class Car {
// Instance Variables
String make;
String model;
int year;

// Constructor
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}

// Methods
public String getMake() { return make; }
public String getModel() { return model; }
public int getYear() { return year; }

@Override
public String toString() {
return "Car make: " + make + ", model: " + model + ", year: " + year;
}

public static void main(String[] args) {


Car myCar = new Car("Toyota", "Corolla", 2022);
System.out.println(myCar.toString());
}
}

Output:

Car make: Toyota, model: Corolla, year: 2022


Ways to Create Objects
1. Using new Keyword

This is the most common method for object creation.

Car car1 = new Car("Honda", "Civic", 2023);

2. Using Class.forName(String className)

This method is used for creating an object by specifying the class name in a string format.

Car car2 = (Car) Class.forName("Car").newInstance();

3. Using clone() Method

This method creates a copy of an existing object.


Car car3 = new Car("Ford", "Focus", 2021);
Car car4 = (Car) car3.clone();

4. Deserialization
Objects can also be created by reading from a serialized file.

FileInputStream file = new FileInputStream("car.ser");


ObjectInputStream in = new ObjectInputStream(file);
Car deserializedCar = (Car) in.readObject();
Creating Multiple Objects Using One Type
It's often practical to manage multiple objects using a single type reference. For example, managing different
types of vehicles using a common interface.

Example:

interface Vehicle {
void start();
}

class Bike implements Vehicle {


public void start() {
System.out.println("Bike started.");
}
}

class Truck implements Vehicle {


public void start() {
System.out.println("Truck started.");
}
}

public class Test {


public static void main(String[] args) {
Vehicle myVehicle;
myVehicle = new Bike();
myVehicle.start(); // Output: Bike started.
myVehicle = new Truck();
myVehicle.start(); // Output: Truck started.
}
}
Anonymous Objects in Java
Anonymous objects are instances that are created without assigning them to a reference variable. They are
typically used for immediate method calls and are discarded after use.

Example:

new Button().setOnAction(new EventHandler<ActionEvent>() {


@Override
public void handle(ActionEvent event) {
System.out.println("Button clicked!");
}
});
Difference Between Java Classes and Objects
• Class: A blueprint for creating objects. It defines the structure and behavior common to all objects of that
type.
• Example: Car class.
• Object: An instance of a class. Each object has its own state and can perform its own behaviors.
• Example: myCar object of type Car.
6. Methods

Methods
Methods, also known as functions, are the heart and soul of object-oriented programming in Java. They are
reusable blocks of code that perform specific tasks within a class. Imagine them as mini-machines that take inputs
(parameters), process them, and often deliver an output (return value) or perform an action.

Parts of a Method:
A method declaration typically consists of six components:

1. Access Modifier (Optional): Controls where the method can be called from. Common options include
public (accessible anywhere), private (accessible only within the class), and protected (accessible within
the class and subclasses).

2. Return Type (Mandatory): Specifies the data type of the value the method returns (e.g., int, double,
String, or void if it doesn't return anything).

3. Method Name (Mandatory): A descriptive name that reflects its functionality (use lowercase with
camelCase for multiple words).

4. Parameter List (Optional): A comma-separated list of variables (parameters) that the method accepts as
input, along with their data types. Empty parentheses () indicate no parameters.

5. Method Body (Optional): The code block enclosed in curly braces {} that contains the instructions the
method executes.

6. Throws Clause (Optional): Declares exceptions the method might throw, allowing for error handling.
Example:

public class Calculator {

// Method to add two numbers


public int add(int num1, int num2) {
int sum = num1 + num2;
return sum; // Return the calculated sum
}

// Method to greet someone


public void sayHello(String name) {
System.out.println("Hello, " + name + "!");
}
}

Types of Methods in Java


Methods in Java can be broadly categorized into two types:
1. Predefined Methods (Standard Library Methods)
• Definition: These methods are built-in functions that are part of the Java class libraries. They provide
essential functionalities for various tasks.
• Accessibility: You can use them directly in your code without defining them yourself.
• Examples:
o Math.sqrt(x): Calculates the square root of a number.
o System.out.println(message): Prints a message to the console.
o Character.isDigit(char): Checks if a character is a digit.
o Arrays.sort(array): Sorts an array of elements.
2. User-Defined Methods
• Definition: These methods are created by programmers to encapsulate specific logic or functionality
within their code.
• Customization: You can tailor them to meet your specific requirements.
• Structure: They follow the standard Java method syntax:
[access_modifier] return_type method_name(parameter_list) {
// Method body
}
• Example:
public class MyCalculator {
public int add(int a, int b) {
return a + b;
}
}

Ways to Create Methods in Java


Methods in Java can be classified into two main categories:
1. Instance Methods
• Definition: These methods are associated with specific objects and can access and modify the object's
data (fields).
• Calling: You need to create an object of the class and use the dot notation to call instance methods.
• Access to data: Instance methods can directly access and modify the fields of the object they are called
on.
Example:
public class Person {
private String name;
private int age;
public void introduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
}
// Creating an object and calling the instance method
Person person = new Person("Alice", 30);
person.introduce(); // Output: Hello, my name is Alice and I am 30 years old.
2. Class Methods (Static Methods)
• Definition: Class methods are not associated with specific objects and can be called directly using the class
name.
• Calling: You can call class methods without creating an object.
• Access to data: Class methods cannot directly access or modify the fields of individual objects.
Example:
public class MathUtils {
public static int add(int a, int b) {
return a + b;
}
}
// Calling the class method
int result = MathUtils.add(5, 3);
System.out.println(result); // Output: 8

Benefits of Using Methods:


• Code Reusability: Methods allow you to write code once and use it multiple times in your program, saving
time and effort.

• Improved Readability: By breaking complex logic into smaller, well-named methods, your code becomes
easier to understand and maintain.

• Modularization: Methods promote modularity by separating functionalities into manageable units,


making your code cleaner and more organized.

• Encapsulation: Methods help encapsulate data and logic within a class, promoting data protection and
access control.

Calling Methods:

Methods are the building blocks of Java programs, encapsulating specific tasks. How do you actually use them?
Here we will see method calling, the process of activating a method's functionality.
When a Method Returns:
A method gives back control to the calling code when:
• All statements in the method body execute: If the method doesn't contain a return statement, it
implicitly returns after completing all its instructions.
• A return statement is reached: The return statement allows a method to send a value back to the calling
code. The returned value can be of any data type, including primitives (e.g., int, double) or objects.
• An exception is thrown: Sometimes, a method might encounter an unexpected error. It can throw an
exception to signal the problem to the calling code, which can then handle it accordingly.
Examples:
1. Simple Addition:
public class Calculator {
public int add(int a, int b) {
int sum = a + b;
return sum; // Return the calculated sum
}
}

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator(); // Create a Calculator object
int result = calc.add(5, 3); // Call the add() method with arguments
System.out.println(result); // Output: 8
}
}
In this example, the add() method returns the calculated sum using the return statement.
2. Printing a Greeting:
public class Greeter {
public void sayHello(String name) {
System.out.println("Hello, " + name + "!");
}
}

public class Main {


public static void main(String[] args) {
Greeter greeter = new Greeter(); // Create a Greeter object
greeter.sayHello("Alice"); // Call the sayHello() method with an argument
}
}

Here, the sayHello() method doesn't explicitly return a value, but it prints a message to the console.
Remember: When calling a method, you provide the necessary arguments (input values) that match the
method's parameter list.

Do It Yourself

1. Write a method that takes two integers as parameters and returns their sum. Then, call this method from
the main method and print the result.
2. Create a method that takes a string as a parameter and returns the string in uppercase. Call this method
from the main method and display the result.
3. Define an overloaded method named multiply that can handle both integer and double parameters. Write
code to call these methods and print the results.

Quiz

1. What is the purpose of the return keyword in a method?


A) To declare a method
B) To define the method's return type
C) To exit a method and optionally return a value
D) To call another method

Answer: C) To exit a method and optionally return a value

2. Which of the following is the correct syntax for declaring a method that returns an integer value?

A) int methodName() { // method body }


B) methodName() int { // method body }
C) methodName() { int // method body }
D) int { methodName() // method body }

Answer: A) int methodName() { // method body }

3. What will happen if a method with a non-void return type does not include a return statement?

A) The code will compile and run with a default return value
B) The method will not compile
C) The method will return null by default
D) The code will throw a runtime exception

Answer: B) The method will not compile

4. Which keyword is used to define a method that does not return any value?

A) public
B) return
C) static
D) void

Answer: D) void

5. How do you specify the return type of a method?

A) By placing it before the method name


B) By placing it after the method name
C) By using the return keyword
D) By using the void keyword

Answer: A) By placing it before the method name

7. Assigning One Object to Another

Assigning One Object to Another


When assigning one object to another in Java, what actually happens is that the reference (or memory address)
of the object is copied, rather than the object itself. This means that both variables (the one being assigned and
the one receiving the assignment) will refer to the same object in memory. Here's an explanation with an
example:
Concept:
In Java, objects are reference types, which means that when you assign one object to another, you're copying the
reference (not the actual object). If you modify the object using either reference, both will reflect the changes
because they point to the same memory location.
Syntax:
ClassName obj1 = new ClassName();
ClassName obj2 = obj1;

• obj1 and obj2 are now references to the same object in memory.
Example:
class Car {
String model;
String color;

Car(String model, String color) {


this.model = model;
this.color = color;
}

void display() {
System.out.println("Model: " + model + ", Color: " + color);
}
}

public class Main {


public static void main(String[] args) {
Car car1 = new Car("Tesla", "Red");
Car car2 = car1; // Assigning car1 to car2

car2.color = "Blue"; // Changing color via car2

// Both car1 and car2 will reflect the same data


car1.display(); // Output: Model: Tesla, Color: Blue
car2.display(); // Output: Model: Tesla, Color: Blue
}
}
Explanation:
• In the example above, car1 and car2 point to the same Car object in memory.
• When the color is changed using car2, the change is reflected in car1 as well because they both reference
the same object.
Important Notes:
• This only applies to object references (not primitive types like int, float, etc.).
• If you need to create a new object with the same data, you'd have to explicitly copy the object or use a
constructor that clones the values from one object to another.

Do It Yourself
1. Write a Java program to define a class Book with attributes title, author, and price. Create an object of this
class, assign values to the attributes, and print them.
2. Write a Java program to create a class Rectangle with attributes length and width, and a method
calculateArea(). Create an object, set the values of the attributes, and print the area of the rectangle.

Quiz

1. How do you declare an object of a class in Java?


a) ClassName objectName;
b) ClassName objectName = new ClassName();
c) objectName = new ClassName();
d) new objectName = ClassName();

Answer: b) ClassName objectName = new ClassName();

2. What does the new keyword do in object creation?


a) It declares a class.
b) It initializes a class.
c) It creates an instance of a class.
d) It assigns a value to an attribute.

Answer: c) It creates an instance of a class.

3. In the statement Person p = new Person();, what is p?


a) A class
b) A method
c) An object
d) A constructor

Answer: c) An object

4. Which statement is true about object declaration in Java?


a) An object must be declared and initialized in separate statements.
b) Objects can only be declared if the class is defined.
c) The new keyword is optional when declaring an object.
d) Objects are automatically initialized without the new keyword.

Answer: b) Objects can only be declared if the class is defined.

5. What happens when you assign one object to another in Java?


a) A new object is created.
b) Both variables reference the same object.
c) Only the first object is updated.
d) The original object is destroyed.

Answer: b) Both variables reference the same object.


6. Which statement correctly assigns objectB to objectA?
a) objectA = objectB;
b) objectB = objectA;
c) objectA == objectB;
d) objectA.equals(objectB);

Answer: a) objectA = objectB;

7. What is the result of modifying an attribute of an object after assigning it to another object?
a) Only the original object is modified.
b) Only the assigned object is modified.
c) Both objects reflect the changes.
d) No change occurs to either object.

Answer: c) Both objects reflect the changes.

8. When you assign an object to another, what is being copied?


a) The actual object
b) The reference to the object
c) The class definition
d) The object's data only

Answer: b) The reference to the object.

References

Classes and objects - #21 Class And Object Theory in Java


Classes and objects - Introduction to Classes and Objects (Part 1)
Access modifier - public, private, and static in Java

Accessing private members of a class:

In Java, private members of a class can only be accessed within the same class. This means that fields, methods,
or constructors marked as private cannot be accessed directly from outside the class. However, you can provide
public getter and setter methods to access and modify these private members indirectly.

Example: Accessing Private Members using Getter and Setter Methods

class Employee {

// Private fields

private String name;


private double salary;

// Constructor to initialize fields

public Employee(String name, double salary) {

this.name = name;

this.salary = salary;

// Public getter method for name

public String getName() {

return name;

// Public setter method for name

public void setName(String name) {

this.name = name;

// Public getter method for salary

public double getSalary() {

return salary;

// Public setter method for salary

public void setSalary(double salary) {

this.salary = salary;

// Method to display employee details


public void displayDetails() {

System.out.println("Employee Name: " + name);

System.out.println("Employee Salary: $" + salary);

public class Main {

public static void main(String[] args) {

// Create an object of Employee class

Employee emp = new Employee("John Doe", 50000);

// Access and modify private members using getter and setter methods

emp.displayDetails(); // Before modification

emp.setName("Jane Smith"); // Modify the name using setter

emp.setSalary(60000); // Modify the salary using setter

// Access the updated values using getter methods

System.out.println("Updated Employee Name: " + emp.getName());

System.out.println("Updated Employee Salary: $" + emp.getSalary());

emp.displayDetails(); // After modification

Explanation:

• The fields name and salary are private, meaning they cannot be accessed directly outside the Employee
class.

• Getter methods (getName(), getSalary()) are provided to access the private fields.

• Setter methods (setName(), setSalary()) are used to modify the values of the private fields.
• In the main() method, we use the getter and setter methods to access and modify the private members.

Important Points:

• Private members enhance encapsulation, as they restrict direct access and modification of class fields
from outside.

• Getter and Setter methods act as a controlled way to interact with private fields.

Do It Yourself

Create a Person class with private fields for name, age, and address. Include getter and setter methods. Write a
driver class to test these methods.

Quiz

1. What is the purpose of getter and setter methods in Java?

A) To directly access private fields

B) To modify private fields

C) To provide controlled access to private fields

D) To perform arithmetic operations

Answer. C) To provide controlled access to private fields

2. What will happen if you try to access a private member directly from another class?

A) Compilation error

B) Runtime exception

C) The program will compile but give incorrect results

D) The member will be accessible


Answer. A) Compilation error

3. How do you typically provide access to a private field in a class?

A) By using protected access modifier

B) By using a public method

C) By using a static method

D) By using a private method

Answer. B) By using a public method

4. Which of the following is a correct way to set a private field in a class?

A) object.field = value;

B) object.setField(value);

C) object.getField(value);

D) object.privateField = value;

Answer. B) object.setField(value);

2. Constructors

Java Constructors:

In Java, constructors play a critical role in initializing objects when they are created. Constructors set up the initial
state of an object and are invoked automatically when the new keyword is used to create an object. They share
the class name and cannot have a return type. Understanding and using constructors efficiently can greatly
enhance your ability to manage object creation in complex applications.

What are Constructors in Java?


A constructor is a block of code in Java similar to a method, but its purpose is to initialize objects. When a
constructor is called, it allocates memory for the object and sets the initial values of its attributes. Every time an
object is created using the new keyword, at least one constructor is invoked.

Key Points:

• Same name as class: The constructor's name must match the class name.

• No return type: Constructors do not return any value, not even void.

• Called once: Constructors are invoked only when an object is created, unlike methods, which can be called
multiple times.

Example: Simple Constructor

class Animal {

String type;

// Constructor to initialize the type of animal

public Animal(String type) {

this.type = type;

public void display() {

System.out.println("Animal type: " + type);

public class Main {

public static void main(String[] args) {

Animal animal = new Animal("Dog");


animal.display();

Output:

Animal type: Dog

How Java Constructors Differ from Methods

Although constructors may look similar to methods, there are some key differences:

1. Name: Constructors must have the same name as the class, whereas methods can have any name.

2. Return Type: Constructors do not return any value, while methods may return a value or void.

3. Invocation: Constructors are called automatically when an object is created, while methods must be
called explicitly.

Need for Constructors

Consider the example of a class representing a Box. To create an object of this class, the attributes (like length,
width, and height) need to be initialized. Constructors allow you to set these values when the object is created.

Example:

class Box {

int length, width, height;

// Constructor to initialize dimensions

public Box(int l, int w, int h) {

length = l;
width = w;

height = h;

public void displayVolume() {

System.out.println("Volume: " + (length * width * height));

public class Main {

public static void main(String[] args) {

Box box = new Box(5, 3, 4);

box.displayVolume();

Output:

Volume: 60

Types of Constructors in Java

There are three main types of constructors in Java:

1. Default Constructor

2. Parameterized Constructor

3. Copy Constructor

1. Default Constructor

A default constructor is a constructor that takes no parameters. If a class doesn’t define any constructor, Java
automatically provides a default constructor.
Example:

class Student {

String name;

// Default constructor

public Student() {

name = "Unknown";

public void display() {

System.out.println("Name: " + name);

public class Main {

public static void main(String[] args) {

Student student = new Student();

student.display();

} }

Output:

Name: Unknown

Note: The default constructor initializes fields to default values (null, 0, etc.).

2. Parameterized Constructor

A parameterized constructor allows you to provide initial values for fields when an object is created.

Example:

class Car {
String brand;

int year;

// Parameterized constructor

public Car(String brand, int year) {

this.brand = brand;

this.year = year;

public void display() {

System.out.println("Brand: " + brand + ", Year: " + year);

public class Main {

public static void main(String[] args) {

Car car = new Car("Honda", 2022);

car.display();

}}

Output:

Brand: Honda, Year: 2022

3. Copy Constructor

A copy constructor creates a new object as a copy of an existing object. While Java doesn’t provide a built-in copy
constructor, you can define one yourself.

Example:

class Book {

String title;

int pages;
// Parameterized constructor

public Book(String title, int pages) {

this.title = title;

this.pages = pages;

// Copy constructor

public Book(Book another) {

this.title = another.title;

this.pages = another.pages;

public void display() {

System.out.println("Title: " + title + ", Pages: " + pages);

public class Main {

public static void main(String[] args) {

Book original = new Book("Java Programming", 500);

Book copy = new Book(original);

copy.display();

Output:Title: Java Programming, Pages: 500

There are many differences between constructors and methods. They are given below.
Do It Yourself

1. Implement a Book class with both default and parameterized constructors. Test object creation using both
constructors

Quiz

1. What is the primary purpose of a constructor in Java?

A) To initialize objects

B) To modify object fields

C) To perform arithmetic operations

D) To handle exceptions

Answer A) To initialize objects


2. What is a default constructor?

A) A constructor that throws an exception

B) A constructor with parameters

C) A constructor with no parameters

D) A constructor with a return type

Answer C) A constructor with no parameters

3. Which of the following statements about constructors is true?

A) Constructors can be inherited

B) A class can have multiple constructors with different parameter lists

C) Constructors can have a return type

D) Constructors can be private only

Answer B) A class can have multiple constructors with different parameter lists

4. What happens if you do not provide any constructor in a class?

A) The class will not compile

B) The class will be incomplete

C) The class will have an abstract constructor

D) The class will have a default constructor provided by the compiler

Answer D) The class will have a default constructor provided by the compiler

3. Constructor Overloading

Constructor Overloading

Constructor overloading is a feature in Java that allows a class to have more than one constructor, each with
different parameter lists. This is similar to method overloading, where methods in the same class can have the
same name but different parameters. Constructor overloading is used to provide multiple ways to initialize
objects of a class.

Key Points of Constructor Overloading:

1. Different Parameters: Overloaded constructors must differ in the number or type of their parameters.

2. Same Name: All constructors in a class have the same name as the class.

3. No Return Type: Constructors do not have a return type, not even void.

4. Purpose: Constructor overloading allows different ways to initialize an object based on different inputs or
scenarios.

Syntax for Constructor Overloading

Here’s how you can define multiple constructors in a class:

class Example {

// Constructor with no parameters

Example() {

System.out.println("No-argument constructor");

// Constructor with one parameter

Example(int a) {

System.out.println("Constructor with one integer parameter: " + a);

// Constructor with two parameters

Example(int a, String b) {

System.out.println("Constructor with integer and string parameters: " + a + ", " + b);

}
}

Example of Constructor Overloading

Let's look at a example to see how constructor overloading works:

class Book {

String title;

String author;

int year;

// Constructor with no parameters

Book() {

title = "Unknown";

author = "Unknown";

year = 0;

// Constructor with one parameter

Book(String title) {

this.title = title;

author = "Unknown";

year = 0; }

// Constructor with two parameters

Book(String title, String author) {

this.title = title;

this.author = author;

year = 0;

// Constructor with three parameters


Book(String title, String author, int year) {

this.title = title;

this.author = author;

this.year = year;

void display() {

System.out.println("Title: " + title);

System.out.println("Author: " + author);

System.out.println("Year: " + year);

public class ConstructorOverloadingDemo {

public static void main(String[] args) {

// Creating objects using different constructors

Book book1 = new Book();

Book book2 = new Book("1984");

Book book3 = new Book("To Kill a Mockingbird", "Harper Lee");

Book book4 = new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925);

// Displaying the details of each book

System.out.println("Book 1:");

book1.display();

System.out.println();

System.out.println("Book 2:");

book2.display();

System.out.println();
System.out.println("Book 3:");

book3.display();

System.out.println();

System.out.println("Book 4:");

book4.display();

Output:

Book 1:

Title: Unknown

Author: Unknown

Year: 0

Book 2:

Title: 1984

Author: Unknown

Year: 0

Book 3:

Title: To Kill a Mockingbird

Author: Harper Lee

Year: 0

Book 4:

Title: The Great Gatsby

Author: F. Scott Fitzgerald


Year: 1925

Benefits of Constructor Overloading

1. Flexibility: Provides different ways to initialize an object based on different inputs.

2. Code Readability: Makes the code cleaner and easier to understand by allowing different ways to
construct objects.

3. Enhanced Functionality: Supports various initialization scenarios, enhancing the functionality and
adaptability of the class.

Do It Yourself

1. Create a Circle class with overloaded constructors for radius and diameter. Write a program to test these
constructors.

Quiz

1. What is constructor overloading?

A) Using multiple constructors with the same parameters


B) Using multiple constructors with different parameters
C) Using a single constructor for different classes
D) Using constructors without parameters

Answer: B) Using multiple constructors with different parameters

2. How does Java distinguish between overloaded constructors?

A) By their return type


B) By their names
C) By the number and types of parameters
D) By their access modifiers

Answer: C) By the number and types of parameters

3. Which of the following is an example of constructor overloading?

A) Defining multiple methods with different names


B) Defining multiple methods with the same name and parameters
C) Defining multiple constructors with different parameter lists
D) Defining multiple constructors with the same parameter list

Answer: C) Defining multiple constructors with different parameter lists

4. What happens if a class has multiple overloaded constructors?

A) The class will compile with an error


B) The most recent constructor will be used
C) The appropriate constructor is called based on the arguments provided
D) The class will have no constructors

Answer: C) The appropriate constructor is called based on the arguments provided

4. Nested classes

Nested Classes

In Java, nested classes are classes defined within another class. They enable you to logically group classes that are
only used in one place, enhancing encapsulation and improving code readability and maintainability. The scope of
a nested class is limited to its enclosing class. Hence, a nested class does not exist independently of the outer
class.

Characteristics of Nested Classes:

• Access to Members: A nested class can access all members, including private members, of its enclosing
class. However, the enclosing class does not have access to the members of the nested class.

• Access Modifiers: Nested classes can be declared as private, public, protected, or package-private
(default).

Types of Nested Classes

1. Static Nested Classes

2. Non-static Nested Classes (Inner Classes)

• Member Inner Classes

• Local Inner Classes

• Anonymous Inner Classes

1. Static Nested Classes

A static nested class is a nested class defined with the static modifier. It behaves like a static member of the outer
class and does not have access to instance variables or methods of the outer class. Instead, it can only access the
outer class’s static members.

Characteristics:
• Independence: A static nested class can be instantiated without an instance of the outer class.

• Access: It can access the static members of the outer class but not instance members directly.

Example:

class OuterClass {

// Static member

static int outer_x = 10;

// Instance (non-static) member

int outer_y = 20;

// Private static member

private static int outer_private = 30;

// Static nested class

static class StaticNestedClass {

void display() {

// Accessing static members of the outer class

System.out.println("outer_x = " + outer_x);

System.out.println("outer_private = " + outer_private);

// Accessing non-static member requires an instance of the outer class

OuterClass outer = new OuterClass();

System.out.println("outer_y = " + outer.outer_y);

public class StaticNestedClassDemo {

public static void main(String[] args) {

// Creating an object of the static nested class


OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

nestedObject.display();

Output:

outer_x = 10

outer_private = 30

outer_y = 20

2. Non-static Nested Classes (Inner Classes)

Inner classes are non-static nested classes. They have access to all members (including private) of the outer class
and can be categorized as follows:

a. Member Inner Classes

A member inner class is defined within the body of the outer class but outside any method. It has access to all
instance members of the outer class.

Example:

class OuterClass {

// Instance (non-static) member

int outer_y = 20;

// Private member

private int outer_private = 30;

// Inner class

class InnerClass {

void display() {

// Accessing instance members of the outer class


System.out.println("outer_y = " + outer_y);

System.out.println("outer_private = " + outer_private);

public class InnerClassDemo {

public static void main(String[] args) {

// Creating an instance of the outer class

OuterClass outerObject = new OuterClass();

// Creating an instance of the inner class

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

innerObject.display();

Output:

outer_y = 20

outer_private = 30

b. Local Inner Classes

A local inner class is defined within a block, usually a method, and can only be instantiated and used within that
method. Local inner classes have access to final or effectively final local variables and parameters of the enclosing
method.

Example:

class OuterClass {

void outerMethod() {
final String localVar = "Local Variable";

class LocalInner {

void display() {

System.out.println("localVar = " + localVar);

LocalInner localInner = new LocalInner();

localInner.display();

public class LocalInnerClassDemo {

public static void main(String[] args) {

OuterClass outerObject = new OuterClass();

outerObject.outerMethod();

Output:

localVar = Local Variable

c. Anonymous Inner Classes

An anonymous inner class is a type of inner class with no name. It is used to create instances of classes or
interfaces with specific behaviors.

Example:

abstract class AbstractClass {

abstract void display();

}
public class AnonymousInnerClassDemo {

public static void main(String[] args) {

// Anonymous inner class

AbstractClass obj = new AbstractClass() {

void display() {

System.out.println("Anonymous inner class implementation.");

};

obj.display();

Output:

Anonymous inner class implementation.

Comparison Between Normal and Static Nested Classes

S.No. Normal/Regular Inner Class Static Nested Class

1. An inner class object requires an outer class object. A static nested class object can be created
without an outer class object.

2. Cannot be directly invoked from the command Can be directly invoked from the command
prompt as main() method is not allowed. prompt if a main() method is defined.

3. Can access both static and non-static members of the Can only access static members of the outer
outer class. class directly.
Do It Yourself

1. Write a Java program that defines an outer class Outer with a nested class Inner. The Inner class should
have a method that prints a message. Instantiate the Inner class from within the Outer class and call the
method.

Quiz

1. What is a static nested class in Java?

A) A nested class that can access non-static members of the outer class

B) A nested class that cannot access non-static members of the outer class

C) A nested class that is defined inside a method

D) A nested class that must be instantiated from the outer class

Answer B) A nested class that cannot access non-static members of the outer class

2. Which of the following is true about non-static nested classes (inner classes)?

A) They can access all members of the outer class, including private members

B) They cannot access any members of the outer class

C) They are always static

D) They are only used for static methods

Answer A) They can access all members of the outer class, including private members

3. How do you instantiate a non-static nested class?


A) Directly using the outer class

B) Using an instance of the outer class

C) Using a static reference

D) Using the new keyword directly

Answer B) Using an instance of the outer class

4. What is the main advantage of using nested classes?

A) To increase the visibility of the outer class

B) To create static methods in the outer class

C) To make the outer class public

D) To logically group classes that are only used in one place

Answer D) To logically group classes that are only used in one place

References

Accessing private members - Accessing/Modifying Private Data Members

Constructors - #43 Constructor in Java

Constructor overloading - OVERLOADING CONCEPT - JAVA PROGRAMMING

Nested Classes - Java Tutorial #34 - Nested and Inner Class in Java Programming

final keyword

The final keyword in Java is used to declare constants, prevent method overriding, and restrict class inheritance.
Here, we'll delve into how final is used with classes and methods, including syntax, real-time examples, and
practice programs.

Different places where final keyword is used:

1. final Variables:

a. When a variable is declared as final, its value cannot be changed once it has been initialized. This makes
final variables constants.

b. Final variables must be initialized either at the time of declaration or in the constructor of the class.
They cannot be assigned a new value after initialization.

c. If a final variable is a reference, the reference itself cannot be changed, but the object's internal state
can still be modified.

2. final Methods:

a. A method declared as final cannot be overridden by subclasses. This is useful for methods that are part
of a class’s public API and should not be modified by subclasses.

3. final Classes:

a. A class declared as final cannot be extended or subclassed. This is useful for preventing inheritance and
creating immutable classes.

1. final Keyword in Variables


When a variable is declared as final, its value cannot be changed once it has been initialized. This is useful for
defining constants or values that should remain constant throughout the program.

• Characteristics:

o A final variable must be initialized either at the time of declaration or in the constructor.

o For reference variables, the reference itself cannot be changed, but the object's internal state can
be modified.

Example:
public class ConstantExample {

public static void main(String[] args) {

final double PI = 3.14159; // Define a constant variable PI

System.out.println("Value of PI: " + PI);

Output:

Value of PI: 3.14159

2. final Keyword with Classes

Purpose

Prevent Inheritance: When a class is declared as final, it cannot be subclassed. This is useful for creating
immutable classes or ensuring certain classes are not extended.

Syntax

final class ClassName {

// class body

Real-time Examples
1. Immutable Class Example

In Java, the String class is a good example of a final class. By making String final, Java ensures that the string's
behavior remains consistent and cannot be modified.

Example:

// Immutable class example

final class ImmutablePerson {

private final String name;

private final int age;

public ImmutablePerson(String name, int age) {

this.name = name;

this.age = age;

public String getName() {

return name;

public int getAge() {

return age;

@Override

public String toString() {

return "ImmutablePerson{name='" + name + "', age=" + age + "}";

Usage:
public class Main {

public static void main(String[] args) {

ImmutablePerson person = new ImmutablePerson("John Doe", 30);

System.out.println(person); // Output: ImmutablePerson{name='John Doe', age=30}

2. Preventing Subclassing

Example:

// Base class

final class Base {

public void display() {

System.out.println("This is a final class.");

// Attempting to extend a final class will cause a compile-time error

// class Derived extends Base { }

public class Main {

public static void main(String[] args) {

Base base = new Base();

base.display(); // Output: This is a final class.

Practice Programs

1. Create a Final Class


Create a final class named Configuration with some configuration settings that cannot be subclassed.

Example Program:

// Final class

final class Configuration {

private final String setting;

public Configuration(String setting) {

this.setting = setting;

public String getSetting() {

return setting;

public class Main {

public static void main(String[] args) {

Configuration config = new Configuration("High Performance");

System.out.println("Setting: " + config.getSetting());

3. final Keyword with Methods

Purpose

• Prevent Method Overriding: When a method is declared as final, it cannot be overridden by subclasses.
This ensures that the method's behavior is consistent and cannot be changed by subclasses.

Syntax
class ClassName {

final void methodName() {

// method body

Real-time Examples

1. Method Finalization

Example:

class BaseClass {

final void display() {

System.out.println("This method cannot be overridden.");

class DerivedClass extends BaseClass {

// Attempting to override will cause a compile-time error

// void display() {

// System.out.println("Illegal!");

// }

public class Main {

public static void main(String[] args) {

BaseClass base = new BaseClass();

base.display(); // Output: This method cannot be overridden.

}
2. Security and Consistency

Using final methods can be crucial for maintaining consistent behavior in security-sensitive applications, where
altering the behavior of certain methods could introduce vulnerabilities.

Example:

class SecureClass {

final void authenticate() {

System.out.println("Authentication complete.");

class SecureSubclass extends SecureClass {

// Attempting to override will cause a compile-time error

// void authenticate() {

// System.out.println("Modified Authentication.");

// }

public class Main {

public static void main(String[] args) {

SecureClass secure = new SecureClass();

secure.authenticate(); // Output: Authentication complete.

Practice Programs

1. Implement Final Method


Create a base class Vehicle with a final method startEngine(). Extend it with a Car class and ensure that
startEngine() cannot be overridden.

Example Program:

class Vehicle {

final void startEngine() {

System.out.println("Engine started.");

class Car extends Vehicle {

// Attempting to override will cause a compile-time error

// void startEngine() {

// System.out.println("Car engine started.");

// }

public class Main {

public static void main(String[] args) {

Car car = new Car();

car.startEngine(); // Output: Engine started.

2. Prevent Method Overriding

Create a class Account with a final method calculateInterest(). Extend it with a SavingsAccount class and ensure
that calculateInterest() cannot be overridden.

Example Program:

class Account {
final void calculateInterest() {

System.out.println("Calculating interest...");

class SavingsAccount extends Account {

// Attempting to override will cause a compile-time error

// void calculateInterest() {

// System.out.println("Savings interest calculation.");

// }

public class Main {

public static void main(String[] args) {

SavingsAccount savings = new SavingsAccount();

savings.calculateInterest(); // Output: Calculating interest...

The final keyword in Java is a crucial tool for controlling the behavior of classes and methods. By using final, you
can:

• Create immutable classes: Ensuring that certain classes cannot be extended, thus preserving their
behavior and integrity.

• Prevent method overriding: Protecting critical methods from being altered in subclasses, ensuring
consistent behavior.

Understanding and utilizing the final keyword helps in designing robust, secure, and maintainable Java
applications.

Do It Yourself
1. Write a Java program that defines a class Circle with a final variable PI and a method
calculateCircumference(double radius) to compute the circumference of the circle. Show that the PI
variable cannot be reassigned.

2. Create a Java program with an Animal class that includes a final method makeSound(). Then, create a
subclass Dog and attempt to override the makeSound() method. Demonstrate that overriding a final
method results in a compilation error.

Quiz

1. What does the final keyword do when applied to a class?

A) Prevents the class from being extended

B) Prevents methods from being overridden

C) Makes the class abstract

D) Makes the class static

Answer A) Prevents the class from being extended

2. What is the effect of declaring a method as final?

A) The method becomes abstract

B) The method can be overridden but not modified

C) The method cannot be overridden in subclasses

D) The method can be static

Answer: D) The method cannot be overridden in subclasses

3. Can you extend a final class in Java?

A) Yes, with a different name


B) No, a final class cannot be extended

C) Yes, but only if it is not abstract

D) Yes, if the class has no methods

Answer: B) No, a final class cannot be extended

4. Can you override a final method in Java?

A) Yes, if it is in a different class

B) Yes, but it must be static

C) Yes, but only in the same class

D) No, a final method cannot be overridden

Answer: D) No, a final method cannot be overridden

2. Passing Arguments by Value and by Reference

Passing Arguments by Value and by Reference

Understanding the Difference

In Java, arguments are passed to methods in a specific way:

1. Pass by Value:

• In Java, all arguments are passed by value. This means that a copy of the argument's value is passed to the
method.

• For primitive data types (e.g., int, double, boolean), this means a copy of the actual value is used within
the method. Changes made to this copy do not affect the original value outside the method.
2. Pass by Reference:

• Java does not support pass-by-reference directly. Instead, it passes object references by value. This means
a copy of the reference (i.e., the address of the object) is passed to the method.

• As a result, while the method receives a reference to the original object, it does not receive the object
itself. Changes made to the object's properties within the method affect the original object.
Example:

public class ArgumentPassing {

public static void passByValue(int x) {

x = x + 10;

System.out.println("Inside the method: x = " + x);

public static void passByReference(Person person) {

person.name = "Neetu";

System.out.println("Inside the method: person.name = " + person.name);

public static void main(String[] args) {

int num = 5;

passByValue(num);

System.out.println("Outside the method: num = " + num); // Output: 5

Person person = new Person("Bob");

passByReference(person);
System.out.println("Outside the method: person.name = " + person.name); // Output: Neetu

class Person {

String name;

Person(String name) {

this.name = name;

In this example:

• passByValue takes an int as an argument. A copy of num is created and used within the method.
Modifying x inside the method does not affect the original num value.

• passByReference takes a Person object as an argument. A copy of the reference to person is passed to the
method. Modifying the object's properties (like person.name) inside the method affects the original
person object.

Key Points:

• Java always uses pass-by-value for method arguments. For primitives, it’s a copy of the actual value. For
objects, it’s a copy of the reference to the object.

• Modifications to primitive values inside methods do not affect the original values.

• Modifications to an object's properties inside a method affect the original object because the method
operates on the reference to the same object.

Additional Considerations:

• When dealing with objects, be cautious about modifying their state within methods, as it can lead to
unintended side effects.
• To avoid modifying the original object, you can create a copy of the object before passing it to the
method, either through cloning or other means.

By understanding how arguments are passed in Java, you can better manage how data is shared and modified
within your methods, leading to more predictable and reliable code.

Do It Yourself

1. Write a program that demonstrates passing a primitive data type and an object to a method. Show how
changes to these parameters within the method affect the original values. Document the findings and
provide explanations.

2. Create a Java class Box with a field size and a method updateSize(int newSize). Write a program that
passes a Box object to the updateSize method and modifies the size field. Show that the size field of the
original Box object is updated.

3. Write a Java program with a class Student that has a field grade. Create a method changeGrade(Student
student, int newGrade) which updates the grade field of the Student object. Pass a Student object and a
new grade to this method and observe how the Student object’s grade changes.

Quiz

1. What does Java use to pass primitive data types to methods?

A) By reference

B) By value

C) By object

D) By address

Answer: B) By value

2. When an object is passed to a method in Java, what is passed?


A) A copy of the object

B) The object's value

C) The object reference

D) The object's address

Answer: C) The object reference

3. What happens to the value of a primitive type argument if it is modified inside a method?

A) The original value changes

B) The original value remains the same

C) The method value becomes final

D) The value cannot be modified

Answer: B) The original value remains the same

4. If an object is passed to a method and its attributes are modified inside the method, what happens?

A) The original object's attributes are changed

B) The method creates a new object

C) The original object remains unchanged

D) The attributes become final

Answer: A) The original object's attributes are changed

3. ‘this’ keyword in Java

this Keyword in Java

In Java, this is a reference variable that refers to the current object instance. It is an essential tool for managing
and manipulating object properties and methods. Using this can help to improve code readability and manage
object-oriented programming more effectively.
Uses of this

1. Referring to Instance Variables:When instance variables are shadowed by method or constructor


parameters with the same name, this can be used to differentiate between them.

2. Invoking Current Class Constructor:this() can be used to call another constructor in the same class, which
helps to reduce code duplication.

3. Returning the Current Class Instance:this can be used to return the current object instance from a
method.

4. Passing Current Object as a Method Parameter:this can be passed as a parameter to other methods or
constructors.

5. Invoking Current Class Method:It can be used to call other methods from within the current method.

6. Using this as an Argument in Constructor Calls:

• this can be used as an argument when creating objects of other classes.

Examples

Imagine a scenario where you are building a class for managing employee records. Each employee has a name
and an ID number. When updating the employee details, you might want to distinguish between the instance
variables and the method parameters.

public class Employee {

private String name;

private int id;

// Constructor

public Employee(String name, int id) {

this.name = name; // Refers to the instance variable

this.id = id; // Refers to the instance variable

// Method to display employee details


public void displayDetails() {

System.out.println("Employee Name: " + this.name);

System.out.println("Employee ID: " + this.id);

public static void main(String[] args) {

Employee emp = new Employee("John Doe", 123);

emp.displayDetails();

Explanation: In this example, this.name and this.id refer to the instance variables of the Employee class,
distinguishing them from the parameters of the constructor.

2. Invoking Current Class Constructor

Consider a class Rectangle that has two constructors: one default and one parameterized.

public class Rectangle {

private int length;

private int width;

// Default constructor

public Rectangle() {

this(10, 5); // Calls the parameterized constructor

// Parameterized constructor

public Rectangle(int length, int width) {

this.length = length;

this.width = width;
}

public void display() {

System.out.println("Length: " + length);

System.out.println("Width: " + width);

public static void main(String[] args) {

Rectangle rect = new Rectangle();

rect.display();

Explanation: The default constructor calls the parameterized constructor using this(10, 5), which initializes the
rectangle with default dimensions.

3. Returning the Current Class Instance

In scenarios where you want to chain method calls, you can return the current object instance.

public class Builder {

private String material;

private int height;

public Builder setMaterial(String material) {

this.material = material;

return this; // Returns the current instance

public Builder setHeight(int height) {

this.height = height;

return this; // Returns the current instance


}

public void build() {

System.out.println("Material: " + material);

System.out.println("Height: " + height);

public static void main(String[] args) {

Builder builder = new Builder();

builder.setMaterial("Wood").setHeight(10).build();

Explanation: The setMaterial and setHeight methods return the current instance of Builder, allowing for method
chaining.

4. Passing Current Object as a Method Parameter

If you want to pass the current object to another method, you can use this.

public class Messenger {

private String message;

public Messenger(String message) {

this.message = message;

public void sendMessage(Messenger msg) {

System.out.println("Sending message: " + msg.message);

public void forwardMessage() {

sendMessage(this); // Passes the current instance


}

public static void main(String[] args) {

Messenger msg = new Messenger("Hello, World!");

msg.forwardMessage();

Explanation: The forwardMessage method uses this to pass the current instance to the sendMessage method.

5. Invoking Current Class Method

You can use this to call another method from within the current method.

public class Calculator {

private int value;

public Calculator(int value) {

this.value = value;

public void performOperation() {

this.printValue(); // Calls another method in the same class

System.out.println("Performing operation...");

private void printValue() {

System.out.println("Value: " + value); }

public static void main(String[] args) {

Calculator calc = new Calculator(100);

calc.performOperation();

}
Explanation: In the performOperation method, this.printValue() is used to call the printValue method within the
same class.

6. Using this as an Argument in Constructor Calls

When you need to pass the current object as an argument to another class, this is helpful.

public class Driver {

private Car car;

public Driver(Car car) {

this.car = car;

this.car.showDetails();

public static void main(String[] args) {

Car myCar = new Car("Toyota", "Corolla");

Driver driver = new Driver(myCar); // Passes the Car instance to the Driver

class Car {

private String make;

private String model;

public Car(String make, String model) {

this.make = make;

this.model = model;

public void showDetails() {

System.out.println("Make: " + make);

System.out.println("Model: " + model);


}

Explanation: The Driver constructor receives a Car object and calls its showDetails method.

Advantages of Using this

1. Clarity:It helps to differentiate between instance variables and local variables with the same name.

2. Code Reusability:It can invoke other constructors in the same class, reducing redundancy.

3. Method Chaining:By returning the current instance, it allows for method chaining.

4. Passing Objects:It can be used to pass the current instance to other methods or constructors.

Disadvantages of Using this

1. Overuse:Excessive use of this can make the code less readable and harder to understand.

2. Performance Overhead:Unnecessary use of this can add performance overhead.

3. Static Context Restrictions:this cannot be used in static methods or static contexts, as they do not belong
to any instance.

The this keyword is a versatile and useful feature in Java that facilitates working with object-oriented
programming. By understanding its applications and limitations, you can effectively manage and manipulate
object instances in your programs.

Do It Yourself

1. Create a class Person with name and age as instance variables. Use the this keyword to initialize these
variables in the constructor.

2. Create a class Car with model and color as instance variables. Implement a method displayCarDetails()
that uses the this keyword to access and print the car's properties.

3. Write a program that demonstrates the use of the this keyword to refer to the current object within a
method. Create a class with a method that prints the object's properties using this.

4. Consider the following code:

public class MyClass {

int x;

public MyClass(int x) {

this.x = x;

public void printX() {

System.out.println(x);

Explain the purpose of the this keyword in the constructor.

5. Identify the error in the following code:

public class Example {

int x = 10;

public void myMethod() {

int x = 20;

System.out.println(x); // Output: 20

System.out.println(this.x); // Output: 10

}
Hint: The this keyword is used to differentiate between instance variables and local variables with the same
name.

Quiz

1. What does the this keyword refer to in a Java class?

A) The class itself

B) The current instance of the class

C) The superclass

D) The method's return type

Answer: B) The current instance of the class

2. How can this be used in a constructor?

A) To call another constructor in the same class

B) To create a new instance of the class

C) To refer to the superclass constructor

D) To access static variables

Answer: A) To call another constructor in the same class

3. When can this be used to differentiate between instance variables and method parameters?

A) When the variable is final

B) When the method is static

C) When the instance variable and parameter have the same name

D) When the instance variable and parameter have different names

Answer: C) When the instance variable and parameter have the same name

4. Can this be used to access static methods?

A) Yes, this can access all methods


B) No, this is used only for instance methods

C) Yes, but only if they are non-static

D) No, this cannot access static methods

Answer: D) No, this cannot access static methods

References

final keyword - #57 Final keyword in java

Passing arguments by Value - Passing Arguments by Value in Java

Passing arguments by Reference - Passing Arguments by Reference in Java

this keyword - #42 This keyword in Java


2.Introduction & Defining Methods

Introduction to Methods
Methods in Java are blocks of code designed to perform specific tasks, and they help in organizing and reusing
code efficiently. A method is invoked by calling it within other methods or from different parts of the program.
Methods promote modularity, allowing you to break down complex programs into simpler, manageable
components. They can accept input through parameters, perform operations, and return a result.

Java has two types of methods:


1. predefined methods (like System.out.println())
2. user-defined methods.
Defining Methods
To define a method in Java, you specify its name, return type, parameters (if any), and the code that will be
executed. The syntax for defining a method is:

returnType methodName(parameters) {
// method body
}

Example:
public int add(int a, int b) {
return a + b;
}

In this example, add is a method that takes two integer parameters and returns their sum. The method body
contains the logic that defines what the method does. Methods may return a value or void if they do not return
anything.

2. Method Overloading

Overloaded Methods:
Introduction to Method Overloading

Method overloading is a feature in Java that allows a class to have more than one method with the same name,
as long as their parameter lists (the number, types, or order of parameters) differ. This allows the same method
name to perform different tasks based on how it is called.

Why Use Method Overloading?

Method overloading improves code readability and reusability. It allows methods with the same purpose but
different types or numbers of inputs to coexist. For example, a method that calculates the area of shapes might
take different parameters for circles, rectangles, or triangles.
Syntax of Method Overloading
class ClassName {
// Method 1: Accepting one integer argument
public void methodName(int a) {
// Method body
}

// Method 2: Accepting two integer arguments


public void methodName(int a, int b) {
// Method body
}
// Method 3: Accepting one double argument
public void methodName(double a) {
// Method body
}
}

In the above example, the method methodName is overloaded with different parameter types (int and double)
and different numbers of arguments (one or two).
Rules for Method Overloading
1. Different Parameter Lists: Methods must differ in the number of parameters, types of parameters, or
both.
2. Return Type Does Not Matter: The return type alone does not distinguish overloaded methods. Simply
changing the return type will not work.
3. Same Method Name: All methods must have the same name.

Real-Time Example: Banking Application


Consider a banking application where you need to calculate interest based on different types of accounts. One
method might calculate interest based on a savings account, another for a fixed deposit account, and another
for a recurring deposit account.

class BankAccount {

// Method 1: Calculates interest for savings account


public double calculateInterest(double principal, double rate) {
return (principal * rate) / 100;
}

// Method 2: Calculates interest for fixed deposit with tenure


public double calculateInterest(double principal, double rate, int years) {
return (principal * rate * years) / 100;
}

// Method 3: Calculates interest for recurring deposit with monthly installments


public double calculateInterest(double principal, double rate, int years, double monthlyInstallment) {
return ((principal + (monthlyInstallment * years * 12)) * rate * years) / 100;
}
}

public class Main {


public static void main(String[] args) {
BankAccount account = new BankAccount();

// Savings account interest


System.out.println("Savings Account Interest: " + account.calculateInterest(10000, 5.5));

// Fixed deposit interest for 5 years


System.out.println("Fixed Deposit Interest: " + account.calculateInterest(10000, 6.5, 5));

// Recurring deposit interest


System.out.println("Recurring Deposit Interest: " + account.calculateInterest(10000, 6.0, 3, 2000));
}
}

Output:

Savings Account Interest: 550.0


Fixed Deposit Interest: 3250.0
Recurring Deposit Interest: 7560.0

Real-Time Example: Online Shopping Platform


An e-commerce application might have a method to calculate the total price of items in the cart. However, the
price calculation could depend on whether the user applies a discount or buys items in bulk.

class ShoppingCart {

// Method 1: Calculate price without discount


public double calculateTotalPrice(double price, int quantity) {
return price * quantity;
}
// Method 2: Calculate price with discount
public double calculateTotalPrice(double price, int quantity, double discount) {
return (price * quantity) - discount;
}

// Method 3: Calculate price with bulk discount


public double calculateTotalPrice(double price, int quantity, double discount, boolean isBulkPurchase) {
if (isBulkPurchase) {
return (price * quantity * 0.9) - discount; // 10% bulk discount
}
return (price * quantity) - discount;
}
}

public class Main {


public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();

// No discount
System.out.println("Total Price: " + cart.calculateTotalPrice(100, 5));

// With discount
System.out.println("Total Price with Discount: " + cart.calculateTotalPrice(100, 5, 50));

// Bulk purchase with discount


System.out.println("Bulk Purchase Price: " + cart.calculateTotalPrice(100, 20, 100, true));
}
}

Output:

Total Price: 500.0


Total Price with Discount: 450.0
Bulk Purchase Price: 1700.0
Advantages of Method Overloading:
1. Code Readability: Using the same method name for related functionality improves clarity.
2. Flexibility: Allows different implementations of a method for different parameter types.
3. Reusability: Code can be reused efficiently by using overloaded methods.

Method overloading is a powerful feature in Java that allows developers to define multiple methods with the
same name but different parameter lists. It helps in organizing methods that perform similar functions but
require different inputs, improving code maintainability and flexibility.

Do It Yourself

1. Write a Java program that demonstrates method overloading by creating a class with three add methods
that accept different types of parameters (e.g., integers, doubles, and strings) and return their sum or
concatenation.

2. Create a Java class with two overloaded methods named display—one that takes an integer
parameter and prints it, and another that takes a string parameter and prints it. Write a main method to test
both display methods.

3. Implement a Java class with a method calculateArea that is overloaded to handle different shapes:
one method calculates the area of a rectangle, and another calculates the area of a circle. The methods should
accept parameters necessary for the area calculation.

4. Write a Java program with a class containing two overloaded methods named multiply. One
method should take two integer parameters, and the other should take two double parameters. Both methods
should return the product of the numbers.

5. Create a Java class with a method print that is overloaded to handle different data types: one
method should print an integer, another should print a double, and a third should print a string. Write a main
method to test each version of the print method.
Quiz

1. What is the main requirement for method overloading in Java?

A) Methods must have different return types


B) Methods must have different names
C) Methods must have different parameter lists
D) Methods must be declared in the same class

Answer: C) Methods must have different parameter lists

2. Which of the following statements about method overloading is true?

A) Method overloading is determined by the return type of the method.


B) Method overloading allows methods with the same name but different parameter lists.
C) Method overloading requires methods to have different names and parameter lists.
D) Method overloading can only be done in different classes.

Answer: B) Method overloading allows methods with the same name but different parameter lists.

3. In which of the following cases is method overloading NOT possible?

A) Two methods with the same name and different number of parameters
B) Two methods with the same name and different parameter types
C) Two methods with the same name and same parameter types but different return types
D) Two methods with the same name and different order of parameters

Answer: C) Two methods with the same name and same parameter types but different return types

4. Consider the following code snippet. What will be the output of the main method?
class Test {
void show(int a) {
System.out.println("Integer: " + a);
}
void show(double a) {
System.out.println("Double: " + a);
}
void show(String a) {
System.out.println("String: " + a);
}
public static void main(String[] args) {
Test obj = new Test();
obj.show(10);
obj.show(10.5);
obj.show("Java");
}
}

A) Integer: 10, Double: 10.5, String: Java


B) Integer: 10, Integer: 10.5, String: Java
C) Integer: 10, String: 10.5, String: Java
D) Compilation error

Answer: A) Integer: 10, Double: 10.5, String: Java

5. What will happen if you try to overload a method based solely on its return type in Java?

A) It will compile successfully.


B) It will result in a compilation error.
C) It will create a new method with a different name.
D) It will overwrite the existing method.

Answer: B) It will result in a compilation error.


6. Which of the following methods are overloaded in the provided class?

class OverloadExample {
void process(int a) { }
void process(double a) { }
void process(int a, int b) { }
void process(double a, double b) { }
}

A) process(int a) and process(double a)


B) process(int a) and process(int a, int b)
C) process(int a) and process(double a, double b)
D) All methods are considered overloaded.

Answer: D) All methods are considered overloaded.

3. Objects as Parameters

Class Objects as Parameters in Methods


In Java, methods can accept class objects as parameters, just like they accept primitive data types (e.g., int,
double) or reference types (e.g., arrays, strings). Passing objects as parameters allows methods to interact with
and modify the attributes of the object. This concept is powerful as it enables complex interactions between
classes and objects, contributing to Java's object-oriented design.
Key Concepts:
1. Class Object: A class object is an instance of a class that contains data (fields) and behavior (methods).
2. Method Parameter: In Java, a method can accept an object as a parameter. The method can then
manipulate the object's fields and call its methods.
Syntax:
The syntax for passing class objects as parameters to a method is the same as passing any other data type:

return_type methodName(ClassName objectName) {


// Method body
}
Here:

• return_type is the type of value the method will return.


• methodName is the name of the method.
• ClassName is the name of the class whose object is being passed as a parameter.
• objectName is the name of the parameter object used inside the method.

Example:
class Employee {
// Fields
String name;
int age;

// Constructor
Employee(String name, int age) {
this.name = name;
this.age = age;
}

// Method to display Employee details


void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
}
}

class Company {
// Method to modify the employee's age
void promoteEmployee(Employee emp, int newAge) {
emp.age = newAge; // Modifying the age of the employee object
System.out.println("Employee " + emp.name + " has been promoted.");
emp.displayInfo(); // Display updated info
}
}
public class Main {
public static void main(String[] args) {
// Creating an Employee object
Employee emp1 = new Employee("John Doe", 30);

// Creating a Company object


Company comp = new Company();

// Passing Employee object as a parameter to promoteEmployee method


comp.promoteEmployee(emp1, 35); // Promoting and updating the age
}
}

Output:

Employee John Doe has been promoted.


Name: John Doe, Age: 35

Explanation:
• In the above example, the Employee class has two fields: name and age. The Company class contains a
method promoteEmployee that accepts an Employee object as a parameter and modifies its age
attribute.
• The method promoteEmployee takes two parameters: an Employee object and an integer for the new
age. Inside this method, the age of the employee object is modified, and the updated details are
displayed.
• This is an example of passing an object by reference, meaning that the method operates on the actual
object rather than a copy.

Real-time Scenario Example:


Let's say you're building a Library Management System, and you want to create a method that accepts a Book
object as a parameter and updates the availability of the book when a user borrows it.

class Book {
// Fields
String title;
boolean isAvailable;

// Constructor
Book(String title) {
this.title = title;
this.isAvailable = true; // Book is initially available
}

// Method to display book info


void displayStatus() {
String status = isAvailable ? "Available" : "Not Available";
System.out.println("Book: " + title + ", Status: " + status);
}
}

class Library {
// Method to update the availability of the book when borrowed
void borrowBook(Book book) {
if (book.isAvailable) {
book.isAvailable = false;
System.out.println("You have borrowed the book: " + book.title);
} else {
System.out.println("Sorry, the book " + book.title + " is currently unavailable.");
}
}
}

public class Main {


public static void main(String[] args) {
// Creating a Book object
Book book1 = new Book("Java Programming");

// Creating a Library object


Library library = new Library();
// Display book status
book1.displayStatus();

// Borrow the book


library.borrowBook(book1);

// Display book status after borrowing


book1.displayStatus();
}
}

Output:

Book: Java Programming, Status: Available


You have borrowed the book: Java Programming
Book: Java Programming, Status: Not Available

Explanation:
• The Book class represents a book with a title and availability status (isAvailable). The Library class
contains the borrowBook method, which accepts a Book object as a parameter and modifies its
isAvailable field.
• In the Main class, a Book object is created and passed to the borrowBook method in the Library class.
After borrowing the book, its availability is updated, demonstrating how the method operates on the
actual object.
Advantages of Passing Objects as Parameters:
1. Code Reusability: You can pass the same object to multiple methods, avoiding redundancy and enabling
reuse of the object’s data.
2. Modify Object Attributes: When an object is passed to a method, you can modify its attributes, and
those changes persist outside the method because objects are passed by reference.
3. Encapsulation: You can maintain data encapsulation by interacting with objects through methods and
constructors, reducing direct access to class fields.
4. Simplifies Complex Systems: Passing objects as parameters is essential for creating complex, real-world
systems where multiple objects need to interact with one another.
Disadvantages:
1. Unintended Modifications: Since objects are passed by reference, modifying the object inside the
method directly affects the object, which can lead to unintended side effects if not handled carefully.
2. Higher Memory Usage: When dealing with large objects or numerous objects, passing them around
methods can consume more memory compared to passing primitive data types.

Key Points to Remember:


• When you pass an object as a parameter, the method receives a reference to the object, not a copy.
• Any changes made to the object inside the method affect the original object outside the method.
• You can use objects as method parameters to perform operations on the object’s fields or to pass
information between different parts of your program.

Passing class objects as parameters in methods is a common and useful practice in Java programming. It allows
methods to manipulate objects, update their state, and pass them around in a controlled manner. This feature
is fundamental to building scalable, object-oriented applications that can model real-world entities and
behaviors efficiently.

Do It Yourself

1. Create a class Flight with fields for flightNumber and departureTime. Write a method delayFlight(Flight
f, int delayInMinutes) that modifies the departureTime by adding the delay. In the main method, create
a Flight object and use the delayFlight method to adjust its departure time.
2. Design a class Movie with fields for title and rating. Create a method compareRating(Movie m1, Movie
m2) that compares the ratings of two Movie objects and prints the title of the movie with the higher
rating. In the main method, create two Movie objects and use the compareRating method to find the
better-rated movie.
3. Create a class InventoryItem with fields for itemName and quantity. Write a method
restockItem(InventoryItem item, int additionalQuantity) that adds more quantity to the existing item.
In the main method, create an InventoryItem object and use the restockItem method to increase the
quantity.

Quiz

1. What is the purpose of passing an object as a parameter to a method in Java?

A) To allow the method to modify the object's state


B) To prevent the method from modifying the object's state
C) To copy the object into a new instance
D) To create a new object inside the method

Answer: A) To allow the method to modify the object's state

2. Which of the following is true about passing objects to methods in Java?

A) Java passes objects by value, meaning a copy of the object is made.


B) Java passes objects by reference, allowing the method to modify the original object.
C) Java passes objects by reference, creating a new object for the method.
D) Java passes objects by value, meaning only the reference to the object is copied.

Answer: D) Java passes objects by value, meaning only the reference to the object is copied.

3. Consider the following code snippet. What will be the output of the main method?

class Test {
int value;
void updateValue(Test t) {
t.value = 10;
}
public static void main(String[] args) {
Test obj = new Test();
obj.value = 5;
obj.updateValue(obj);
System.out.println(obj.value);
}
}

A) 5
B) 10
C) Compilation error
D) Runtime error

Answer: B) 10

4. What happens if you pass an object to a method and modify its fields within the method?

A) The changes are reflected in the original object.


B) The changes are not reflected in the original object.
C) A new object is created inside the method.
D) The method will cause a compile-time error.

Answer: A) The changes are reflected in the original object.

5. How can you ensure that an object passed to a method does not get modified?

A) Use the final keyword with the method parameter


B) Make a copy of the object inside the method
C) Use a return type with the method
D) Declare the method as static

Answer: B) Make a copy of the object inside the method

6. Which of the following is a valid way to pass an object as a parameter to a method in Java?

A) void method(SomeClass obj) where SomeClass is the class of the object


B) void method(SomeClass obj, SomeClass obj) where both parameters are of the same class
C) void method(SomeClass obj, int value) where SomeClass and int are different types
D) All of the above

Answer: D) All of the above

4. Access Controls
Access Control
Access control in Java governs how classes, methods, and fields can be accessed from other parts of a program.
This is crucial for encapsulating the implementation details of a class and protecting its internal state. Java
provides mechanisms to control access through access modifiers and the structure of packages and classes..
Access Control Mechanisms
1. Access Modifiers: Access modifiers define the visibility of classes, methods, and fields. They help control
access from outside the class or package.
Types of Access Modifiers in Java
Java provides four types of access modifiers:

1. Default (Package-Private)
2. Private
3. Protected
4. Public
1. Default Access Modifier
When no access modifier is explicitly specified, the default access modifier is applied. This means that the class,
method, or variable is accessible only within the same package. It’s like sharing something within a specific
group of people.

Example:

Imagine you are running a community library. You have a list of books (LibraryBooks) that is only available to
the staff of that specific library. People from other libraries (packages) can't access this list.

// Package: library
package library;

class LibraryBooks {
void displayBooks() {
System.out.println("List of books available in the library.");
}
}
// Package: otherLibrary
package otherLibrary;

import library.LibraryBooks;

public class AccessBooks {


public static void main(String[] args) {
LibraryBooks books = new LibraryBooks(); // Compile-time error
books.displayBooks(); // Error: Cannot access due to default access modifier
}
}
2. Private Access Modifier
The private access modifier is the most restrictive. Members declared as private are accessible only within the
class they are defined in. Think of it as your personal diary; only you can read and write in it.

Example:

Consider a class that handles the financial records of a customer in a bank. The account balance should be a
private member because only specific operations (like depositing or withdrawing) should modify it.

package banking;

class BankAccount {
private double accountBalance;

public BankAccount(double initialBalance) {


this.accountBalance = initialBalance;
}

private void calculateInterest() {


accountBalance += accountBalance * 0.05;
}

public void deposit(double amount) {


accountBalance += amount;
}

public void withdraw(double amount) {


if (accountBalance >= amount) {
accountBalance -= amount;
} else {
System.out.println("Insufficient balance.");
}
}
}

In this example, accountBalance and calculateInterest() are private and can only be accessed within the
BankAccount class.
3. Protected Access Modifier
The protected access modifier allows access within the same package and by subclasses in different packages.
It’s like a family secret; only your family members (subclasses) and people within your household (package)
know about it.

Example:

Consider a scenario where you have a vehicle manufacturing company. The company has a class for Vehicle
that has a protected method engineDetails(). Only specific models (subclasses) can access this method.

package vehicleCompany;

public class Vehicle {


protected void engineDetails() {
System.out.println("Engine details: 2000cc, V6");
}
}

package vehicleModels;

import vehicleCompany.Vehicle;
public class Car extends Vehicle {
public void showDetails() {
engineDetails(); // Accessible due to protected access
}
}
4. Public Access Modifier
The public access modifier has the widest scope. Public members are accessible from anywhere in the
application. It’s like a public park; everyone can enter and use it.

Example:

Consider a class that holds public information, such as a company's contact details. This information should be
available to everyone, both within and outside the company.

package companyInfo;

public class Company {


public String name = "Tech Innovators";
public String contactNumber = "+1-800-555-1234";

public void displayContactDetails() {


System.out.println("Contact us at: " + contactNumber);
}
}

package clientApp;

import companyInfo.Company;

public class Client {


public static void main(String[] args) {
Company company = new Company();
System.out.println("Company Name: " + company.name);
company.displayContactDetails(); // Accessible everywhere
}
}

Key Points to Remember

• Default (Package-Private): Accessible only within the same package. No keyword is needed.
• Private: Accessible only within the same class.
• Protected: Accessible within the same package and by subclasses in different packages.
• Public: Accessible from anywhere in the program.

Best Practices
• Use private for variables that should not be accessed or modified directly from outside the class.
• Use protected when you want to allow access to subclasses but still keep control over the data.
• Use public only when it is necessary to expose members to all parts of your application.

2. Access Control in Packages:


• Package-Level Access: Classes and members with default access are accessible only within the same
package. This is useful for grouping related classes and controlling their visibility.
• Usage: Helps in designing modular and cohesive packages that encapsulate functionality.
3. Access Control with Inheritance:
• Protected Members: Subclasses can access protected members of their superclass. This allows for
extending and modifying the behavior of parent classes.
• Usage: Facilitates inheritance while maintaining a level of access control.
4. Access Control with Encapsulation:
• Encapsulation: The practice of hiding the internal state of an object and requiring all interactions to be
performed through methods. Encapsulation is enforced using private fields and public getter and setter
methods.
• Usage: Protects the integrity of an object's state and ensures that it can only be modified in controlled
ways.

Do It Yourself

1. Create a class with a private method that performs a calculation. Add a public method that calls this
private method internally. In the main method, create an object of the class and attempt to call both
the public and private methods. Observe the results.

2. Design a base class in which a method has protected access. Create a subclass that extends the
base class and attempts to access the protected method. In the main method, create an object of the subclass
and call the protected method.

3. Write a class in which a method has default (package-private) access. Then, create another class
in the same package and attempt to call the method from the second class. In the main method, create an
object of the second class and invoke the method.

4. Implement a class with three methods, each having different access control (private, protected,
public). In a subclass, attempt to access the protected method and override it. From the main method, try to
access all three methods as allowed by their access control levels.

Quiz

1. What will happen if you try to access a private method outside the class in which it is defined?
A) It will compile successfully but throw a runtime exception.
B) It will not compile and show a compilation error.
C) The private method will be accessible from any class in the same package.
D) The private method will be accessible only from subclasses.
Answer: B) It will not compile and show a compilation error.
2. Consider the following code snippet:
class Animal {
private void makeSound() {
System.out.println("Animal Sound");
}
}

class Dog extends Animal {


public void bark() {
makeSound();
}
}

public class Main {


public static void main(String[] args) {
Dog d = new Dog();
d.bark();
}
}

What will happen when the code is executed?

A) It will print "Animal Sound".


B) It will result in a compilation error due to trying to access a private method.
C) It will compile but throw a runtime exception.
D) It will print "Dog Sound".
Answer: B) It will result in a compilation error due to trying to access a private method.

3. Which of the following access modifiers allows a method to be accessible from within the same package
but not from outside the package?
A) public
B) private
C) protected
D) default (no modifier)
Answer: D) default (no modifier)
4. What is the output of the following code?
class Library {
protected void issueBook() {
System.out.println("Book issued.");
}
}

class SchoolLibrary extends Library {


public static void main(String[] args) {
SchoolLibrary lib = new SchoolLibrary();
lib.issueBook();
}
}

A) The code will not compile because issueBook() is protected.


B) The code will print "Book issued.".
C) The code will compile but throw an exception at runtime.
D) The code will not compile because issueBook() should be private.
Answer: B) The code will print "Book issued."

5. Consider the following code snippet:


class Person {
void displayInfo() {
System.out.println("Person Info");
}
}

public class Main {


public static void main(String[] args) {
Person p = new Person();
p.displayInfo();
}
}
If displayInfo() has no access modifier, where will this method be accessible?
A) Only within the Person class.
B) Within the same class and subclasses outside the package.
C) Within the same package only.
D) From any class in any package.
Answer: C) Within the same package only.

6. What will be the result of trying to access a protected method from a class in a different package that does
not extend the class containing the protected method?
A) The method will be accessible.
B) The code will not compile due to access control.
C) The method will throw an exception at runtime.
D) The protected method will be accessible only if it is called using the class name.
Answer: B) The code will not compile due to access control.

References

Methods in Java - Methods in Java, #24 Methods in Java Methods in Java


Method Overloading - #25 Method Overloading in Java
Objects as Parameters - 7.8 Object Passing in Java
Recursive Methods in Java
Definition:

In Java, recursion is a process in which a method calls itself directly or indirectly. The method that performs this
self-call is known as a recursive method. Recursive algorithms are powerful tools for solving problems that can
be divided into similar sub-problems. Examples of problems solved using recursion include the Towers of Hanoi,
tree traversals (Inorder, Preorder, Postorder), and Depth-First Search (DFS) of graphs.

Base Condition in Recursion:

In a recursive program, the base case provides the solution for the simplest instance of the problem and serves
as a stopping point for the recursion. The solution to more complex instances of the problem is expressed in
terms of smaller, simpler sub-problems.

Example of Factorial Calculation:

The factorial of a number ( n ) (denoted as ( n! )) is the product of all positive integers less than or equal to ( n
). The factorial of ( n ) can be computed recursively by defining the factorial of ( n ) in terms of the factorial of (
n-1 ).

int fact(int n) {
if (n <= 1) // base case
return 1;
else
return n * fact(n - 1); // recursive case
}

In this example, the base case is defined as ( n \leq 1 ), returning 1. For larger values of ( n ), the method
recursively calls itself with ( n-1 ) until the base case is reached.

Working of Recursion:

The essence of recursion is to solve a problem by breaking it down into smaller instances of the same problem
and combining the results. For instance, to compute the factorial of ( n ), if you know the factorial of ( n-1 ), you
can compute ( n! ) as ( n \times (n-1)! ). The base case for the factorial problem is ( n = 0 ), where the factorial
is defined as 1.

Java Recursion Programs:

1. Factorial Using Recursion

The factorial of a number ( N ) is calculated as the product of all positive integers from 1 to ( N ). Below is a Java
implementation of the factorial calculation using recursion:

// Java Program to implement Factorial using recursion


class GFG {

// Recursive method to calculate factorial


int fact(int n) {
int result;

if (n == 1) // Base case
return 1;
result = fact(n - 1) * n; // Recursive case
return result;
}
}

// Driver Class
class Recursion {
// Main function
public static void main(String[] args) {
GFG f = new GFG();

System.out.println("Factorial of 3 is " + f.fact(3));


System.out.println("Factorial of 4 is " + f.fact(4));
System.out.println("Factorial of 5 is " + f.fact(5));
}
}

Output:

Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120

2. Fibonacci Series

Fibonacci Numbers are the integer sequence where Fib(N) = Fib(N-2) + Fib(N-1). Below is an example to find
3,4,5.
• Fib(3) = Fib(2) + Fib(1) = Fib(1) + 0 + 1 = 1+1 = 2
• Fib(4) = Fib(3) + Fib(2) = 2+1 = 3
• Fib(5) = Fib(4) + Fib(3) = 3 + 2 = 5
// Java Program to implement Fibonacci Series
import java.io.*;

class GFG {

// Function to return Fibonacci value


static int Fib(int N) {
if (N == 0 || N == 1) // Base case
return N;
return Fib(N - 1) + Fib(N - 2); // Recursive case
}

// Main function
public static void main(String[] args) {
System.out.println("Fibonacci of " + 3 + " is " + Fib(3));
System.out.println("Fibonacci of " + 4 + " is " + Fib(4));
System.out.println("Fibonacci of " + 5 + " is " + Fib(5));
}
}

Output:

Fibonacci of 3 is 2
Fibonacci of 4 is 3
Fibonacci of 5 is 5

Stack Overflow Error:

If the base case is not defined properly, the recursion may continue indefinitely, causing a stack overflow error.
For example:

int fact(int n) {
// Incorrect base case (it may cause stack overflow).
if (n == 100)
return 1;
else
return n * fact(n - 1);
}

If fact(10) is called, it will call fact(9), fact(8), and so on, but will never reach 100. This will eventually lead to a
stack overflow error as the memory is exhausted.

Memory Allocation in Recursion:

When a function is called, memory is allocated on the stack for that function's local variables and state. For
recursive calls, each function call creates a new stack frame. Each call has its own set of local variables. Once
the base case is reached, the function returns its value, and the stack frames are de-allocated, allowing the
previous calls to complete.

Example of Recursion:

// A Java program to demonstrate working of recursion


class GFG {
static void printFun(int test) {
if (test < 1)
return;
else {
System.out.printf("%d ", test);
// Recursive call
printFun(test - 1);
System.out.printf("%d ", test);
return;
}
}

public static void main(String[] args) {


int test = 3;
printFun(test);
}
}
Output:

321123

Explanation:

When printFun(3) is called, it prints 3, then calls printFun(2), which prints 2, and so forth. After reaching the
base case, the function starts returning, printing the numbers in reverse order as it returns to the previous calls.

Advantages of Recursive Programming:

• Provides a clean and simple way to write code for problems that naturally fit a recursive approach.
• Particularly useful for problems like tree traversals and the Tower of Hanoi, where the recursive
approach mirrors the problem structure.

Disadvantages of Recursive Programming:

• Higher space requirements due to maintaining multiple stack frames.


• Increased time complexity due to the overhead of function calls.
• Recursive programs may be less efficient than iterative solutions for certain problems.

Note: Both recursive and iterative solutions have the same problem-solving capabilities. Any problem that can
be solved recursively can also be solved iteratively, and vice versa.

Do It Yourself

1. Write a recursive method in Java that calculates the sum of all natural numbers up to nnn. For example,
if n=5n = 5n=5, the method should return 1+2+3+4+51 + 2 + 3 + 4 + 51+2+3+4+5. Call this method from
the main method and print the result for n=5n = 5n=5.
2. Create a recursive method in Java to calculate xxx raised to the power of yyy (i.e., xyx^yxy). For example,
if x=2x = 2x=2 and y=3y = 3y=3, the method should return 8. Test this method with x=2x = 2x=2 and y=3y
= 3y=3.
3. Create a recursive method gcd(int a, int b) that calculates the greatest common divisor of two integers
aaa and bbb. For example, gcd(48, 18) should return 6.

Quiz

1. What is a base case in recursion?

A) The condition that stops the recursion


B) The initial value of the recursive method
C) The method that calls itself
D) The number of recursive calls

Answer: A) The condition that stops the recursion

2. Which of the following is an example of a problem that can be solved using recursion?

A) Sorting a list of numbers


B) Computing the factorial of a number
C) Finding the maximum value in an array
D) Both B and C

Answer: D) Both B and C

3. What happens if a recursive method does not have a base case?

A) The method will complete execution normally


B) The method will cause a compile-time error
C) The method will result in infinite recursion and a stack overflow error
D) The method will return zero

Answer: C) The method will result in infinite recursion and a stack overflow error
4. In the recursive method int factorial(int n) { if (n == 0) return 1; else return n * factorial(n - 1); },
what will factorial(3) return?

A) 3
B) 6
C) 9
D) 12

Answer: B) 6

5. Which statement about recursion in Java is true?

A) Recursive methods always use more memory than iterative methods.


B) Recursion is always faster than iteration.
C) Recursive methods must always have a base case to avoid infinite recursion.
D) Recursive methods cannot return values.

Answer: C) Recursive methods must always have a base case to avoid infinite recursion

2. Nesting of Methods

Nesting of Methods in Java


In Java, method nesting refers to the practice of calling one method from another method within the same
class. Nesting of methods can help break down complex tasks into smaller, manageable operations while
improving code modularity and readability.
Syntax
Java does not allow declaring a method within another method directly (as in some other programming
languages like Python). However, nesting of method calls is allowed, where one method calls another, forming
a hierarchy of method executions.

General Syntax:

class ClassName {
// Method 1
void method1() {
// Method body
}

// Method 2
void method2() {
// Method1 is called inside Method2
method1();
}
}
In this example, method2() calls method1() within its body. This kind of nesting helps in organizing functionality
and code reusability.

Example Program:

public class MethodNesting {

// Method to calculate the average of three numbers


public static double average(double a, double b, double c) {
return sum(a, b, c) / 3; // Calls the sum method
}

// Method to calculate the sum of three numbers


public static double sum(double a, double b, double c) {
return a + b + c;
}

public static void main(String[] args) {


double num1 = 10.5, num2 = 20.0, num3 = 30.5;
System.out.println("Average: " + average(num1, num2, num3));
}
}

This Java program demonstrates method nesting, where one method calls another. It has two static methods:
1. average(double a, double b, double c): Calculates the average of three numbers by calling the sum
method and dividing the result by 3.
2. sum(double a, double b, double c): Computes the sum of three numbers.

In the main method, it initializes three double values, calculates their average using the average method, and
prints the result.

Practice Program: Banking System

Consider a scenario in a banking system where a user performs multiple operations, such as checking account
balance, withdrawing funds, and calculating transaction charges. Nesting methods can be used to simplify these
tasks.
Example:
class BankAccount {
double balance;

// Method to check balance


double checkBalance() {
System.out.println("Checking balance...");
return balance;
}

// Method to deduct transaction charges


void deductCharges() {
System.out.println("Deducting transaction charges...");
balance -= 10; // Deduct a flat charge
}

// Method to withdraw amount


void withdraw(double amount) {
// Checking balance first (nested method call)
if (checkBalance() >= amount) {
balance -= amount;
System.out.println("Withdrawal of $" + amount + " successful.");
// Deducting charges after withdrawal
deductCharges(); // Nested method call
} else {
System.out.println("Insufficient balance for withdrawal.");
}
}

// Method to deposit amount


void deposit(double amount) {
balance += amount;
System.out.println("Deposit of $" + amount + " successful.");
}

// Main method to demonstrate nesting


public static void main(String[] args) {
BankAccount account = new BankAccount();
account.balance = 500; // Set initial balance
account.deposit(200); // Deposit funds
account.withdraw(100); // Withdraw funds
}
}
Output:
Deposit of $200 successful.
Checking balance...
Withdrawal of $100 successful.
Deducting transaction charges...

Explanation:
• In this example, withdraw() method calls both checkBalance() and deductCharges() to check the account
balance and deduct charges. These methods are "nested" within the withdraw() method.
• This example simulates real-time banking operations where multiple steps need to be performed
together, making method nesting an effective way to organize related tasks.

Key Points
1. Improved Code Modularity: Nesting methods breaks down larger, complex tasks into smaller, reusable
methods. Each method performs a specific task, improving code readability and reusability.

2. Maintainability: Smaller methods make maintaining and debugging code easier, especially in real-
time systems where multiple operations occur frequently.

3. Flexibility in Design: Using nested methods allows you to modify one method's functionality
without impacting others. For example, if the transaction charges change, the deductCharges() method can be
updated without altering the other methods.

4. Real-Time Usage: In real-world applications like banking, online shopping, or hotel booking,
method nesting is essential to manage sequences of operations in a clean and organized manner.

Nesting methods in Java is a useful technique for organizing code and promoting reuse. While Java does not
allow the direct declaration of methods inside other methods, it supports method nesting via calls, allowing
one method to invoke others, making code simpler and more maintainable in complex systems.

Do It Yourself

1. Implement a program that converts between Celsius, Fahrenheit, and Kelvin using nested conversion
methods.
2. Write a program that adds items to a cart, calculates the total, and applies discounts using nested
method calls.
3. Design a program where nested methods check book availability, issue books, and calculate overdue
fines.
4. Create a program that calculates the final grade using nested methods to compute marks from
assignments, exams, and projects.

Quiz

1. Which of the following is true about nested classes in Java?


A) Nested classes are allowed to access only static members of the outer class
B) Nested classes can access all members of the outer class, including private ones
C) Nested classes cannot be declared private or protected
D) Nested classes are not allowed in Java
Answer: B) Nested classes can access all members of the outer class, including private ones

2. What is the correct syntax to create an object of an inner class?

class Outer {
class Inner {
void show() {
System.out.println("Inside Inner class");
}
}
}

class Test {
public static void main(String[] args) {
// Which of the following is the correct way to instantiate Inner class?
}
}

A) Inner i = new Inner();


B) Outer.Inner i = new Outer.Inner();
C) Outer.Inner i = new Outer().new Inner();
D) Outer.Inner i = new Inner();

Answer: C) Outer.Inner i = new Outer().new Inner();

3. Which type of nested class can access only static members of the outer class?
A) Static nested class
B) Non-static inner class
C) Anonymous inner class
D) Local inner class

Answer: A) Static nested class


4. Which of the following is a valid reason for using nested Java classes?
A) To reduce the visibility of a class
B) To create multiple objects of the outer class
C) To avoid memory leaks
D) To organize classes that are used only by the outer class

Answer: D) To organize classes that are used only by the outer class

5. Consider the following code:


class Outer {
private int x = 10;
class Inner {
void display() {
System.out.println(x);
}
}
}
public class Main {
public static void main(String[] args) {
Outer o = new Outer();
Outer.Inner i = o.new Inner();
i.display();
}
}

What will be the output?


A) Compilation error
B)Runtimeerror
C)0
D) 10
Answer: D) 10

6. Which of the following statements is true about static nested classes?


A) Static nested classes can access non-static members of the outer class
B) Static nested classes are only accessible by the outer class
C) Static nested classes can be instantiated without an object of the outer class
D) Static nested classes cannot have constructors

Answer: C) Static nested classes can be instantiated without an object of the outer class

4. Method Overriding

Method Overriding in Java


Method overriding is a key feature in Java that allows a subclass to provide a specific implementation of a
method that is already defined in its superclass. This capability is essential for implementing Run Time
Polymorphism, where the method that gets executed depends on the type of object used to invoke it.
Basics of Method Overriding
Definition: Method overriding occurs when a subclass defines a method with the same name, parameters, and
return type as a method in its superclass. The method in the subclass overrides the method in the superclass.

Key Points:

• Same Method Signature: The overriding method must have the same name, parameter list, and return
type (or subtype) as the method in the superclass.
• Access Modifiers: The access level of the overriding method can be the same or more accessible than
the method in the superclass (e.g., protected can be overridden as public).
• Method Bodies: The implementation of the method in the subclass provides the specific behavior.
Example of Method Overriding
// Base Class
class Animal {
void makeSound() {
System.out.println("Animal makes a sound");
}
}

// Subclass
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog barks");
}
}

// Driver Class
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
myAnimal.makeSound(); // Output: Animal makes a sound

Animal myDog = new Dog();


myDog.makeSound(); // Output: Dog barks
}
}

Explanation:

• Animal is the superclass with a method makeSound().


• Dog is a subclass that overrides the makeSound() method.
• When the method is invoked using a reference of type Animal but pointing to a Dog object, the
overridden method in Dog is executed.
Rules for Java Method Overriding
1. Access Modifiers:
• An overriding method can have the same or more permissive access level compared to the method in
the superclass. For instance, if the superclass method is protected, it can be overridden with protected
or public, but not with private.

class Parent {
protected void display() {
System.out.println("Display from Parent");
}
}
class Child extends Parent {
@Override
public void display() {
System.out.println("Display from Child");
}
}

2. Final Methods:

Methods marked as final in the superclass cannot be overridden in subclasses.

class Parent {
final void display() {
System.out.println("Final display from Parent");
}
}
class Child extends Parent {
// This would produce an error
// void display() { System.out.println("Display from Child"); }
}

3. Static Methods:

Static methods cannot be overridden; they are subject to method hiding. The method in the subclass
hides the static method of the superclass.

class Parent {
static void display() {
System.out.println("Static display from Parent");
}
}
class Child extends Parent {
static void display() {
System.out.println("Static display from Child");
}
}
public class Main {
public static void main(String[] args) {
Parent.display(); // Output: Static display from Parent
Child.display(); // Output: Static display from Child
}
}

4. Private Methods: Private methods cannot be overridden as they are not accessible to subclasses.
They are only accessible within the class where they are declared.

class Parent {
private void display() {
System.out.println("Private display from Parent");
}
}

class Child extends Parent {


// This will not override the parent's private method
private void display() {
System.out.println("Private display from Child");
}
}

5. Covariant Return Types:


• From Java 5 onwards, the return type of the overriding method can be a subtype of the return type
declared in the superclass.

class Parent {
public Number getNumber() {
return 1;
}
}

class Child extends Parent {


@Override
public Integer getNumber() {
return 2;
}
}

6. Using super to Call Superclass Methods:

• The super keyword can be used to call methods from the superclass within the overriding method.

class Parent {
void show() {
System.out.println("Parent's show()");
}
}

class Child extends Parent {


@Override
void show() {
super.show();
System.out.println("Child's show()");
}
}
public class Main {
public static void main(String[] args) {
Parent obj = new Child();
obj.show(); // Output: Parent's show() \n Child's show()
}
}
Do It Yourself

1. Create a base class Vehicle with a method start(). Create a subclass Car that overrides start() to provide
a specific implementation.
2. Define a base class Employee with a method calculateSalary(). Implement a subclass Manager that
overrides calculateSalary() to return a different salary calculation.
3. Write a base class Shape with a method draw(). Create subclasses Circle and Rectangle that override the
draw() method to provide specific drawing behavior.
4. Implement a class Animal with a method eat(). Create a subclass Cat that overrides the eat() method to
provide a specific eating behavior.
5. Create a class Bird with a method fly(). Define a subclass Parrot that overrides fly() to provide a detailed
implementation of how a parrot flies.

Quiz

1. What is required for a method to override a method in Java?


A) Same method name, different return type
B) Same method name, same parameters
C) Same method name, different parameters
D) Different method name, same return type

Answer: B) Same method name, same parameters

2. Which of the following statements is true about method overriding?

A) The overriding method can have a less restrictive access modifier.


B) The overriding method must have the same return type as the method in the superclass.
C) Private methods can be overridden.
D) Static methods are overridden, not hidden.

Answer: B) The overriding method must have the same return type as the method in the superclass.
3. What will be the output of the following code?

class A {
void show() {
System.out.println("A");
}
}
class B extends A {
void show() {
System.out.println("B");
}
}

public class Main {


public static void main(String[] args) {
A obj = new B();
obj.show();
}
}

A) A
B) B
C) Compilation Error
D) Runtime Error

Answer: B) B

4. Can a final method be overridden in Java?

A) Yes, it can be overridden


B) No, it cannot be overridden
C) It depends on the return type
D) It depends on the access modifier
Answer: B) No, it cannot be overridden

5. If a superclass method throws a checked exception, what can be the exception handling rule for
the overridden method in the subclass?

A) It can throw any checked exception.


B) It can throw the same checked exception or its subclasses.
C) It must throw the same checked exception.
D) It must not throw any exception.

Answer: B) It can throw the same checked exception or its subclasses.

6. What will be the output of the following code?

class Parent {
static void display() {
System.out.println("Parent display");
}
}
class Child extends Parent {
static void display() {
System.out.println("Child display");
}
}
public class Main {
public static void main(String[] args) {
Parent.display();
Child.display();
}
}
A) Parent display \n Child display
B) Child display \n Child display
C) Parent display \n Parent display
D) Compilation Error
Answer: A) Parent display \n Child display

5. Method Overloading Vs Method Overriding

Differences Between Method Overloading and Method Overriding:


Method Overloading and Method Overriding are both concepts related to polymorphism in Java, but they
function differently. Here's a detailed comparison between them:

Aspect Method Overloading Method Overriding

Polymorphism Compile-time polymorphism Run-time polymorphism


Type

Purpose Increases readability by allowing multiple Provides specific implementation of a


methods with the same name but method already defined in the parent
different parameters. class.

Location Occurs within the same class. Involves two classes with an
inheritance relationship.

Inheritance Inheritance is not mandatory. Inheritance is mandatory.


Requirement

Method Methods must have the same name but Methods must have the same name,
Signature different signatures (parameter lists). signature, and return type.

Return Type The return type can be the same or The return type must be the same or
different. Parameters must change. co-variant.

Binding Type Uses static binding (compile-time). Uses dynamic binding (run-time).

Private/Final Private and final methods can be Private and final methods cannot be
Methods overloaded. overridden.

Argument List Must differ in method overloading. Must be the same in method
overriding.
Method Overloading

Method Overloading allows multiple methods in the same class to share the same name but differ in their
parameter lists. It's a type of compile-time polymorphism.

Example of Method Overloading:


class MethodOverloadingEx {
static int add(int a, int b) {
return a + b;
}
static int add(int a, int b, int c) {
return a + b + c;
}
public static void main(String args[]) {
System.out.println("add() with 2 parameters: " + add(4, 6));
System.out.println("add() with 3 parameters: " + add(4, 6, 7));
}
}

Output:

add() with 2 parameters: 10


add() with 3 parameters: 17

Method Overriding:

Method Overriding allows a subclass to provide a specific implementation of a method that is already defined
in its parent class. It is a type of runtime polymorphism.

Example of Method Overriding:


class Animal {
void eat() {
System.out.println("Animal is eating.");
}
}
class Dog extends Animal {
@Override
void eat() {
System.out.println("Dog is eating.");
}
void eatAsAnimal() {
super.eat();
}
}
class MethodOverridingEx {
public static void main(String args[]) {
Dog dog = new Dog();
Animal animal = new Animal();
dog.eat(); // Calls Dog's eat method
animal.eat(); // Calls Animal's eat method
// Polymorphism
Animal animalDog = new Dog();
animalDog.eat(); // Calls Dog's eat method due to dynamic binding
// Calling base class method using subclass reference
((Dog) animalDog).eatAsAnimal();
}
}

Output:

Dog is eating.
Animal is eating.
Dog is eating.
Animal is eating.
Explanation:

• The eat() method is overridden in the Dog class, providing its own implementation while the parent
Animal class has its own.
• The base class method can be called using the super keyword within the subclass.

Key Takeaways:

• Method Overloading is primarily used to provide multiple ways to perform a similar task, improving
code readability.
• Method Overriding is used in inheritance hierarchies to modify or extend the behavior of methods
inherited from parent classes.

6. final and static in Methods

final and static in Methods in Java


In Java, the final and static keywords can be used with methods to modify their behavior. These attributes serve
distinct purposes in controlling method inheritance, overriding, and the method's association with objects or
classes.

1. Final Methods
When a method is declared final, subclasses cannot override it. This is typically used to prevent modification of
crucial functionality in derived classes.
Characteristics of final Methods:
• Prevent Overriding: A final method cannot be overridden by any subclass. This is useful when a class
wants to ensure that a specific method remains unchanged across all subclasses.
• Inheritance: Although a subclass can inherit a final method, it cannot be modified in that subclass.
• Performance Optimization: In some cases, marking methods as final allows the compiler to optimize
calls to those methods because it knows the implementation will not change.
Example of a final Method:
class Vehicle {
final void start() {
System.out.println("Vehicle is starting.");
}
}
class Car extends Vehicle {
// This will cause a compile-time error
// void start() {
// System.out.println("Car is starting.");
// }
}
public class FinalMethodExample {
public static void main(String[] args) {
Car car = new Car();
car.start(); // Inherits the final method from Vehicle
}
}

Key Point: Trying to override the start() method in the Car class will result in a compile-time error.

2. Static Methods
A static method in Java belongs to the class rather than to any specific instance (object) of that class. This means
static methods can be called without creating an object of the class.
Characteristics of static Methods:
• Class-Level Association: static methods are associated with the class itself, not with any instance.
• Access without Object: They can be called using the class name directly.
• Cannot Use Instance Variables/Methods: static methods cannot directly access instance variables or
instance methods. They can only interact with static variables and other static methods.
• Overriding Restriction: static methods cannot be overridden, but they can be hidden by a subclass (this
is known as method hiding).
Example of a static Method:
class Calculator {
static int add(int a, int b) {
return a + b;
}
}
public class StaticMethodExample {
public static void main(String[] args) {
// Calling static method without creating an object
int result = Calculator.add(5, 10);
System.out.println("Sum: " + result);
}
}

Static Method Hiding vs. Overriding


While static methods cannot be overridden, they can be hidden. If a subclass defines a static method with the
same name and parameters as the one in its superclass, it hides the superclass method rather than overriding
it.
Example of Method Hiding:
class Parent {
static void display() {
System.out.println("Static method in Parent class.");
}
}
class Child extends Parent {
static void display() {
System.out.println("Static method in Child class.");
}
}
public class StaticMethodHiding {
public static void main(String[] args) {
Parent p = new Parent();
p.display(); // Calls Parent's static method
Child c = new Child();
c.display(); // Calls Child's static method
Parent pc = new Child();
pc.display(); // Calls Parent's static method (not overridden)
}
}

Output:

Static method in Parent class.


Static method in Child class.
Static method in Parent class.
Key Differences Between final and static in Methods:

Aspect final Method static Method

Inheritance Cannot be overridden by subclasses. Cannot be overridden, but can be hidden.

Object/Class Associated with object instances. Associated with the class itself.

Usage Used to prevent changes to method Used for utility methods that don’t depend on
behavior. object state.

Instance Can access instance variables and Cannot access instance variables or methods.
Access methods.

• Use final methods when you want to prevent any modifications to the method’s behavior in subclasses.
• Use static methods when the method’s functionality is tied to the class as a whole and does not rely on
object instances.

Do It Yourself

1. Write a Java program that demonstrates the use of the final keyword with methods. Create a parent
class with a final method and attempt to override it in the child class. Explain why the program does or
does not compile.Show a compilation error for the final method being overridden and explain the error.
2. Create a Java program with a class that has both instance and static methods. Call the static method
without creating an instance of the class. Explain how static methods differ from instance methods in
terms of memory and access.
3. Write a Java program that declares a final method and a static method within the same class. Inside the
static method, attempt to modify a final variable. Explain why the program does or does not allow
modification of the final variable inside the static method

Quiz

1. What happens when you attempt to override a final method in a subclass?


A) The program runs normally.
B) The final method is successfully overridden.
C) The program compiles but throws an exception at runtime.
D) The program fails to compile with an error.
Answer: D) The program fails to compile with an error.

2. Which of the following is true about static methods in Java?


A) Static methods can be called without creating an instance of the class.
B) Static methods can access both static and instance variables directly.
C) Subclass methods can override static methods.
D) Static methods cannot return any value
Answer: A) Static methods can be called without creating an instance of the class.

3. Given the following code, what will happen when the program is compiled?

class A {
public final void display() {
System.out.println("Final method in Class A");
}
}

class B extends A {
public void display() {
System.out.println("Trying to override final method");
}
}

A) The code will run and print "Trying to override final method."
B) The code will run and print "Final method in Class A."
C) The program will fail to compile with an error.
D) The code will throw a runtime exception.
Answer: C) The program will fail to compile with an error.

4. Which of the following statements is false regarding the static and final keywords in methods?

A) A static method belongs to the class rather than to any specific object.
B) A final method cannot be overridden by a subclass.
C) A static method can be overridden in the subclass.
D) A final method can be called from the subclass but cannot be modified.
Answer: C) A static method can be overridden in the subclass.

5. Consider the following code snippet. What will be the output?

class Test {
static int count = 0;
Test() {
count++;
}
}

public class Main {


public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
Test t3 = new Test();
System.out.println(Test.count);
}
}

A) 0
B) 1
C) 2
D) 3
Answer: D) 3

6. Given the following code, which statement is true?

class MyClass {
static void display() {
System.out.println("Static method called");
}
}

public class MainClass {


public static void main(String[] args) {
MyClass obj = new MyClass();
obj.display();
MyClass.display();
}
}

A) The program will fail to compile.


B) The static method can only be called using the class name.
C) The static method can be called using both the class name and the object.
D) The static method cannot be called at all.
Answer: C) The static method can be called using both the class name and the object.

References

Recursive methods - Recursion in Java Full Tutorial - How to Create Recursive Methods
Nesting of methods - Java-70- Nesting of Methods in Java || Java Programming
Method overriding - #52 Method Overriding in Java
Method overloading Vs Method overriding - DIFFERENCES BETWEEN METHOD OVERLOADING AND
OVERRIDING - JAVA PROGRAMMING
Final and static methods - #57 Final keyword in java #4.6 Java Tutorial | Static Keyword

You might also like