core_java_unit_II

Classes, Objects and Methods

2.1 Class and Object

Class

A class in Java is a blueprint for creating objects. It defines a type by bundling data and methods that operate on that data into a single unit. A class can contain fields (variables) and methods (functions) to define the behavior of an object.

Syntax for defining a class:

public class ClassName {

// Fields (variables)

private int field1;

private String field2;


// Constructor

public ClassName(int field1, String field2) {

this.field1 = field1;

this.field2 = field2;

}


// Methods

public void display() {

System.out.println("Field1: " + field1);

System.out.println("Field2: " + field2);

}


// Getter and Setter methods

public int getField1() {

return field1;

}


public void setField1(int field1) {

this.field1 = field1;

}


public String getField2() {

return field2;

}


public void setField2(String field2) {

this.field2 = field2;

}

}

Object

An object is an instance of a class. It is created from a class and can access the class's fields and methods. Each object has its own state (values of fields) and behavior (methods).



Syntax for creating an object:

ClassName objectName = new ClassName(field1Value, field2Value);

Example:

public class Main {

public static void main(String[] args) {

// Creating an object of the class

ClassName obj = new ClassName(10, "Hello");


// Accessing the object's fields and methods

obj.display();


// Using getter and setter methods

obj.setField1(20);

System.out.println("Updated Field1: " + obj.getField1());

}

}

Detailed Example

Let's consider a more detailed example to illustrate the concepts of class and object in Java.

Defining a Person class:

public class Person {

// Fields

private String name;

private int age;


// Constructor

public Person(String name, int age) {

this.name = name;

this.age = age;

}


public void displayInfo() {

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

System.out.println("Age: " + age);

}


public String getName() {

return name;

}


public void setName(String name) {

this.name = name;

}


public int getAge() {

return age;

}


public void setAge(int age) {

this.age = age;

}

}

Creating and using Person objects:

public class Main {

public static void main(String[] args) {

// Creating objects of the Person class

Person person1 = new Person("Alice", 30);

Person person2 = new Person("Bob", 25);


// Displaying information about person1

person1.displayInfo();

// Displaying information about person2

person2.displayInfo();


// Updating and displaying information about person1

person1.setName("Alice Smith");

person1.setAge(31);

System.out.println("Updated Info for person1:");

person1.displayInfo();

}

}

In this example:

  1. We define a Person class with fields name and age, a constructor to initialize these fields, and methods to display, get, and set these fields.

  2. We create two objects of the Person class (person1 and person2).

  3. We call the displayInfo method on both objects to print their details.

  4. We update the name and age of person1 using setter methods and then display the updated information.

Summary

  • Class: A blueprint for creating objects. It defines fields and methods to represent the state and behavior of an object.

  • Object: An instance of a class. It has its own state and can perform actions defined by its class's methods.



2.2 Object reference

In Java, when you create an object, you are actually creating a reference to that object. This reference is a variable that stores the memory address of the object, allowing you to access and manipulate the object.

Understanding Object References

Creating an Object and a Reference:

When you create an object using the new keyword, the object is stored in the heap memory, and the reference variable holds the address of the object in the heap.

Example:

Person person1 = new Person("Alice", 30);

Here:

  • new Person("Alice", 30) creates a new Person object in the heap.

  • person1 is a reference variable that stores the memory address of the Person object.

Copying References:

When you assign one reference variable to another, both variables point to the same object.

Example:

Person person2 = person1;

Now, person1 and person2 both refer to the same Person object. Any changes made through one reference will be visible through the other.

Null References:

A reference variable that does not refer to any object is called a null reference.

Example:

Person person3 = null;

Attempting to access an object's members through a null reference will result in a NullPointerException.

Example Demonstration:

Let's demonstrate the concepts of object references with a detailed example:

