OOPS IN JAVA PART 1
Notes Of Kunal Kushwaha Sir Java + DSA + Interview Preparation Course By Me
CLASS AND OBJECTS IN JAVA
Class:
- Think of a class like a blueprint or a plan for creating something.
- It defines what that something will be like, what it can do, and what information it can remember.
- For example, if you were designing a class for a "Car," you'd decide what a car should have (like color, model, and year) and what it can do (like start, accelerate, and brake).
- The class is like a template for creating specific instances or objects.
Object:
- An object is a specific thing created from a class blueprint.
- If a class is like a blueprint for a car, an object is a real, tangible car made from that blueprint.
- Objects have characteristics (like color, model, and year) and can perform actions (like starting and braking) based on what the class describes.
- Each object created from a class is unique, but it follows the general design specified by the class.
Example:
- Imagine you have a class called "Dog."
- The class defines that a dog can have attributes like "name," "breed," and "age."
- It also says that a dog can do things like "bark" and "fetch."
- Now, you can create specific dogs (objects) from this class, like a dog named Max, a dog of the Golden Retriever breed, and 3 years old.
- Each dog (object) you create will have its own unique values for these attributes but will follow the general design of the "Dog" class.
In summary, a class is like a blueprint or plan, describing what something should be and do. An object is a real thing created from that plan, with specific characteristics and abilities based on the class design.
package com.Akshaypratap;
import java.util.*;
// Define the Dog class
class Dog {
// Attributes
String name;
String breed;
int age;
// Constructor - a special method to initialize objects
public Dog(String name, String breed, int age) {
this.name = name;
this.breed = breed;
this.age = age;
}
// Method to make the dog bark
public void bark() {
System.out.println(name + " is barking: Woof! Woof!");
}
// Method to make the dog fetch
public void fetch() {
System.out.println(name + " is fetching the ball.");
}
}
// Main class to demonstrate the Dog class
public class Main {
public static void main(String[] args) {
// Create two Dog objects using the constructor
Dog dog1 = new Dog("Max", "Golden Retriever", 3);
Dog dog2 = new Dog("Bella", "Labrador", 2);
// Make the dogs perform actions
System.out.println("Dog 1 actions:");
dog1.bark();
dog1.fetch();
System.out.println("\nDog 2 actions:");
dog2.bark();
dog2.fetch();
}
}
OUTPUT:- Dog 1 actions:
Max is barking: Woof! Woof!
Max is fetching the ball.
Dog 2 actions:
Bella is barking: Woof! Woof!
Bella is fetching the ball.
package com.Akshaypratap;
import java.util.*;
// Define the Person class
class Person {
// Attributes
String name;
int age;
// Method to display information about the person
public void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
// Main class to demonstrate assigning values without a constructor
public class Main {
public static void main(String[] args) {
// Create a Person object
Person person1 = new Person();
// Assign values without using a constructor
person1.name = "John";
person1.age = 25;
// Display information about the person
person1.displayInfo();
}
}
OBJECTS (State , Identity, Behavior)
State of an Object:
Definition:
Example:
class Car {
String make;
String model;
int year;
String color;
// Other methods...
public void displayState() {
System.out.println("Car state: " + make + " " + model + " (" + year + "), Color: " + color);
}
}
// Creating a Car object
Car myCar = new Car();
myCar.make = "Toyota";
myCar.model = "Camry";
myCar.year = 2022;
myCar.color = "Silver";
// Displaying the state of the Car object
myCar.displayState(); // Output: Car state: Toyota Camry (2022), Color: Silver
Identity of an Object:
Definition:
Person person1 = new Person("John", 25);
Person person2 = new Person("Jane", 30);
System.out.println(person1); // Output: Person@1a2b3c4d (a unique identifier)
System.out.println(person2); // Output: Person@5e6f7g8h (another unique identifier)
Example:
Behavior of an Object:
Definition:
Example:
· class Person {
String name;
int age;
// Other attributes...
// Behavior: Display information about the person
public void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
}
// Behavior: Make the person work
public void work() {
System.out.println(name + " is working.");
}
}
// Creating a Person object
Person myPerson = new Person();
myPerson.name = "Alice";
myPerson.age = 28;
// Using behaviors of the Person object
myPerson.displayInfo(); // Output: Name: Alice, Age: 28
myPerson.work(); // Output: Alice is working
Constructor:
Definition:
- A constructor in Java is a special method that gets called when an object is created from a class.
- It is used to initialize the attributes or properties of the object.
- The name of the constructor is the same as the name of the class.
Purpose:
- Constructors ensure that when you create an object, it starts with a well-defined state.
Example:
class Person {
// Attributes
String name;
int age;
// Constructor
public Person(String newName, int newAge) {
name = newName;
age = newAge;
}
// Method to display information about the person
public void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
// Creating a Person object using the constructor
Person person1 = new Person("John", 25);
// Displaying information about the person
person1.displayInfo();
In this example, the Person class has a constructor that takes name and age as parameters and initializes the corresponding attributes. When we create a Person object (`person1`), we pass values to the constructor to set its initial state.
this Keyword:
Definition:
- The this keyword refers to the current instance of the object in which it is used.
- It is often used inside a class to refer to the instance variables of the class.
Purpose:
- this is used to distinguish between instance variables and parameters with the same name.
- It helps to avoid ambiguity and makes the code more readable.
Example:
class Person {
// Attributes
String name;
int age;
// Constructor with parameters having the same names as attributes
public Person(String name, int age) {
// Using 'this' to refer to the instance variables
this.name = name;
this.age = age;
}
// Method to display information about the person
public void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
// Creating a Person object using the constructor
Person person1 = new Person("John", 25);
// Displaying information about the person
person1.displayInfo();
In this example, the this keyword is used inside the constructor to explicitly refer to the instance variables (`this.name` and this.age). This helps to differentiate them from the parameters with the same names, making the code clear and unambiguous.
Recommended by LinkedIn
In summary, constructors initialize object attributes, ensuring a well-defined initial state. The this keyword is used to refer to the current instance of the object and helps avoid naming conflicts between instance variables and parameters.
This Keyword Importance AND ITS USE
// Importing the java.util package (though currently not used)
package com.Akshaypratap;
import java.util.*;
// Class representing an Example
class Example {
// Instance variable to store the value of x, initialized to 0
int x = 0;
// Constructor with a parameter having the same name as the instance variable
public Example(int x) {
// Using 'this' to refer to the instance variable and set its value
this.x = x;
}
// Another constructor with two parameters (x and y)
public Example(int x, int y) {
x=x;
// Here, 'x = x;' is incorrect, as it doesn't update the instance variable x
// Instead, it creates a local variable 'x' which shadows the instance variable
}
// Method to display the value of x
public void displayX() {
// Printing the value of the instance variable x
System.out.println("Value of x: " + x);
}
}
// Main class to demonstrate the Example class
public class Main {
public static void main(String[] args) {
// Creating an Example object with two parameters (20 and 80)
Example obj1 = new Example(20, 80);
// Displaying the value of x for obj1
obj1.displayX(); // Output: Value of x: 0 (since the constructor with two parameters doesn't update x)
// Creating another Example object with one parameter (20)
Example obj2 = new Example(20);
// Displaying the value of x for obj2
obj2.displayX(); // Output: Value of x: 20
}
}
Explanation:
1. Constructor Overloading:
- The Example class has two constructors: one that takes one parameter (`public Example(int x)`) and another that takes two parameters (`public Example(int x, int y)`).
2. Constructor with Two Parameters:
- In the constructor public Example(int x, int y), you are using x = x; to assign the value of the parameter x to itself. However, this does not affect the instance variable x; instead, it creates a local variable x within the scope of the constructor.
3. Display Method Output:
- When you create obj1 using Example obj1 = new Example(20, 80);, it uses the constructor with two parameters.
- The displayX() method prints the value of the instance variable x, which was not modified by the constructor with two parameters. Hence, the output is Value of x: 0.
4. Constructor with One Parameter:
- When you create obj2 using Example obj2 = new Example(20);, it uses the constructor with one parameter. This constructor correctly assigns the parameter value to the instance variable using this.x = x;.
5. Display Method for obj2:
- The displayX() method for obj2 prints the value of the instance variable x, which was set to 20. Hence, the output is Value of x: 20.
Importance of the this Keyword:
- In the constructor public Example(int x, int y), using x = x; without this creates a local variable x that shadows the instance variable x. This can lead to confusion and unexpected behavior.
- Using the this keyword (`this.x = x;`) explicitly refers to the instance variable x, ensuring that the correct variable is updated.
Corrected Constructor:
public Example(int x, int y) {
// Using 'this' to refer to the instance variable
this.x = x;
}
### Updated Output:
Value of x: 20
Value of x: 20
In summary, the corrected use of the this keyword ensures that the instance variable is correctly updated, avoiding confusion with local variables.
Pass an object of the same class as an argument to its own constructor
You can pass an object of the same class as an argument to its own constructor. This is often referred to as a copy constructor. Here's an example:
class Person {
String name;
int age;
// Constructor to initialize a Person object with name and age
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Copy constructor to create a new Person object based on an existing Person object
public Person(Person originalPerson) {
this.name = originalPerson.name;
this.age = originalPerson.age;
}
// Method to display person details
public void displayPersonDetails() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
public class Main {
public static void main(String[] args) {
// Creating a Person object
Person person1 = new Person("John", 25);
// Creating another Person object by passing the first Person object
Person person2 = new Person(person1);
// Displaying details of both Person objects
System.out.println("Person 1 Details:");
person1.displayPersonDetails();
System.out.println("\nPerson 2 Details (created using copy constructor):");
person2.displayPersonDetails();
}
}
In this example, the Person class has a copy constructor that takes another Person object as a parameter. This copy constructor initializes a new Person object using the details of the existing Person object.
When you run this program, it will output:
Person 1 Details:
Name: John
Age: 25
Person 2 Details (created using copy constructor):
Name: John
Age: 25
This demonstrates how you can create a new object of the same class by passing an existing object of that class to the constructor.
Calling one constructor from another constructor
In Java, you can call one constructor from another constructor within the same class using the this keyword. This is known as constructor chaining. Here's an example:
class Example {
int x;
int y;
// Default constructor
public Example() {
// Calling another constructor with specific values
this(0, 0);
}
// Constructor with two parameters
public Example(int x, int y) {
this.x = x;
this.y = y;
}
// Method to display the values of x and y
public void displayValues() {
System.out.println("x: " + x);
System.out.println("y: " + y);
}
}
public class Main {
public static void main(String[] args) {
// Creating an Example object using the default constructor
Example obj1 = new Example();
// Creating another Example object using the parameterized constructor
Example obj2 = new Example(10, 20);
// Displaying values for both objects
System.out.println("Values for obj1:");
obj1.displayValues();
System.out.println("\nValues for obj2:");
obj2.displayValues();
}
}
In this example, the default constructor public Example() calls another constructor this(0, 0), effectively initializing x and y with default values. The second constructor public Example(int x, int y) initializes the instance variables with the provided values.
When you run this program, it will output:
Values for obj1:
x: 0
y: 0
Values for obj2:
x: 10
y: 20
This demonstrates how one constructor can invoke another constructor in the same class using the this keyword, providing a way to reuse initialization logic.
Why primitives are not created using the new keyword
In Java, primitives are not created using the new keyword because they are not objects. Primitives are basic data types (like int, char, boolean, etc.), and they do not have the characteristics of objects, such as methods or additional properties. Instead, they are simple, atomic data types that directly store values.
Memory Allocation for Primitives:
When it comes to memory allocation for primitives in Java, they are typically stored in the stack or within the method's stack frame. The stack is a region of memory that is used for local variables and method call information. Each thread running in a Java program has its own stack.
Stack Memory:
- Primitives are often stored in the stack memory because they are simple, and their values can be directly stored in a fixed amount of memory.
- Stack memory is fast and efficient, and it allows for quick allocation and deallocation of memory.
- When a method is called, a new stack frame is created, and local variables (including primitives) are allocated within that frame. When the method execution is complete, the stack frame is popped, and the memory is freed.
Heap Memory:
- The heap memory is used for dynamic memory allocation and is primarily associated with objects.
- Objects (which can include reference types like arrays or instances of classes) are stored in the heap because their size and lifetime are not fixed at compile time.
- Primitives do not involve the same dynamic allocation characteristics as objects, and thus, they are typically stored on the stack for efficiency.
Example:
Let's consider an example to illustrate the concept:
public class PrimitiveExample {
public static void main(String[] args) {
// Primitives stored in stack memory
int age = 25;
char grade = 'A';
boolean isStudent = true;
// Output the values
System.out.println("Age: " + age);
System.out.println("Grade: " + grade);
System.out.println("Is Student: " + isStudent);
}
}
In this example, variables age, grade, and isStudent are primitive types (`int`, char, and boolean, respectively). These variables are stored in the stack memory, and their values are directly assigned and retrieved.
In summary, primitives in Java are not created using new because they are not objects. They are typically stored in the stack memory due to their simplicity and fixed size, and they do not involve dynamic allocation like objects stored in the heap.