Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Unit 2 Notes

Download as pdf or txt
Download as pdf or txt
You are on page 1of 24

UNIT 2 NOTES

Introduction to Classes
In object-oriented programming (OOP), a class serves as a blueprint for creating objects
(instances). It defines the structure and behavior (data and methods) that the objects will
have.

Key Concepts:
Class: A template or blueprint used to create objects. It encapsulates data (attributes)
and behavior (methods).
Object: An instance of a class. It has a unique identity, state, and behavior.

1. CLASS DECLARATION
In Java (or most OOP languages), a class is declared with a specific syntax, and you can
control its visibility and accessibility using access modifiers.

Syntax for Class Declaration

To declare a class, use the following basic structure:

[modifier] class ClassName {


// fields (attributes)
// methods (behaviors)
}

Modifier: Optional keyword(s) that define the accessibility (public, private, protected) or
behavior (e.g., abstract, final) of the class.
ClassName: The name of the class, which should typically follow CamelCase
convention.

Example:

public class Car {


// fields (attributes)
String model;
int year;

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

// method (behavior)
public void displayInfo() {
System.out.println("Model: " + model + ", Year: " + year);
}
}

In this example, the Car class has:

Fields: model and year that define the state of a car object.
Constructor: A method that initializes the state of the object when it is created.
Method: displayInfo() that defines the behavior of the class.

2. CLASS MEMBERS
Fields
Fields, also known as attributes or properties, store data specific to an object. For
example, a Car class might have fields for model , color , and year .

public class Car {


// Fields (attributes)
private String model;
private int year;
}

Methods

Methods define the actions or behavior of a class. They usually operate on the fields of the
class and can modify or retrieve the data stored in them.

public class Car {


// Method
public void startEngine() {
System.out.println("The engine has started.");
}
}

Constructors
A constructor is a special method used to initialize objects. It’s called when an object is
created. In most languages like Java, the constructor has the same name as the class.