public class Person {

private String name;

private int age;


public Person(String name, int age) {

this.name = name;

this.age = age;

}


public void displayInfo() {

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

System.out.println("Age: " + age);

}


public void setName(String name) {

this.name = name;

}


public void setAge(int age) {

this.age = age;

}


public static void main(String[] args) {

// Creating a Person object and a reference

Person person1 = new Person("Alice", 30);

person1.displayInfo();


// Creating another reference to the same object

Person person2 = person1;

System.out.println("\nReference person2 points to the same object as person1:");

person2.displayInfo();


// Modifying the object through person2 reference

person2.setName("Alice Smith");

person2.setAge(31);


System.out.println("\nAfter modifying through person2 reference:");

System.out.println("person1 details:");

person1.displayInfo();

System.out.println("person2 details:");

person2.displayInfo();


// Creating a null reference

Person person3 = null;


// Checking if the reference is null before accessing it

if (person3 != null) {

person3.displayInfo();

} else {

System.out.println("\nperson3 is null, cannot access its members.");

}


// Creating a new object and making person3 reference to it

person3 = new Person("Bob", 25);

System.out.println("\nperson3 now refers to a new object:");

person3.displayInfo();

}

}



Output:

Name: Alice

Age: 30


Reference person2 points to the same object as person1:

Name: Alice

Age: 30


After modifying through person2 reference:

person1 details:

Name: Alice Smith

Age: 31

person2 details:

Name: Alice Smith

Age: 31


person3 is null, cannot access its members.


person3 now refers to a new object:

Name: Bob

Age: 25

Key Points

  1. Object Creation: Person person1 = new Person("Alice", 30); creates a new Person object and a reference variable person1 that refers to it.

  2. Reference Assignment: Person person2 = person1; assigns the reference of person1 to person2, making both references point to the same object.

  3. Modifying Through References: Changes made to the object through person2 are reflected when accessed through person1 because they refer to the same object.

  4. Null References: A reference variable can be assigned null to indicate that it does not refer to any object.

  5. Null Check: Always check if a reference is null before accessing its members to avoid NullPointerException.

  6. New Object Assignment: person3 = new Person("Bob", 25); creates a new Person object and assigns its reference to person3.

Understanding object references is crucial for managing memory, object manipulation, and avoiding common pitfalls such as NullPointerException in Java programming



2.3 Constructor:

Constructor Overloading in Java

Constructor overloading in Java allows a class to have more than one constructor with different parameter lists. This enables objects of the class to be initialized in different ways, providing flexibility and enhancing the readability of the code.

Key Concepts

  1. Multiple Constructors: A class can have multiple constructors, each with a unique signature (parameter list).

  2. Initialization Logic: Each constructor can have different initialization logic, allowing for various ways to instantiate objects.

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

Example of Constructor Overloading

Let's illustrate constructor overloading with a detailed example using a Person class.

Person Class with Overloaded Constructors:

public class Person {

private String name;

private int age;

private String address;


// Constructor with two parameters

public Person(String name, int age) {

this.name = name;

this.age = age;

}


// Overloaded constructor with three parameters

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

this.name = name;

this.age = age;

this.address = address;

}


// Overloaded constructor with no parameters (default constructor)

public Person() {

this.name = "Unknown";

this.age = 0;

this.address = "Not specified";

}


// Method to display person information

public void displayInfo() {

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

System.out.println("Age: " + age);

System.out.println("Address: " + address);

}


public static void main(String[] args) {

// Using constructor with two parameters

Person person1 = new Person("Alice", 30);

person1.displayInfo();


System.out.println();


// Using constructor with three parameters

Person person2 = new Person("Bob", 25, "123 Main St");

person2.displayInfo();


System.out.println();


// Using default constructor

Person person3 = new Person();

person3.displayInfo();

}

}

Output:

Name: Alice

Age: 30

Address: null


Name: Bob

Age: 25

Address: 123 Main St


Name: Unknown

Age: 0

Address: Not specified

Detailed Explanation

  1. Constructor with Two Parameters:

