Advance OOP With JAVA.
Advance OOP With JAVA.
Object
An object is an instance of a class. When a class is defined, no memory is
allocated until an object of that class is created. Objects are created using
the new keyword.
Example
In this example:
Dog is a simple class with one field (name) and one method (bark).
In the Main class, we create an instance of the Dog class called
myDog.
We set the name field of myDog to "Buddy" and call the bark method
on myDog, which prints "Woof!" to the console.
Polymorphism in JAVA?
Polymorphism means "many forms", and it occurs when we have many classes
that are related to each other by inheritance.
Abstraction in JAVA?
Data abstraction is the process of hiding certain details and showing only
essential information to the user.
The abstract keyword is a non-access modifier, used for classes and methods:
Abstract class: is a restricted class that cannot be used to create objects
(to access it, it must be inherited from another class).
Abstract method: can only be used in an abstract class, and it does not
have a body. The body is provided by the subclass (inherited from).
In this example:
We have an abstract class Animal with an abstract method
makeSound().
We have a concrete class Dog that extends the Animal class and
provides an implementation for the makeSound() method.
In the Main class, we create an object of the Dog class but store it in a
reference of type Animal.
We call the makeSound() method on the Animal reference without
knowing the specific implementation of the Dog class. This
demonstrates abstraction, where we focus on the behavior of an object
(i.e., making a sound) rather than the details of how it is implemented.
Access Modifiers
In Java, access modifiers are keywords used in object-oriented programming
to set the access level for classes, variables, methods, and constructors.
They are the primary means of enforcing encapsulation, a fundamental
concept of OOP that restricts direct access to some of the object’s
components.
This not only helps safeguard the object's internal state but also improves
maintainability and reduces the risk of errors in code.
1. private
The private access modifier is the most restrictive level of access control.
When a member (be it a field, method, or constructor) is declared private, it
can only be accessed within the same class.
No other class, including subclasses in the same package or different
packages, can access the member.
This modifier is typically used for sensitive data that should be hidden from
external classes.
Example:
public class Person {
return this.name;
In this example, the name attribute and the getName() method are only
accessible within the Person class.
void display() {
In this example, the Log class and its method display() are accessible only
within classes defined in the same package.
3. protected
The protected access modifier is less restrictive than private and default.
Members declared as protected can be accessed within the same package or
in subclasses in different packages.
This is particularly useful in cases where you want to hide a member from
the world but still make it available to child classes.
Example:
public class Animal {
}
}
Here, the type attribute and the displayType() method can be accessed
within all classes in the same package and in any subclass of Animal, even if
those subclasses are in different packages.
4. public
The public access modifier is the least restrictive and specifies that the
member can be accessed from any other class anywhere, whether within or
in a different package.
This access level is typically used for methods and variables that must be
available consistently to all other classes.
Example:
public class Calculator {
In this example, the add() method of the Calculator class can be accessed by
any other class.
3. With a string
StringBuffer Methods
Method Description
insert(int offset, It is used to insert the specified string with this string
String s) at the specified position. The insert() method is
overloaded like insert(int, char), insert(int, boolean),
insert(int, int), insert(int, float), insert(int, double) etc.
3 Here the length of the string class is Here the length can be modified whenever
static. required, as it is dynamic in behaviour.
5 It utilises a string constant pool to It prefers heap memory to store the objects.
store the values.
Defining an Enum
An enum in Java is defined using the enum keyword. Here’s a basic example:
In this example, Day is an enum that contains the days of the week as its
constants.
Using an Enum
You can use an enum just like any other type in Java. Here’s how you can use
the Day enum defined above:
Thread
Imagine you're making a delicious breakfast. Threads are like the different
tasks you can do at the same time:
• One thread (you) is making coffee: You boil water, add coffee
grounds, and pour it into a mug. This represents a single task within the
thread.
• Another thread (you again!) is scrambling eggs: You whisk eggs,
heat them in a pan, and season them. This is another task within the same
thread (you) but happening concurrently with making coffee.
• Maybe a third thread (your sibling) is toasting bread: They put
bread in the toaster, wait for it to pop, and butter it. This is a separate thread
(your sibling) working on their own task.
Key points from this example:
• You (the program) can handle multiple tasks (threads) at once, just
like making breakfast.
• Each thread can perform its own independent actions (making coffee,
scrambling eggs).
• Threads can sometimes share resources (like the kitchen space) but need
to be careful not to interfere with each other (e.g., accidentally knocking
over the coffee while grabbing toast).
This is a simplified analogy, but it captures the essence of threads in Java:
allowing your program to manage seemingly simultaneous tasks for
improved efficiency and responsiveness.
Threads in Java
Threads are a fundamental concept in Java that enable a program to perform
multiple tasks apparently simultaneously. They represent a lightweight unit
of execution within a process. Unlike traditional processes that are
heavyweight and resource-intensive, threads share the same memory space
of the process, making them efficient for multitasking within a program.
Why Use Threads?
• Improved Responsiveness: By utilizing threads, your program can
remain responsive to user interaction even while executing long-running
tasks in the background. The main thread, responsible for handling user
interface elements, wouldn't be blocked by a time-consuming operation
running in another thread.
• Increased Efficiency: Threads allow you to leverage multi-core
processors effectively. By distributing tasks across multiple threads, you
can significantly improve the performance of your program, especially for
CPU-bound operations.
• Background Operations: Threads are well-suited for executing tasks
in the background without hindering the main program's flow. This can be
beneficial for activities like downloading files, network communication, or
playing music.
In both approaches, once you have your thread class or a class implementing
Runnable, you can create a Threadobject and call its start()method to initiate
thread execution. The run() method will be invoked automatically by the Java
Virtual Machine (JVM) in a separate thread of control.
Thread States
A thread in Java can exist in various states throughout its lifecycle:
• New: The initial state when a thread object is created.
• Runnable: The thread is ready to be scheduled for execution by
the JVM.
• Running: The thread is currently executing code.
• Waiting: The thread is waiting for a specific event to occur
before proceeding, such as waiting for user input or for another
thread to finish a task.
• Blocked: The thread is temporarily suspended due to
external factors like I/O operations or resource contention.
• Terminated: The thread has finished execution and its
resources have been released.
Thread Synchronization
When multiple threads access shared resources within a program, it's crucial
to ensure data consistency. This is achieved through thread synchronization
mechanisms like synchronized methods or blocks. Synchronization
guarantees that only one thread can access a particular code section or
resource at a time, preventing race conditions and data corruption.
Example: Thread Implementation
Here's a comprehensive example demonstrating both approaches for
creating threads in Java: Java
As you can see, the main thread continues executing while the other two
threads print their messages concurrently.
Remember, threads are a powerful concept, but improper use can lead to
complex debugging challenges. It's essential to understand synchronization
mechanisms and utilize best practices when working with threads in your
Java applications.
Method Overloading
Overloading occurs when two or more methods in the same class have the
same name but different parameters (different type or number of
parameters). It allows a class to have more than one method with the same
name but different implementations.
Method Overriding
Overriding occurs when a subclass provides a specific implementation for a
method that is already defined in its superclass. The method in the subclass
should have the same name, return type, and parameters as the method in
the superclass.