Example:
public class Car {
String model;
int year;

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

Constructors can be overloaded (having multiple constructors with different parameters) to


provide more flexibility.

3. DECLARATION OF CLASS OBJECTS


To use a class, we must create objects (instances) of that class. Declaring objects is the
process of allocating memory and initializing them using constructors.

Syntax for Object Instantiation:

ClassName objectName = new ClassName(parameters);

ClassName : The name of the class from which the object is created.
objectName : The name of the object.
new : The keyword used to allocate memory for the object.
ClassName(parameters) : Calls the constructor to initialize the object.

Example:

Car obj = new Car("Tesla", 2023);

This creates an object myCar of the class Car with model as "Tesla" and year as 2023 .

Different Ways to Declare Objects:

1. Declare and Initialize in One Step:

Car obj = new Car("Honda", 2020);

2. Declare Without Initialization:


Car obj;
obj = new Car("Honda", 2020);

This separates declaration and initialization into two steps.

4. ASSIGNING ONE OBJECT TO ANOTHER


When you assign one object to another, both references point to the same memory location,
meaning that changes made to one object affect the other. This concept is important to
understand when working with references and copying objects.

Shallow Copy vs. Deep Copy

Shallow Copy: In a shallow copy, the new object references the same memory location
as the original object. Therefore, changes to one object will affect the other.

Example of Shallow Copy:

public class Student


{
String name = "John";
int age = 33 ;

public void attendance()


{
System.out.println("I am Present");
}

public static void main(String[] args)


{
Student obj = new Student();

Student obj2 = obj ;

System.out.println(obj2.name);
System.out.println(obj2.age);

obj2.attendance();
}
}

Deep Copy: In a deep copy, a new object is created with its own memory space, and
the fields of the original object are copied into this new object. Changes made to one
object do not affect the other.

Example of Deep Copy (Manual Copying of Attributes):

public class Student


{
String name = "John";
int age = 33 ;

public void attendance()


{
System.out.println("I am Present");
}

public static void main(String[] args)


{
Student obj1 = new Student();
System.out.println(obj1.name);
System.out.println(obj1.age);

Student obj2 = new Student();


obj2.name = obj1.name;
obj2.age = obj1.age;

System.out.println(obj2.name);
System.out.println(obj2.age);

}
}

5. CONSTRUCTORS
A constructor is a special method in a class that is called automatically when an object of
the class is created. It is used to initialize the object’s instance variables or provide default
values. The name of the constructor is always the same as the class name, and it doesn’t
have a return type, not even void .

Why are Constructors Important?

Constructors ensure that objects start in a consistent state by initializing their instance
variables.
Without constructors, objects would need to be manually initialized using methods after
creation, which could lead to uninitialized or inconsistent data.
Example of a Simple Constructor:

public class Student


{
String name ;
int age ;

public Student()
{
this.name = "Raja";
this.age = 44 ;
}

Types of Constructors:

- Default Constructor:
If you do not provide any constructor, the compiler provides a default constructor that
initializes the object with default values (like null for strings, 0 for integers).

Example:

public class Student


{
String name ;
int age ;

public Student()
{
this.name = "Raja";
this.age = 44 ;
}

public void display()


{
System.out.println(name);
System.out.println(age);
}

public static void main(String[] args)


{
Student obj = new Student();
obj.display();
}
}

An object can be created with:

Student obj = new Student(); // Default constructor

- Parameterized Constructor:
A constructor that accepts parameters to initialize the object with specific values.

Example:

public class Student


{
String name ;
int age ;

public Student(String x , int y)


{
this.name = x;
this.age = y ;
}

public void display()


{
System.out.println(name);
System.out.println(age);
}

public static void main(String[] args)


{
Student obj = new Student("Siva" , 77);
obj.display();
}

OVERLOADED CONSTRUCTOR:
Constructor overloading allows you to create multiple constructors within a class, each
with different numbers or types of parameters. This provides flexibility in object creation, as
different constructors can handle different ways of initializing an object.
Purpose: Overloading constructors is useful when you want to provide multiple ways to
create an object based on different sets of input data.

Example of Constructor Overloading:

public class Student


{
String name ;
int age ;

public Student()
{
this.name = "Alice";
this.age = 10 ;
}

public Student(String x)
{
this.name = x;
this.age = 20 ;
}

public Student(String x , int y)


{
this.name = x ;
this.age = y ;
}

public void display()


{
System.out.println(name);
System.out.println(age);
}

public static void main(String[] args)


{
Student obj1 = new Student();
Student obj2 = new Student("Bob");
Student obj3 = new Student("Charlie",30);

obj1.display();
obj2.display();
obj3.display();

}
Advantages of Constructor Overloading:

Flexibility: Multiple constructors allow you to initialize objects in different ways without
the need for multiple class definitions.
Convenience: You can create objects with varying levels of data, allowing optional or
default values for certain attributes.

6. this KEYWORD
The this keyword in Java is a reference to the current object (the instance of the class
that is executing the code). It is commonly used to avoid ambiguity between class fields
(instance variables) and parameters with the same name.

Referring to Instance Variables: If a constructor or method parameter has the same


name as an instance variable, the this keyword is used to distinguish between them.

Example:

public class Car {


private String model;
private int year;

// Constructor with parameters having the same names as instance


variables
public Car(String model, int year) {
this.model = model; // 'this.model' refers to the instance variable
this.year = year; // 'this.year' refers to the instance variable
}
}

In this example, this.model refers to the instance variable model , while model (without
this ) refers to the parameter of the constructor. Without this , there would be ambiguity
between the parameter and the instance variable.

7. NESTED CLASS
In Java, nested classes are classes that are defined within another class. They provide a
way to logically group classes that are only used in one place, which can lead to more
readable and maintainable code. There are two main types of nested classes:

1. Static Nested Classes


2. Inner Classes
1.1 Static Nested Classes
A static nested class is a nested class that is declared with the static keyword. Since it's
static, it cannot directly access instance variables or methods of the outer class. Static
nested classes are often used when the nested class logically belongs to the outer class but
does not require access to its instance members.

Features of Static Nested Classes:


Can access static members of the outer class.
Cannot access non-static (instance) members of the outer class directly.
Can be instantiated without an instance of the outer class.

class Outer
{
String name = "Raja";
static int age = 55 ;

static class Inner


{
void display()
{
System.out.println(age);
}
}

public class Student


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

2 Inner Classes
An inner class is a non-static nested class that is associated with an instance of the outer
class. Inner classes can access both static and non-static members of the outer class,
including private ones.

Regular Inner Class


Local Inner Class
2.1 Regular Inner Class
A regular inner class is defined within another class but outside any method, and it has
access to all members (including private members) of the outer class.

class Outer
{
String name = "Raja";
static int age = 55 ;

class Inner
{
void display()
{
System.out.println(name);
System.out.println(age);
}
}

public class Student


{
public static void main(String[] args)
{
Outer obj1 = new Outer();
Outer.Inner obj2 = obj1.new Inner();
obj2.display();
}
}

2.2 Local Inner Class


A local inner class is defined within a block (like a method or a loop). It has access to all
members of the outer class and the local variables of the enclosing block, but those local
variables must be final or effectively final.

class Outer
{

void outermethod()
{
String name = "Raja";

class LocalInner
{
void display()
{
System.out.println(name);
}
}

LocalInner obj2 = new LocalInner();


obj2.display();

public class Student


{
public static void main(String[] args)
{
Outer obj1 = new Outer();
obj1.outermethod();
}
}

8. PASS BY VALUE AND PASS BY REFERENCE


In Java, understanding how parameters are passed to methods is crucial for managing data
and object interactions effectively. Java uses pass-by-value for all parameters, but the
specifics differ between primitive data types and object references.

1. Passing Arguments by Value


Definition: In Java, when you pass a variable to a method, you are actually passing a
copy of that variable's value. This means changes made to the parameter inside the
method do not affect the original variable outside the method.

Example with Primitive Data Type:

public class Student


{

static void change(int x)


{
x = 100 ;
System.out.println(x);
}
public static void main(String[] args)
{
int num = 55 ;
System.out.println(num);

change(num);
System.out.println(num);
}
}

2. Passing Arguments by Reference (Object


References)
Definition: While Java uses pass-by-value, when it comes to objects, it passes the
value of the reference (i.e., the memory address) to the object. Thus, if you modify the
object’s fields through the parameter, those changes will reflect on the original object.
However, if you change the reference itself to point to a new object, it will not affect the
original reference.

Example with Object Reference:

class Person
{
int num = 55 ;
}

public class Student


{

static void change(Person x)


{
x.num = 200 ;
System.out.println(x.num);
}

public static void main(String[] args)


{

Person obj = new Person();


System.out.println(obj.num);

change(obj);
System.out.println(obj.num);
}
}
9. ACCESS CONTROL FOR CLASS MEMBERS
In Java, access control modifiers determine the visibility and accessibility of class
members (variables and methods) from outside the class. This is a key part of
encapsulation, one of the fundamental principles of object-oriented programming (OOP),
where data is hidden and only accessible through well-defined interfaces.

The four types of access control modifiers in Java are:

1. public: Accessible from anywhere.


2. private: Accessible only within the same class.
3. protected: Accessible within the same package and subclasses.
4. default (package-private): Accessible only within the same package.

Access Modifiers in Detail

public: When a class member (variable or method) is declared as public , it can be


accessed from any other class. This modifier is typically used when you want other
parts of your program (or external programs) to use the class member without any
restrictions.

public class Car {


public String model;

public void start() {


System.out.println("Car started");
}
}

In this example, both the model variable and the start() method can be accessed
from any class.
private: When a class member is declared as private , it can only be accessed within
the class in which it is defined. This is the most restrictive access level and is often
used to enforce encapsulation and protect sensitive data from external modification.

public class Car {


private String model;

private void start() {


System.out.println("Car started");
}
}

In this case, model and start() cannot be accessed directly from outside the Car
class.
protected: A protected class member is accessible within the same package and by
subclasses of the class, even if they are in different packages. This modifier is useful
when you want to allow controlled access to inherited members in subclasses.

public class Car {


protected String model;

protected void start() {


System.out.println("Car started");
}
}

Here, model and start() can be accessed by subclasses or any class in the same
package.
default (no modifier): If no access modifier is specified, the member has default
(package-private) access. This means it can be accessed only within the same
package, but not from outside the package.

public class Car {


String model; // default access

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

Both model and start() are accessible to other classes within the same package but
not to classes in different packages.

10.METHODS IN JAVA
What are Methods?

A method is a block of code that performs a specific task and can be called upon
whenever needed. Methods help in organizing code, improving readability, and
facilitating code reusability.

Defining Methods
Method Signature:

The method signature consists of the method name and the parameter list. It uniquely
identifies the method within its class.
Return Types:

A method can return a value, indicated by its return type. If a method does not return
any value, its return type is void .

Parameters:

Parameters are the inputs to the method. They are defined within parentheses in the
method declaration. A method can have zero or more parameters.

Method Body:

The body of the method contains the code that defines what the method does,
enclosed within curly braces {} .

Example of Defining a Method:

class Calculator {
// Method to add two numbers (returns an integer)
public int add(int a, int b) {
return a + b; // Returns the sum of a and b
}

// Method to print a message (void method)


public void printMessage(String message) {
System.out.println(message);
}
}

public class Main {


public static void main(String[] args) {
Calculator calc = new Calculator();
int sum = calc.add(5, 3); // Calling the add method
System.out.println("Sum: " + sum); // Output: Sum: 8

calc.printMessage("Hello, World!"); // Calling the printMessage


method
// Output: Hello, World!
}
}

11. Class Objects as Parameters in Methods


Passing Class Objects as Parameters:

Methods can take objects of user-defined classes as parameters, allowing for


manipulation of the object's data within the method.
This is particularly useful for operations that require interacting with the state of an
object.

Example of Passing Objects as Parameters:

class Abc
{
String name = "Raja" ;
}

class Def
{
void display(Abc obj)
{
System.out.println(obj.name);
}
}

public class Student


{
public static void main(String[] args)
{

Abc obj1 = new Abc();

Def obj2 = new Def();


obj2.display(obj1);

Let's delve into access control in Java methods and the concept of recursive methods.
These are essential components of Java programming that help manage data encapsulation
and solve problems efficiently.

12. Access Control in methods


Access control in Java is managed through access modifiers, which define the visibility and
accessibility of classes, methods, and variables.

Access Modifiers:

1. Public:
The method is accessible from any other class in any package.
Use it for methods that need to be widely accessible.
public class MyClass {
public void myMethod() {
// Method implementation
}
}

2. Private:
The method is accessible only within its own class.
Use it to hide implementation details and protect sensitive data.

public class MyClass {


private void myMethod() {
// Method implementation
}
}

3. Protected:
The method is accessible within its own package and by subclasses (even if they
are in different packages).
Use it when you want to allow controlled access to subclasses.

public class MyClass {


protected void myMethod() {
// Method implementation
}
}

4. Default (Package-Private):
If no access modifier is specified, the method is accessible only within its own
package.
Use it for methods that should be accessible to other classes in the same package
but hidden from the outside world.

class MyClass { // No modifier means default access


void myMethod() {
// Method implementation
}
}

Example of Access Modifiers:


class Person {
private String name; // Private variable
protected int age; // Protected variable
public String city; // Public variable

public Person(String name, int age, String city) {


this.name = name;
this.age = age;
this.city = city;
}

// Public method to access private variable


public String getName() {
return name;
}

// Protected method
protected void display() {
System.out.println("Name: " + name + ", Age: " + age + ", City: " +
city);
}
}

public class Main {


public static void main(String[] args) {
Person person = new Person("Alice", 30, "New York");
System.out.println("Accessing public field: " + person.city); //
Accessible
System.out.println("Accessing private field: " + person.getName());
// Accessible via public method

// person.display(); // Not accessible from here since it's


protected
}
}

13. Recursive Methods


Definition:

A recursive method is a method that calls itself to solve a problem. It is often used to
solve problems that can be broken down into smaller, similar sub-problems.

Key Components of Recursion:

1. Base Case: The condition under which the recursion ends. It prevents infinite
recursion.
2. Recursive Case: The part of the method where the method calls itself with modified
arguments.

Example of a Recursive Method (Factorial Calculation):

public class Factorial {


// Recursive method to calculate factorial
public static int factorial(int n) {
// Base case: if n is 0 or 1, return 1
if (n <= 1) {
return 1;
}
// Recursive case: n * factorial of (n-1)
return n * factorial(n - 1);
}

public static void main(String[] args) {


int number = 5;
int result = factorial(number);
System.out.println("Factorial of " + number + " is: " + result); //
Output: 120
}
}

14. Nesting of Methods


Definition:

Method nesting refers to the practice of calling one method from another method within
the same class. This technique allows for better organization of code and can help
break complex tasks into simpler, reusable methods.

Practical Applications:

Code Reusability: You can call common functionalities in multiple methods without
repeating code.
Modularity: It helps in structuring your code, making it easier to understand and
maintain.
Clear Logic Flow: It allows for a clearer logical flow in your program by breaking down
operations into smaller, more manageable parts.

Example of Nesting Methods:

public class Student


{
int add(int a , int b , int c)
{
return a+b+c ;
}

void average(int a , int b , int c)


{
int sum = add(a,b,c);
System.out.println("Average is "+ (sum/3) );
}

public static void main(String[] args)


{
Student obj = new Student();
obj.average(21,37,67);

15. Final & Static


1. Final Attribute
The final keyword in Java is used to restrict inheritance or modification of classes,
methods, and variables. It is part of the language's mechanisms for ensuring immutability
and stability of code.

1.1 Final Classes


When a class is declared as final , it cannot be subclassed (i.e., no other class can extend
it). This is useful when you want to create an immutable class or prevent further modification
of the class’s behavior through inheritance.

Use cases for final classes:


Security: Prevents malicious or accidental overriding of methods that could
compromise the class’s functionality.
Performance: Final classes can be optimized by the JVM, as it knows the class
won’t be extended.

public final class FinalClass {


public void display() {
System.out.println("This is a final class.");
}
}

// The following class will cause a compilation error


// because FinalClass cannot be extended:
// public class SubClass extends FinalClass {}

In this example, FinalClass is declared as final , so no other class can extend it.

1.2 Final Methods


When a method is declared as final , it cannot be overridden by subclasses. This ensures
that the method’s implementation remains unchanged in any subclass, protecting important
logic.

Use cases for final methods:


When you want to prevent a subclass from altering the behavior of a specific
method, which could otherwise lead to unpredictable results.
To ensure that critical methods, such as security-related methods, remain
unmodified.

public class SuperClass {


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

public class SubClass extends SuperClass {


// The following method will cause a compilation error
// because display() is final and cannot be overridden:
// public void display() {}
}

Here, display() in the SuperClass is declared as final , so it cannot be overridden by


the SubClass .

1.3 Final Variables


A variable that is declared as final can only be assigned once. Once initialized, its value
cannot be changed. This is commonly used for defining constants.

public class MyClass {


final int MAX_VALUE = 100;

void display() {
System.out.println("MAX_VALUE: " + MAX_VALUE);
// MAX_VALUE = 200; // Compilation error
}
}
In this example, MAX_VALUE is a constant, and any attempt to reassign it will result in a
compilation error.

2. Static Attributes
The static keyword in Java is used to define class-level variables and methods that
belong to the class itself rather than to any specific instance. This means that static variables
and methods can be accessed without creating an instance of the class.

2.1 Static Variables:


A static variable is shared among all instances of a class. All objects share the same
copy of the variable.

Example of Static Variables:

class Counter {
static int count = 0; // Static variable

public Counter() {
count++; // Increment count for each object created
}

public static void displayCount() {


System.out.println("Total count of objects: " + count);
}
}

public class Main {


public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
Counter.displayCount(); // Output: Total count of objects: 2
}
}

2.2 Static Methods:


A static method can be called without an instance of the class. Static methods can
access static variables and other static methods, but they cannot access instance
variables or methods directly.

Example of Static Method:

class MathUtil {
// Static method to calculate square
public static int square(int number) {
return number * number;
}
}

public class Main {


public static void main(String[] args) {
int result = MathUtil.square(5); // Calling static method without
creating an object
System.out.println("Square of 5: " + result); // Output: Square of
5: 25
}
}

You might also like