public Person(String name, int age) {

this.name = name;

this.age = age;

}

This constructor initializes the name and age fields, leaving the address field as null.

  1. Constructor with Three Parameters:

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

this.name = name;

this.age = age;

this.address = address;

}

This constructor initializes all three fields: name, age, and address.

  1. Default Constructor:

public Person() {

this.name = "Unknown";

this.age = 0;

this.address = "Not specified";

}

This no-argument constructor initializes the fields with default values, providing a fallback option for creating Person objects.

Additional Example: Book Class

Here is another example demonstrating constructor overloading with a Book class.

public class Book {

private String title;

private String author;

private double price;


// Constructor with two parameters

public Book(String title, String author) {

this.title = title;

this.author = author;

this.price = 0.0; // Default price

}


// Overloaded constructor with three parameters

public Book(String title, String author, double price) {

this.title = title;

this.author = author;

this.price = price;

}


// Overloaded constructor with no parameters (default constructor)

public Book() {

this.title = "Untitled";

this.author = "Unknown";

this.price = 0.0;

}


// Method to display book information

public void displayInfo() {

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

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

System.out.println("Price: $" + price);

}


public static void main(String[] args) {

// Using constructor with two parameters

Book book1 = new Book("1984", "George Orwell");

book1.displayInfo();


System.out.println();


// Using constructor with three parameters

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

book2.displayInfo();


System.out.println();


// Using default constructor

Book book3 = new Book();

book3.displayInfo();

}

}

Output:

Title: 1984

Author: George Orwell

Price: $0.0


Title: To Kill a Mockingbird

Author: Harper Lee

Price: $15.99


Title: Untitled

Author: Unknown

Price: $0.0

Summary

  • Constructor Overloading: Allows a class to have multiple constructors with different parameter lists, providing different ways to initialize objects.

  • Default Constructor: A no-argument constructor that initializes fields with default values.

  • Flexibility: Overloaded constructors enable more flexible and readable code by allowing objects to be created with different initial states.

2.4 Methods in Java

Methods in Java are blocks of code that perform a specific task and are defined within a class. They can take parameters, perform operations, and return a value or void (no value).

Method Overloading

Method overloading is a feature that allows a class to have more than one method with the same name, but different parameter lists (different type, number, or both). This allows methods to perform similar tasks with different inputs.

Example of Method Overloading:

java

Copy code

public class MathOperations {


// Method to add two integers

public int add(int a, int b) {

return a + b;

}


// Overloaded method to add three integers

public int add(int a, int b, int c) {

return a + b + c;

}


// Overloaded method to add two double values

public double add(double a, double b) {

return a + b;

}


public static void main(String[] args) {

MathOperations math = new MathOperations();


System.out.println("Sum of 2 and 3: " + math.add(2, 3));

System.out.println("Sum of 2, 3, and 4: " + math.add(2, 3, 4));

System.out.println("Sum of 2.5 and 3.5: " + math.add(2.5, 3.5));

}

}

Output:

Sum of 2 and 3: 5

Sum of 2, 3, and 4: 9

Sum of 2.5 and 3.5: 6.0

Recursion

Recursion is a programming technique where a method calls itself to solve a problem. Each recursive call should bring the problem closer to a base case that can be solved without further recursion.

Example of Recursion:

public class RecursionExample {


// Method to calculate factorial of a number

public int factorial(int n) {

if (n == 0) { // Base case

return 1;

} else {

return n * factorial(n - 1); // Recursive call

}

}


public static void main(String[] args) {

RecursionExample example = new RecursionExample();

int number = 5;

System.out.println("Factorial of " + number + " is: " + example.factorial(number));

}

}

Output:

Factorial of 5 is: 120

Passing and Returning Objects from Methods

In Java, methods can take objects as parameters and can also return objects.

Passing Objects to Methods: When an object is passed to a method, the reference to the object is passed, not the actual object. Therefore, any changes made to the object within the method affect the original object.

