UNIT 2 Notes
UNIT 2 Notes
Unit - II
Classes and Objects – Introduction
In Object-Oriented Programming, classes and objects are the basic building blocks used to design and
develop programs. A class is a user-defined data type that acts as a blueprint or template for creating objects.
It defines the properties (data members) and behaviors (member functions) that the objects created from it
will have. A class represents a logical concept and does not occupy memory by itself.
An object is an instance of a class and represents a real-world entity. When an object is created, memory is
allocated to store its data members. Objects contain state (values of variables), behavior (methods), and
identity (unique existence). Through objects, we can access the variables and methods defined in the class.
Classes and objects help in organizing programs into reusable and modular units. They improve code
readability, maintainability, and security by supporting features such as data abstraction, encapsulation, and
reusability. Therefore, classes and objects form the foundation of Object-Oriented Programming.
Example of a class:
class Student {
int rollNo;
String name;
void display() {
[Link](rollNo + " " + name);
}
}
Class modifiers are keywords used in a class declaration to control the accessibility and behavior of a class.
They are mainly classified into access modifiers and non-access modifiers. Access modifiers determine
where the class can be accessed from. The public modifier allows a class to be accessed from anywhere,
while a class with default access (no modifier) can be accessed only within the same package.
Non-access modifiers define the behavior of a class. A final class cannot be inherited, which helps prevent
modification. An abstract class cannot be instantiated and is mainly used as a base class for other classes.
Class modifiers play an important role in improving security, flexibility, and design of a program.
GPCET Department of CSE&CAI
Examples:
Class members are the components that make up a class and define its structure and behavior. They mainly
include data members (variables) and member functions (methods). Data members store information
related to the class, while member functions define the actions that can be performed using that data. Class
members can have different access levels such as public, private, or protected, which control how they can
be accessed. Data members represent the state of an object, and methods represent its behavior. Together,
class members help in achieving encapsulation by binding data and functions into a single unit.
class Student {
int rollNo; // data member
String name; // data member
class Main {
public static void main(String[] args) {
Student s1 = new Student(); // object declaration
[Link] = 1;
[Link] = "Amit";
[Link]();
}
}
In summary, class members define what a class contains and what it can do, while object declaration creates
actual instances of the class that use those members.
GPCET Department of CSE&CAI
Assigning one object to another means making two reference variables point to the same object in memory.
In Object-Oriented Programming (especially in Java), objects are accessed using reference variables. When
one object reference is assigned to another, no new object is created. Instead, both references refer to the
same memory location. Any change made using one reference will be reflected when accessed through the
other reference.
This concept is important because it shows that object assignment copies the reference, not the actual object
data. Therefore, object assignment does not perform a deep copy; it performs a shallow copy (reference
copy).
Example Explanation
Consider a class with some data members. When an object is created, memory is allocated for it. If another
object reference is assigned to this object, both references will point to the same object. As a result,
modifying the object through one reference affects the other. This behavior is different from primitive data
types, where values are copied instead of references.
Code Example
class Student {
int rollNo;
}
class Main {
public static void main(String[] args) {
Student s1 = new Student(); // first object
[Link] = 10;
[Link] = 20;
[Link]([Link]); // Output: 20
[Link]([Link]); // Output: 20
}
}
Key Points
Access control for class members determines where and how the data members and member functions of
a class can be accessed. It is achieved using access specifiers (access modifiers). Access control is an
important feature of Object-Oriented Programming because it supports data hiding, security, and
encapsulation by restricting unauthorized access to class members.
1. Private
Members declared as private are accessible only within the same class. They cannot be accessed directly
from outside the class. This modifier is mainly used to hide data and protect it from misuse.
class Student {
private int rollNo;
void setRollNo(int r) {
rollNo = r;
}
int getRollNo() {
return rollNo;
}
}
When no access modifier is specified, the member has default access. Such members are accessible within
the same package only.
class Student {
int rollNo; // default access
}
3. Protected
Members declared as protected are accessible within the same package and in subclasses outside the
package. This modifier is mainly used when inheritance is involved.
class Person {
protected String name;
}
4. Public
Members declared as public are accessible from anywhere in the program. They have the widest scope.
class Student {
GPCET Department of CSE&CAI
In Object-Oriented Programming, private members of a class cannot be accessed directly from outside
the class. This restriction is used to achieve data hiding and security. However, private members can still
be accessed indirectly through public methods of the same class. This concept is known as encapsulation.
Private data members are usually accessed using getter and setter methods. A setter method is used to
assign or modify the value of a private variable, while a getter method is used to retrieve its value. This
controlled access ensures that data is not misused or modified in an unintended way.
Example Explanation
Consider a class where the data members are declared as private. These members cannot be accessed
directly using an object of the class. To access them, public member functions are provided inside the class.
These functions allow reading or modifying the private data in a safe and controlled manner. This approach
helps in maintaining the integrity of data and improves program reliability.
Code Example
class Student {
private int rollNo;
// setter method
public void setRollNo(int r) {
rollNo = r;
}
// getter method
public int getRollNo() {
return rollNo;
}
}
class Main {
public static void main(String[] args) {
GPCET Department of CSE&CAI
Short Note
Private members of a class cannot be accessed directly from outside the class. They can be accessed
indirectly through public member functions such as getter and setter methods, which provide controlled and
secure access to the private data.
A constructor is a special member function of a class that is used to initialize objects of that class. It is
automatically invoked when an object of the class is created. The main purpose of a constructor is to assign
initial values to the data members of the class and to perform any setup required for the object.
A constructor has the same name as the class and does not have a return type, not even void.
Constructors help ensure that objects are always created in a valid and consistent state.
Characteristics of Constructors
Types of Constructors
1. Default Constructor
A default constructor does not take any parameters. It assigns default values to data members.
Example:
class Student {
int rollNo;
2. Parameterized Constructor
A parameterized constructor accepts arguments and initializes data members with user-defined values.
GPCET Department of CSE&CAI
Example:
class Student {
int rollNo;
3. Constructor Overloading
When a class has more than one constructor with different parameter lists, it is called constructor
overloading.
Example:
class Student {
int rollNo;
String name;
Student() {
rollNo = 0;
name = "Not Assigned";
}
Student(int r, String n) {
rollNo = r;
name = n;
}
}
Example Program
class Student {
int rollNo;
String name;
Student(int r, String n) {
rollNo = r;
name = n;
}
void display() {
[Link](rollNo + " " + name);
}
}
class Main {
public static void main(String[] args) {
Student s1 = new Student(10, "Anil");
[Link]();
}
}
Importance of Constructors
When an object is created, the constructor that matches the arguments passed is automatically invoked. This
improves flexibility and makes the program easier to use and understand.
Explanation
Overloaded constructor methods allow a class to provide multiple ways of initializing an object. One
constructor may assign default values, while another may initialize the object with user-defined values. This
helps in creating objects with different initial states without writing separate initialization methods.
Constructor overloading is an example of compile-time polymorphism.
Example Code
class Student {
int rollNo;
String name;
// Default constructor
Student() {
rollNo = 0;
name = "Not Assigned";
}
// Parameterized constructor
Student(int r, String n) {
rollNo = r;
name = n;
}
void display() {
[Link](rollNo + " " + name);
}
}
class Main {
public static void main(String[] args) {
Student s1 = new Student(); // calls default constructor
Student s2 = new Student(5, "Ravi"); // calls parameterized constructor
[Link]();
[Link]();
}
}
Key Points
Nested Classes
A nested class is a class that is defined inside another class. The class inside is called the nested class, and
the outer class is called the enclosing class. Nested classes are used to logically group classes that are
closely related, improve code readability, and increase encapsulation.
Nested classes can access the members (including private members) of the enclosing class. They are mainly
used when one class is useful only to another class.
Explanation
Nested classes help organize code by placing one class inside another when there is a strong relationship
between them. They enhance security by restricting access to helper classes and reduce namespace pollution.
In Java, nested classes are divided into static nested classes and non-static nested classes (inner classes).
Inner classes further include member inner classes, local inner classes, and anonymous inner classes.
An inner class is a class declared inside another class without the static keyword. It is associated with an
instance of the outer class and can access all instance variables and methods of the outer class directly.
class Outer {
int x = 10;
class Inner {
void show() {
[Link]("Value of x: " + x);
}
}
}
class Test {
public static void main(String[] args) {
Outer obj = new Outer();
[Link] in = [Link] Inner();
[Link]();
}
}
A static nested class is declared using the static keyword. Unlike inner classes, it does not require an
object of the outer class and can access only static members of the outer class.
GPCET Department of CSE&CAI
class Outer {
static int y = 20;
class Test {
public static void main(String[] args) {
[Link] obj = new [Link]();
[Link]();
}
}
A final class improves security and prevents misuse through inheritance, while a final method ensures
consistent behavior across subclasses.
In Java, all arguments are passed by value. When passing primitive data types (such as int, float, char), a
copy of the value is passed to the method. Any changes made inside the method do not affect the original
variable.
When objects are passed to methods, a copy of the reference is passed. Both the original and copied
references point to the same object, so changes made inside the method affect the original object. This
behavior is often referred to as call by reference, though technically Java still uses call by value.
class Test {
void change(Box b) {
[Link] = 20;
}
[Link]([Link]); // Output: 20
}
}
Exam Note:
Java uses call by value, but object references allow modification of object data.
Keyword this
The keyword this is a reference variable that refers to the current object of the class. It is mainly used to
differentiate between instance variables and local variables when they have the same name. It can also
be used to invoke current class methods and constructors.
GPCET Department of CSE&CAI
class Student {
int rollNo;
Student(int rollNo) {
[Link] = rollNo;
}
}
class Demo {
void display() {
[Link]("Display method");
}
void show() {
[Link]();
}
}
class Demo {
Demo() {
this(10);
[Link]("Default Constructor");
}
Demo(int x) {
[Link]("Parameterized Constructor");
}
}
A method is a block of code that performs a specific task and is executed only when it is called. Methods
are used to define the behavior of a class in Object-Oriented Programming. They help in breaking a large
program into smaller, manageable units, thereby improving code readability, reusability, and
maintainability. A method may take input in the form of parameters, perform certain operations, and may
return a result.
Methods allow code reuse because the same method can be called multiple times without rewriting the code.
They also make debugging easier since errors can be traced within individual methods.
Defining Methods
Defining a method means declaring it with a proper method header and method body. A method definition
includes the access modifier (optional), return type, method name, parameter list, and the body of the
method enclosed within braces.
General Syntax:
GPCET Department of CSE&CAI
returnType methodName(parameters) {
// method body
}
class Calculator {
class Main {
public static void main(String[] args) {
Calculator c = new Calculator();
int result = [Link](5, 3);
[Link](result);
[Link]();
}
}
Key Points
Overloaded Methods
Method overloading is a feature of Object-Oriented Programming that allows a class to have multiple
methods with the same name but different parameter lists. The methods may differ in the number of
parameters, type of parameters, or order of parameters. Method overloading helps improve code readability
and flexibility by allowing similar operations to be performed using the same method name.
The return type alone cannot be used to overload methods. Method overloading is an example of compile-
time polymorphism, as the method call is resolved during compilation.
Example
In method overloading, the compiler determines which method to execute based on the arguments passed
during the method call. This allows a single method name to perform similar tasks with different inputs,
reducing the need for multiple method names.
Code Example
class Calculator {
return a + b;
}
class Main {
public static void main(String[] args) {
Calculator c = new Calculator();
[Link]([Link](5, 10));
[Link]([Link](2, 3, 4));
[Link]([Link](2.5, 3.5));
}
}
When an object is created, the constructor that matches the arguments passed is automatically invoked.
Constructor overloading helps provide default values as well as customized initialization.
Example
One constructor may assign default values to data members, while another constructor may initialize the
object with specific values provided by the user. This avoids writing separate initialization methods and
makes object creation more flexible.
Code Example
class Student {
int rollNo;
String name;
Student() {
rollNo = 0;
name = "Not Assigned";
}
Student(int r, String n) {
rollNo = r;
name = n;
}
void display() {
GPCET Department of CSE&CAI
class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student(10, "Ravi");
[Link]();
[Link]();
}
}
In Object-Oriented Programming, objects of a class can be passed as parameters to methods, just like
primitive data types. When a class object is passed to a method, the reference of the object is passed (call
by value of reference). This means both the calling method and the called method refer to the same object
in memory. Therefore, any changes made to the object inside the method will be reflected in the original
object.
Passing class objects as parameters is useful when a method needs to access or modify multiple data
members of an object or when complex data structures are involved.
Explanation
When an object is passed as an argument to a method, Java passes a copy of the reference to that object.
Since both references point to the same memory location, modifications made to the object's data members
inside the method affect the original object. However, if the reference itself is reassigned inside the method,
it does not affect the original reference. This mechanism supports efficient memory usage and allows
methods to operate directly on object data.
Code Example
class Box {
int length;
int width;
}
class Test {
[Link]([Link]); // Output: 10
[Link]([Link]); // Output: 5
}
}
Key Points
Access Control
Access control determines who can access the members (variables and methods) of a class. It is
implemented using access modifiers, which help in protecting data and achieving encapsulation. Proper
access control improves security and prevents misuse of class members.
The main access modifiers are private, default, protected, and public.
Code Example
class Student {
private int rollNo;
void setRollNo(int r) {
rollNo = r; // accessible inside class
}
void display() {
[Link](rollNo);
}
}
class Main {
public static void main(String[] args) {
Student s = new Student();
[Link](10);
[Link]();
Code Example
class Demo {
int x = 20; // default access
void show() {
[Link](x);
}
}
class Test {
public static void main(String[] args) {
GPCET Department of CSE&CAI
Code Example
class Parent {
protected int value = 50;
}
class Main {
public static void main(String[] args) {
Child c = new Child();
[Link]();
}
}
Code Example
class Sample {
public int num = 100;
}
class Test {
public static void main(String[] args) {
Sample s = new Sample();
[Link]([Link]); // accessible anywhere
}
}
Recursive Methods
A recursive method is a method that calls itself to solve a problem. Recursion is useful for problems that
can be broken down into smaller sub-problems. Every recursive method must have a base condition to stop
the recursion; otherwise, it leads to infinite calls and stack overflow.
Nesting of Methods
Nesting of methods means calling one method from another method. Java does not allow defining a
method inside another method, but a method can call another method within the same class or from another
class. Nesting improves modularity and code reuse.
Example
class Demo {
void display() {
[Link]("Display Method");
}
void show() {
display(); // method calling another method
}
Overriding Methods
Method overriding occurs when a subclass provides its own implementation of a method already defined
in its superclass. The method name, parameters, and return type must be the same. Overriding supports
runtime polymorphism.
Rules:
• Inheritance is required
• Method signature must be the same
GPCET Department of CSE&CAI
Example
class Parent {
void show() {
[Link]("Parent Method");
}
}
A final attribute is a constant whose value cannot be changed once initialized. It must be assigned a value
at the time of declaration or inside a constructor.
class Demo {
final int MAX = 100;
}
Static Attributes
A static attribute belongs to the class rather than objects. Only one copy exists, shared by all objects of
the class. Static variables are accessed using the class name.
class Counter {
static int count = 0;
Counter() {
count++;
}