OOPS Through JAVA - Unit2
OOPS Through JAVA - Unit2
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.
// 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());
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.
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
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:
Example:
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
}
Example:
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:
// 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.");
}
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.
• Visibility:
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.
• Visibility:
// 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.
Example:
Notes:
• Visibility:
Example:
Key points:
public Accessible from any class in any package. public class Employee
public Accessible from any class in any package. public 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;
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;
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.
Example:
class Car {
String model;
String color;
static int numberOfCars; // Static field
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;
• 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.
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:
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;
}
Output:
This method is used for creating an object by specifying the class name in a string format.
4. Deserialization
Objects can also be created by reading from a serialized file.
Example:
interface Vehicle {
void start();
}
Example:
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:
• Improved Readability: By breaking complex logic into smaller, well-named methods, your code becomes
easier to understand and maintain.
• 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
}
}
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
2. Which of the following is the correct syntax for declaring a method that returns an integer value?
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
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
• obj1 and obj2 are now references to the same object in memory.
Example:
class Car {
String model;
String color;
void display() {
System.out.println("Model: " + model + ", Color: " + color);
}
}
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
Answer: c) An object
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.
References
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.
class Employee {
// Private fields
this.name = name;
this.salary = salary;
return name;
this.name = name;
return salary;
this.salary = salary;
// Access and modify private members using getter and setter methods
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
2. What will happen if you try to access a private member directly from another class?
A) Compilation error
B) Runtime exception
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.
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.
class Animal {
String type;
this.type = type;
Output:
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.
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 {
length = l;
width = w;
height = h;
box.displayVolume();
Output:
Volume: 60
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";
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
this.brand = brand;
this.year = year;
car.display();
}}
Output:
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
this.title = title;
this.pages = pages;
// Copy constructor
this.title = another.title;
this.pages = another.pages;
copy.display();
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
A) To initialize objects
D) To handle exceptions
Answer B) A class can have multiple constructors with different parameter lists
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.
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.
class Example {
Example() {
System.out.println("No-argument constructor");
Example(int a) {
Example(int a, String b) {
System.out.println("Constructor with integer and string parameters: " + a + ", " + b);
}
}
class Book {
String title;
String author;
int year;
Book() {
title = "Unknown";
author = "Unknown";
year = 0;
Book(String title) {
this.title = title;
author = "Unknown";
year = 0; }
this.title = title;
this.author = author;
year = 0;
this.title = title;
this.author = author;
this.year = year;
void display() {
Book book4 = new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925);
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:
Year: 0
Book 4:
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
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.
• 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).
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
void display() {
nestedObject.display();
Output:
outer_x = 10
outer_private = 30
outer_y = 20
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 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 {
// Private member
// Inner class
class InnerClass {
void display() {
innerObject.display();
Output:
outer_y = 20
outer_private = 30
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() {
localInner.display();
outerObject.outerMethod();
Output:
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:
}
public class AnonymousInnerClassDemo {
void display() {
};
obj.display();
Output:
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
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
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
Answer A) They can access all members of the outer class, including private members
Answer D) To logically group classes that are only used in one place
References
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.
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.
• 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 {
Output:
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
// 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:
this.name = name;
this.age = age;
return name;
return age;
@Override
Usage:
public class Main {
2. Preventing Subclassing
Example:
// Base class
Practice Programs
Example Program:
// Final class
this.setting = setting;
return setting;
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 {
// method body
Real-time Examples
1. Method Finalization
Example:
class BaseClass {
// void display() {
// System.out.println("Illegal!");
// }
}
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 {
System.out.println("Authentication complete.");
// void authenticate() {
// System.out.println("Modified Authentication.");
// }
Practice Programs
Example Program:
class Vehicle {
System.out.println("Engine started.");
// void startEngine() {
// }
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...");
// void calculateInterest() {
// }
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. 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:
x = x + 10;
person.name = "Neetu";
int num = 5;
passByValue(num);
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
A) By reference
B) By value
C) By object
D) By address
Answer: B) By value
3. What happens to the value of a primitive type argument if it is modified inside a method?
4. If an object is passed to a method and its attributes are modified inside the method, what happens?
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
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.
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.
// Constructor
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.
Consider a class Rectangle that has two constructors: one default and one parameterized.
// Default constructor
public Rectangle() {
// Parameterized constructor
this.length = length;
this.width = width;
}
rect.display();
Explanation: The default constructor calls the parameterized constructor using this(10, 5), which initializes the
rectangle with default dimensions.
In scenarios where you want to chain method calls, you can return the current object instance.
this.material = material;
this.height = height;
builder.setMaterial("Wood").setHeight(10).build();
Explanation: The setMaterial and setHeight methods return the current instance of Builder, allowing for method
chaining.
If you want to pass the current object to another method, you can use this.
this.message = message;
msg.forwardMessage();
Explanation: The forwardMessage method uses this to pass the current instance to the sendMessage method.
You can use this to call another method from within the current method.
this.value = value;
System.out.println("Performing operation...");
calc.performOperation();
}
Explanation: In the performOperation method, this.printValue() is used to call the printValue method within the
same class.
When you need to pass the current object as an argument to another class, this is helpful.
this.car = car;
this.car.showDetails();
Driver driver = new Driver(myCar); // Passes the Car instance to the Driver
class Car {
this.make = make;
this.model = model;
Explanation: The Driver constructor receives a Car object and calls its showDetails method.
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.
1. Overuse:Excessive use of this can make the code less readable and harder to understand.
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.
int x;
public MyClass(int x) {
this.x = x;
System.out.println(x);
int x = 10;
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
C) The superclass
3. When can this be used to differentiate between instance variables and method parameters?
C) When the instance variable and parameter have the same name
Answer: C) When the instance variable and parameter have the same name
References
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.
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.
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
}
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.
class BankAccount {
Output:
class 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));
Output:
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
Answer: B) Method overloading allows methods with the same name but different parameter lists.
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");
}
}
5. What will happen if you try to overload a method based solely on its return type in Java?
class OverloadExample {
void process(int a) { }
void process(double a) { }
void process(int a, int b) { }
void process(double a, double b) { }
}
3. Objects as Parameters
Example:
class Employee {
// Fields
String name;
int age;
// Constructor
Employee(String name, int age) {
this.name = name;
this.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);
Output:
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.
class Book {
// Fields
String title;
boolean isAvailable;
// Constructor
Book(String title) {
this.title = title;
this.isAvailable = true; // Book is initially available
}
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.");
}
}
}
Output:
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.
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
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?
5. How can you ensure that an object passed to a method does not get modified?
6. Which of the following is a valid way to pass an object as a parameter to a method in Java?
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;
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;
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;
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;
package clientApp;
import companyInfo.Company;
• 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.
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");
}
}
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.");
}
}
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
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.
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.
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.
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:
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();
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 {
// 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
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.
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:
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.
• 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.
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
2. Which of the following is an example of a problem that can be solved using recursion?
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
Answer: C) Recursive methods must always have a base case to avoid infinite recursion
2. Nesting of Methods
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:
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.
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;
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
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?
}
}
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: D) To organize classes that are used only by the outer class
Answer: C) Static nested classes can be instantiated without an object of the outer class
4. Method Overriding
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
Explanation:
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:
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 Parent {
public Number getNumber() {
return 1;
}
}
• 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()");
}
}
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
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");
}
}
A) A
B) B
C) Compilation Error
D) Runtime Error
Answer: B) B
5. If a superclass method throws a checked exception, what can be the exception handling rule for
the overridden method in the subclass?
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
Location Occurs within the same class. Involves two classes with an
inheritance relationship.
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.
Output:
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.
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.
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);
}
}
Output:
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
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.
class Test {
static int count = 0;
Test() {
count++;
}
}
A) 0
B) 1
C) 2
D) 3
Answer: D) 3
class MyClass {
static void display() {
System.out.println("Static method called");
}
}
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