For working professionals
For fresh graduates
More
6. JDK in Java
7. C++ Vs Java
16. Java If-else
18. Loops in Java
20. For Loop in Java
45. Packages in Java
52. Java Collection
55. Generics In Java
56. Java Interfaces
59. Streams in Java
62. Thread in Java
66. Deadlock in Java
73. Applet in Java
74. Java Swing
75. Java Frameworks
77. JUnit Testing
80. Jar file in Java
81. Java Clean Code
85. Java 8 features
86. String in Java
92. HashMap in Java
97. Enum in Java
100. Hashcode in Java
104. Linked List in Java
108. Array Length in Java
110. Split in java
111. Map In Java
114. HashSet in Java
117. DateFormat in Java
120. Java List Size
121. Java APIs
127. Identifiers in Java
129. Set in Java
131. Try Catch in Java
132. Bubble Sort in Java
134. Queue in Java
141. Jagged Array in Java
143. Java String Format
144. Replace in Java
145. charAt() in Java
146. CompareTo in Java
150. parseInt in Java
152. Abstraction in Java
153. String Input in Java
155. instanceof in Java
156. Math Floor in Java
157. Selection Sort Java
158. int to char in Java
163. Deque in Java
171. Trim in Java
172. RxJava
173. Recursion in Java
174. HashSet Java
176. Square Root in Java
189. Javafx
In the world of software development, two fundamental concepts play a crucial role in designing robust and maintainable code: data hiding and abstraction. While these concepts are related, they serve distinct purposes and offer unique benefits. OOP uses the ideas of data abstraction and data hiding to make systems less complex and more user-friendly by only displaying the information that is important to the end user and hiding the details that are not. In this article, we will delve into the differences between data hiding and abstraction, exploring their definitions, implementation, and practical examples.
Both data hiding and abstraction are essential principles in object-oriented programming (OOP) that contribute to building modular, scalable, and secure software systems. While they share similarities, it is important to understand their distinctions to make informed design decisions.
Abstraction is used to hide the internal implementation details of the code or software and show users only the most crucial set of services or features. On the other side, data hiding is a procedure that conceals internal data and prevents a program from directly accessing it for illegal access. Utilizing private and secured access specifiers allows for this.
Abstraction is a fundamental concept in OOP that focuses on representing complex systems by simplifying their complexity. It conceals the internal implementation and just emphasizes the services. The use of abstract classes and interfaces, along with their subsequent implementation, enable this. Only the essential qualities of an object set it apart from all other objects. Only the most crucial information is highlighted; the remainder is kept hidden from the user or reader.
It involves creating abstract classes, abstract methods, and interfaces to define common characteristics and behaviors shared by a group of related objects. Abstraction allows developers to model real-world scenarios and design flexible, reusable code.
An abstract class serves as a blueprint for derived classes and cannot be instantiated on its own. It provides common attributes and methods that subclasses inherit and implement. It must be inherited from or implemented by another class in order to be accessed. The abstract keyword creates an abstract class. It might or might not include abstract techniques. This enables code reusability and promotes a consistent structure across related objects.
A method that is declared without an implementation (without braces) and is followed by a semicolon is referred to as an abstract method. Abstract methods exist within an abstract class and do not have an implementation. Subclasses must provide a concrete implementation for these methods, ensuring adherence to the defined contract. Abstract methods enforce consistency while allowing flexibility in implementation. For example:
A class must be declared abstract if it contains abstract methods, for example:
abstract class Bird {
// declare fields (if needed)
// declare non-abstract methods (if needed)
// declare the abstract method 'fly'
abstract void fly();
}
The inherited class typically offers implementations for each of the abstract methods in the parent class when an abstract class is inherited. However, the inherited class must also be marked abstract if it does not implement every one of them.
Similar to a class, an interface is a reference type that can only contain nested types, constants, method signatures, default methods, and static methods. Interfaces define a set of method signatures that a class must implement. They serve as contracts, ensuring that classes that implement an interface adhere to a specific set of behaviors.
They enable loose coupling and polymorphism, allowing objects to be treated interchangeably based on shared capabilities. Only default methods and static methods have a method body. Interfaces can only be extended by other interfaces or implemented by classes; they cannot be instantiated. The abstract modifier is not applied to the methods declared in interfaces since those that are not default or static are implicitly abstract.
We must create a class that implements the interface in order to use it.
public class operateKTMDuke implements operateMotorBike {
// Implement the OperateMotorBike method signatures here
int turn(Direction direction, double radius, double startspeed, double endspeed) {
// Implement the logic for turning the motorbike here
// You can use the provided parameters to control the turn
// Return the result, possibly indicating success or failure
return 0; // Placeholder return value, modify as needed
}
// Implement the signalTurn method
public int signalTurn(Direction direction, boolean signalOn) {
// Implement the logic for signaling a turn
// You can use the provided parameters to determine the direction
// and whether to turn the indicator lights on or off
if (signalOn) {
// Turn the corresponding indicator lights on
} else {
// Turn the corresponding indicator lights off
}
return 0; // Placeholder return value, modify as needed
}
// Other members and helper classes can be defined here
}
The abstract method signalTurn or turn is available in the interface, as we have seen in the examples above. However, the other class's implementation of the method hides it.
Abstraction can be categorized into three main types: procedural abstraction, data abstraction, and control abstraction. Each type focuses on abstracting specific aspects of a system to improve maintainability and modularity.
1. Procedural Abstraction
Procedural abstraction involves encapsulating a sequence of operations into a single function or method. The word itself contains a set of functions that are performed one after another in order to achieve abstraction through classes.
It is an example of what a subprogram should accomplish. It offers methods for designating well-defined actions or procedures as entities. It promotes code reuse, readability, and simplifies complex operations.
Data Abstraction
Data abstraction focuses on exposing the essential properties and behaviors of an object while hiding its implementation details. It is a form of abstraction in which we develop complicated data types and shield consumers from the specifics of their implementation. It allows for effective data management, enhances security, and shields internal representations from external entities.
This method has the advantage of resolving performance problems and gradually improving implementation. The code that is present on the client side is unaffected by any performance-related changes we make.
class BankAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def deposit(self, amount):
self.balance += amount # Corrected to update the balance
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount # Corrected to update the balance
else:
print("Insufficient funds.")
def display_balance(self):
print("Account Number:", self.account_number)
print("Balance:", self.balance)
# Example usage
account = BankAccount("1234567890", 5000) # Corrected to use '=' instead of 'account'
account.deposit(2000)
account.withdraw(1000)
account.display_balance()
Output:
BankAccount class abstracts by encapsulating the account number and balance, hence the output.
Control abstraction is the process of identifying all identical and frequently repeated statements and making them appear as a single piece of workControl abstraction involves abstracting control flow mechanisms, such as loops and conditional statements, into higher-level constructs.
This enhances code readability, simplifies complex logic, and promotes modularity.
Using functions in a program is the ideal example of control abstraction since it adheres to the fundamental principle of DRY programming, which stands for Don't Repeat Yourself.
def perform_calculations():
total = 0
while True:
number = int(input("Enter a number (0 to stop): "))
if number == 0:
break
total += number
return total
# Example usage
result = perform_calculations()
print("Total:", result)
Output:
The code abstracts the process of performing calculations on user input until the user enters 0, making the code more readable and simplifying the control flow logic.
It is implemented as a class that merely depicts the crucial characteristics without providing background information. Including only the information that is necessary and keeping its internal implementation a secret. The Java implementation of abstraction is shown below:
// Java program showing the working of abstraction
// Importing generic libraries
import java.io.*;
// Creating an abstract class
// demonstrate abstraction
abstract class Creature {
// Just providing that creatures has legs
// Hiding the number of legs
abstract void No_Of_legs();
}
// A new child class is extending
// the parent abstract class above
class Elephant extends Creature {
// Implementation of the abstract method
void No_Of_legs()
{
// Printing message of function in non abstract
// child class
System.out.println("It has four legs");
}
}
// Again a new child class is extended from parent
// Human class to override function created above
class Human extends Creature {
// Same function over-riden
public void No_Of_legs()
{
// Message printed if this function is called or
// Implementation of the abstract method
System.out.println("It has two legs");
}
}
public class TOTO {
// Main driver method
public static void main(String[] args)
{
// Creating human object showing the implementation
Human ob = new Human();
ob.No_Of_legs();
// Creating object of above class in main
Elephant ob1 = new Elephant();
// Calling the function in main by
// creating object of above non abstract class
ob1.No_Of_legs();
// Implementation of abstraction
}
}
Output:
This code demonstrates abstraction by defining an abstract class "Creature" with an abstract method "No_Of_legs()", which is then implemented in the concrete child classes "Elephant" and "Human" to provide the specific number of legs each creature has when called in the main driver method.
Abstraction offers several benefits, including:
It promotes efficient collaboration among developers, reduces code duplication, and allows for easier code maintenance and updates
Data hiding in OOPs is a principle that focuses on encapsulating data within a class, preventing direct access from external entities. It ensures that sensitive data remains hidden and can only be accessed through controlled mechanisms. It is not recommended that external individuals or groups have direct access to internal data. It is accomplished by utilizing a private modifier as an access specifier.
To achieve data hiding, developers utilize getter and setter methods. Getters provide controlled access to retrieve the values of private data members, while setters allow for controlled modification of those values. This approach ensures data integrity and encapsulation.
After authentication, getter is used to access private data, while setter is used to change private data. It is essentially concealing internal information from users outside the company. No internal data will be accessible without authentication, thanks to its use as security. Internal data will not be accessible to an unauthorized end user. By designating data items as private, we can implement data hiding in programs.
We now have a unique method known as getter setter for modification, depending on the need, to access this data. After authentication, getter is used to access private data, while setter is used to change private data.
Data hiding example in java:
// Java Program showing working of data hiding
// Importing generic libraries
import java.io.*;
// Class created named Bank
class Bank {
// Private data (data hiding)
private long CurBalance = 0;
// Bank_id is checked for authentication
long bank_id;
String name;
// Getter function to modify private data
public long get_balance(long Id)
{
// Checking whether the user is
// authorized or unauthorized
// Comparing bank_id of user and the given Id
// then only it will get access
if (this.bank_id == Id) {
// Return current balance
return CurBalance;
}
// Unauthorized user
return -1;
}
// Setter function
public void set_balance(long balance, long Id)
{
// Comparing bank_id of user and the given Id
// then only it will get access
if (this.bank_id == Id) {
// Update balance in current ID
CurBalance = CurBalance + balance;
}
}
}
// Another class created- Employee
public class Emp {
public static void main(String[] args)
{
// Creating employee object of bank type
Bank _emp = new Bank();
// Assigning employee object values
_emp.bank_id = 12345;
_emp.name = "Roshan";
// _emp.get_balance(123456)
_emp.set_balance(10000, 12345);
// This will no get access as bank_id is given wrong
// so
// unauthorized user is not getting access that is
// data hiding
long emp_balance = _emp.get_balance(12345);
// As this time it is valid user it will get access
// Display commands
System.out.println("User Name"
+ " " + _emp.name);
System.out.println("Bank_ID"
+ " " + _emp.bank_id);
System.out.println("Current Balance"
+ " " + emp_balance);
}
}
Output:
This Java code demonstrates data hiding by defining a class "Bank" with a private data member "CurBalance" that can only be accessed or modified through the public getter and setter methods, ensuring that unauthorized users cannot directly access or modify the balance.
If you're wondering, "In what way is data hiding related to data abstraction?” – Data hiding and abstraction share the goal of enhancing code maintainability and security, but they differ in their focus and approach. Abstraction aims to simplify complex systems and create higher-level representations, while data hiding focuses on encapsulating and securing data within classes.
Understanding the differences between data hiding and abstraction is crucial for designing robust and maintainable software systems. Abstraction allows for modeling complex systems, while data hiding ensures the security and encapsulation of sensitive data. By leveraging these concepts effectively, developers can create modular, flexible, and secure codebases.
1. What is the difference between data hiding and encapsulation?
Ans: The difference between data hiding and encapsulation is that data hiding is a concept of restricting access to certain data members, while encapsulation is a broader concept that encompasses data hiding and also includes bundling data and methods together within a class.
2. Data hiding is also known as?
Data hiding is also known as information hiding. This concept promotes the idea of data safety and security in software design by restricting direct access to certain data components.
3. How does a class enforce data hiding?
A class enforces data hiding by declaring certain data members as private, which means they can only be accessed or modified within the class itself. This prevents direct access to the data from outside the class and encourages the use of getter and setter methods to control access to the data.
Take the Free Quiz on Java
Answer quick questions and assess your Java knowledge
Author
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.