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:
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.
We create two objects of the Person class (person1 and person2).
We call the displayInfo method on both objects to print their details.
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
Object Creation: Person person1 = new Person("Alice", 30); creates a new Person object and a reference variable person1 that refers to it.
Reference Assignment: Person person2 = person1; assigns the reference of person1 to person2, making both references point to the same object.
Modifying Through References: Changes made to the object through person2 are reflected when accessed through person1 because they refer to the same object.
Null References: A reference variable can be assigned null to indicate that it does not refer to any object.
Null Check: Always check if a reference is null before accessing its members to avoid NullPointerException.
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
Multiple Constructors: A class can have multiple constructors, each with a unique signature (parameter list).
Initialization Logic: Each constructor can have different initialization logic, allowing for various ways to instantiate objects.
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
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.
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.
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
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.
Recursion: A method that calls itself to solve a problem. It requires a base case to terminate the recursive calls.
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.
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:
To refer to the current object's instance variables.
To call the current object's methods.
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:
To define class-level variables and methods.
To create utility or helper methods that do not require an object to be called.
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
New Operator: Used to create new objects and allocate memory on the heap.
this Keyword: Refers to the current object instance, resolving variable naming conflicts and passing the current object as a parameter.
static Keyword: Indicates class-level members that are shared among all instances of the class.
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
Static Nested Class: A static class within another class. It can access static members of the outer class.
Inner Class: A non-static class within another class. It has access to all members of the outer class.
Local Inner Class: A class defined within a method. It can access the method's final or effectively final local variables.
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