Returning Objects from Methods: A method can return an object, which allows complex data structures and objects to be manipulated and returned.

Example:

public class Person {

private String name;

private int age;


public Person(String name, int age) {

this.name = name;

this.age = age;

}


public void displayInfo() {

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

System.out.println("Age: " + age);

}


// Method to update person details

public void updateDetails(String name, int age) {

this.name = name;

this.age = age;

}


// Static method to create a new Person object

public static Person createPerson(String name, int age) {

return new Person(name, age);

}


public static void main(String[] args) {

// Creating an object and passing it to a method

Person person = new Person("Alice", 30);

person.displayInfo();


System.out.println("\nUpdating person details:");

person.updateDetails("Alice Smith", 31);

person.displayInfo();


System.out.println("\nCreating a new person:");

Person newPerson = Person.createPerson("Bob", 25);

newPerson.displayInfo();

}

}

Output:

Name: Alice

Age: 30


Updating person details:

Name: Alice Smith

Age: 31


Creating a new person:

Name: Bob

Age: 25

Key Points

  1. Method Overloading: Allows methods with the same name but different parameters to coexist in a class, enabling methods to handle different types or numbers of inputs.

  2. Recursion: A method that calls itself to solve a problem. It requires a base case to terminate the recursive calls.

  3. Passing Objects to Methods: When an object is passed to a method, the reference to the object is passed, allowing the method to modify the original object.

  4. Returning Objects from Methods: Methods can return objects, facilitating complex data manipulations and the creation of new objects within methods.



2.5 New Operator

The new operator in Java is used to create new objects. It allocates memory for the object on the heap and returns a reference to that memory location.

Syntax:

ClassName objectName = new ClassName(parameters);

Example:

public class Person {

private String name;

private int age;


// Constructor

public Person(String name, int age) {

this.name = name;

this.age = age;

}


public void displayInfo() {

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

System.out.println("Age: " + age);

}


public static void main(String[] args) {

// Using the new operator to create an object

Person person = new Person("Alice", 30);

person.displayInfo();

}

}

Output:

Name: Alice

Age: 30

this Keyword

The this keyword in Java is a reference to the current object. It is used to avoid naming conflicts and to pass the current object as a parameter to other methods or constructors.

Common Uses of this:

  1. To refer to the current object's instance variables.

  2. To call the current object's methods.

  3. To call another constructor in the same class.

Example:

public class Person {

private String name;

private int age;


// Constructor

public Person(String name, int age) {

this.name = name; // 'this' refers to the current object's instance variable

this.age = age;

}


public void setName(String name) {

this.name = name;

}


public void displayInfo() {

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

System.out.println("Age: " + this.age);

}


public static void main(String[] args) {

Person person = new Person("Alice", 30);

person.displayInfo();

}

}

Output:

Name: Alice

Age: 30

static Keyword

The static keyword in Java is used to indicate that a member (variable, method, or block) belongs to the class itself rather than to instances of the class. Static members are shared among all instances of the class.

Common Uses of static:

  1. To define class-level variables and methods.

  2. To create utility or helper methods that do not require an object to be called.

  3. To access static members without creating an instance of the class.

Example:

public class MathUtils {

// Static variable

public static final double PI = 3.14159;


// Static method

public static double square(double number) {

return number * number;

}


public static void main(String[] args) {

// Accessing static variable and method without creating an instance

System.out.println("PI: " + MathUtils.PI);

System.out.println("Square of 5: " + MathUtils.square(5));

}

}

Output:

PI: 3.14159

Square of 5: 25.0

finalize() Method

The finalize() method in Java is called by the garbage collector before an object is destroyed. This method is intended to perform cleanup operations, such as releasing resources or closing connections. However, its use is generally discouraged in favor of using try-with-resources or explicit resource management techniques.

Syntax:

@Override

protected void finalize() throws Throwable {

// Cleanup code

}

