OOP_3|Data Hiding,|Encapsulation|Access Modifiers|Abstraction VS Encapsulation
Encapsulation can be used in Java to improve the security of a program by hiding sensitive data and methods from other parts of the program that don’t need access to them
Data Hiding:
Data hiding is a key aspect of encapsulation in object-oriented programming. It refers to the practice of making class members private, so they cannot be directly accessed or modified from outside the class.
Data hiding provides several benefits, such as:
- Encapsulation: Hiding implementation details and providing a public interface for interacting with objects.
- Security: Preventing unauthorized access to sensitive data.
- Flexibility: Allowing the class to change its internal representation without affecting the code that uses the class.
Here’s an example of data hiding in Java:
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
balance = initialBalance;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
public double getBalance() {
return balance;
}
}
In this example, the balance
field is declared as private, which means it can only be accessed from within the BankAccount
class. The public deposit()
, withdraw()
, and getBalance()
methods are used to provide controlled access to the balance
data.
The deposit()
and withdraw()
methods ensure that the amount being deposited or withdrawn is valid and update the balance
field accordingly. The getBalance()
method returns the current balance, which can be used by other classes to display the balance or perform additional calculations.
What is Encapsulation?
Encapsulation is a fundamental principle of object-oriented programming that refers to the practice of hiding the internal details of an object and providing a public interface for interacting with the object. The idea behind encapsulation is to create a well-defined boundary around an object, which prevents other objects from directly accessing or modifying its internal state.
Access Modifiers in Java
Access modifiers are used in Java to control the visibility of class members, such as fields and methods. There are four access modifiers in Java:
- public: members with this modifier are visible to all classes, regardless of package or subclass
- protected: members with this modifier are visible to the same package and subclass, and to any class in a different package that is a subclass of the declaring class
- private: members with this modifier are only visible within the same class
- default: members with no access modifier are only visible within the same package
Encapsulating Fields in Java{Getter and Setter}
To encapsulate fields in Java, you can use the private access modifier to make the field only visible within the same class. You can then provide public getter and setter methods to allow other classes to access and modify the field. Here’s an example:
public class Person {
private String name;
private int 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;
}
}
In this example, we have a Person
class with name
and age
fields that are marked as private. We then provide public getter and setter methods to allow other classes to read and modify the field values. The use of getter and setter methods to access the private fields provides a level of encapsulation, as it allows us to control how the fields are accessed and modified.
Encapsulating Methods in Java
You can also use encapsulation to control access to methods in a Java class. This can be useful for hiding implementation details and preventing other classes from invoking methods that could cause unexpected behavior. Here’s an example:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.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) {
if(age >= 0 && age <= 120) {
this.age = age;
}
else {
throw new IllegalArgumentException("Age must be between 0 and 120");
}
}
}
In this example, the Person
class has two private data fields, name
and age
, and four methods, two of which are getters and two of which are setters. The getName()
and getAge()
methods are getters that provide controlled access to the private data fields of the class. The setName()
and setAge()
methods are setters that allow the data fields to be modified, but with restrictions on the values that can be assigned.
The setName()
method simply assigns the new value to the name
field, without any restrictions. The setAge()
method, on the other hand, first checks whether the new value is between 0 and 120 (the valid age range), and only assigns the new value if it meets this criterion. If the new value is outside this range, the method throws an IllegalArgumentException
with an error message.
Abstraction VS Encapsulation
Abstraction is the process of simplifying complex real-world objects or systems by focusing on their essential characteristics and ignoring details that are not relevant to the problem at hand. Abstraction involves creating a model or representation of the object or system that captures its essential features and behaviors while ignoring irrelevant details.
Encapsulation, on the other hand, is the process of hiding the implementation details of an object or system from the outside world and providing controlled access to its functionality through a well-defined interface. Encapsulation involves wrapping data and methods into a single unit (i.e., a class) and controlling access to them through access modifiers such as private, public, and protected.
To illustrate the difference between abstraction and encapsulation, consider the example of a car. Abstraction would involve identifying the essential features and behaviors of a car, such as its ability to transport people and goods, its ability to move at different speeds, and its ability to turn and stop. Encapsulation would involve hiding the details of how the car actually works, such as the internal combustion engine, the transmission, and the braking system, and providing a well-defined interface for controlling the car’s movements, such as the accelerator, brake, and steering wheel.
extra information:
1. instanceof
is a Java keyword that is used to check if an object is an instance of a particular class or a subclass of that class. It returns a boolean value indicating whether the object is an instance of the specified class or not. Here is an example:
class Animal {}
class Dog extends Animal {}
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
Dog d = new Dog();
System.out.println(a instanceof Animal); // true
System.out.println(d instanceof Animal); // true
System.out.println(a instanceof Dog); // false
System.out.println(d instanceof Dog); // true
}
}
In this example, the instanceof
keyword is used to check whether the a
and d
objects are instances of the Animal
and Dog
classes, respectively. The output of the program shows that a
is an instance of Animal
but not an instance of Dog
, while d
is an instance of both Animal
and Dog
.
2. getClass()
is a method in Java that is defined in the Object
class, which is the root class of all classes in Java. The getClass()
method returns a Class
object that represents the runtime class of the object on which the method is called.
class Animal {}
class Dog extends Animal {}
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
Dog d = new Dog();
System.out.println(a.getClass().getName()); // Animal
System.out.println(d.getClass().getName()); // Dog
}
}
In this example, the getClass()
method is called on the a
and d
objects, which are instances of the Animal
and Dog
classes, respectively. The getName()
method is then called on the Class
object returned by getClass()
to get the name of the class. The output of the program shows that the runtime class of a
is Animal
, and the runtime class of d
is Dog
.
The getClass()
method is often used in Java to perform runtime type checking and to access the metadata associated with a class at runtime, such as its name, package, superclass, and interfaces. It can also be used to create new instances of a class dynamically using reflection.
So, we have seen important concepts here mostly of encapsulation that help to achieve the concept of object-oriented programming.