Example:

public class Resource {

// Constructor

public Resource() {

System.out.println("Resource created.");

}


// finalize method

@Override

protected void finalize() throws Throwable {

System.out.println("Resource is being cleaned up.");

super.finalize();

}


public static void main(String[] args) {

Resource res = new Resource();

res = null; // Make the resource eligible for garbage collection


// Request garbage collection

System.gc();

}

}

Output:

Resource created.

Resource is being cleaned up.

Note: The output may vary as the invocation of the finalize method is not guaranteed to happen immediately.

Summary

  1. New Operator: Used to create new objects and allocate memory on the heap.

  2. this Keyword: Refers to the current object instance, resolving variable naming conflicts and passing the current object as a parameter.

  3. static Keyword: Indicates class-level members that are shared among all instances of the class.

  4. finalize() Method: Called by the garbage collector before an object is destroyed for cleanup operations, though its use is discouraged in favor of more reliable resource management techniques.

These concepts are fundamental in Java programming, helping manage memory, resolve naming conflicts, and define class-level behavior.



2.6 Nested Classes in Java

Nested classes are classes defined within another class. Java supports several types of nested classes: static nested classes, inner classes, local inner classes, and anonymous inner classes.

Static Nested Class

A static nested class is a static class defined within another class. It does not have access to the instance variables and methods of the outer class but can access its static members.

Example:

public class OuterClass {

static int outerStaticVar = 10;


// Static nested class

static class StaticNestedClass {

void display() {

System.out.println("Outer static variable: " + outerStaticVar);

}

}


public static void main(String[] args) {

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

nested.display();

}

}

Output:

Outer static variable: 10

Inner Class

An inner class is a non-static class defined within another class. Inner classes can access all members (including private members) of the outer class.

Example:

public class OuterClass {

private int outerVar = 20;


// Inner class

class InnerClass {

void display() {

System.out.println("Outer variable: " + outerVar);

}

}


public static void main(String[] args) {

OuterClass outer = new OuterClass();

OuterClass.InnerClass inner = outer.new InnerClass();

inner.display();

}

}

Output:

Outer variable: 20

Local Inner Class

A local inner class is a class defined within a method of the outer class. It has access to the local variables of the method if they are final or effectively final.

Example:

java

Copy code

public class OuterClass {

void display() {

int localVar = 30;


// Local inner class

class LocalInnerClass {

void print() {

System.out.println("Local variable: " + localVar);

}

}


LocalInnerClass localInner = new LocalInnerClass();

localInner.print();

}


public static void main(String[] args) {

OuterClass outer = new OuterClass();

outer.display();

}

}

Output:

Local variable: 30

Anonymous Inner Class

An anonymous inner class is a class without a name that is both declared and instantiated in a single statement. It is typically used to create a one-time use implementation of an interface or subclass.

Example with Interface:

interface Greeting {

void greet();

}


public class TestAnonymousInnerClass {

public static void main(String[] args) {

Greeting greeting = new Greeting() { // Anonymous inner class

@Override

public void greet() {

System.out.println("Hello, world!");

}

};


greeting.greet();

}

}

Output:

Hello, world!

Example with Class:

java

Copy code

abstract class Animal {

abstract void makeSound();

}


public class TestAnonymousInnerClass {

public static void main(String[] args) {

Animal dog = new Animal() { // Anonymous inner class

@Override

void makeSound() {

System.out.println("Woof woof");

}

};


dog.makeSound();

}

}

Output:

Woof woof

Summary

  1. Static Nested Class: A static class within another class. It can access static members of the outer class.

  2. Inner Class: A non-static class within another class. It has access to all members of the outer class.

  3. Local Inner Class: A class defined within a method. It can access the method's final or effectively final local variables.

  4. Anonymous Inner Class: A class without a name, instantiated and declared in a single statement. It is often used for one-time use implementations of interfaces or abstract classes



No comments:

Post a Comment