Skip to main content

Encapsulation in Java

 Encapsulation in Java is a fundamental concept of object-oriented programming that combines data and methods into a single unit and restricts access to some of the object's components to ensure better control and security. Here's a simple explanation:

Key Features of Encapsulation:

  1. Data Hiding: Encapsulation allows you to hide the internal details (like variables) of an object from the outside world.
  2. Controlled Access: It provides controlled access to the data through methods (getters and setters).
  3. Improved Security: Sensitive data can be kept safe by making it private and only allowing modification through specific methods.

How It Works:

  1. Private Variables: Declare the instance variables of a class as private, so they are not directly accessible outside the class.
  2. Public Methods: Provide public getter and setter methods to read or update the values of these variables.

Example:

java
public class Person { // Private variables private String name; private int age; // Getter for name public String getName() { return name; } // Setter for name public void setName(String name) { this.name = name; } // Getter for age public int getAge() { return age; } // Setter for age public void setAge(int age) { if (age > 0) { // Validation this.age = age; } else { System.out.println("Age must be positive!"); } } public static void main(String[] args) { Person person = new Person(); person.setName("John"); person.setAge(25); System.out.println("Name: " + person.getName()); System.out.println("Age: " + person.getAge()); } }

Why Use Encapsulation?

  1. Data Security: Prevents unauthorized access to variables.
  2. Flexibility: Allows changes in the implementation without affecting external code.
  3. Maintainability: Easier to maintain and update code.

This approach ensures that data is accessed and modified only in a controlled manner, leading to robust and secure code.


==============================================    

Encapsulation in Java involves a set of rules or principles to ensure that data and methods are bundled together and access is controlled. Here are the rules of encapsulation:


1. Declare Class Variables as Private

  • All instance variables (fields) of the class should be declared as private.
  • This restricts direct access to these variables from outside the class.
java
private String name; // Private variable

2. Provide Public Getter and Setter Methods

  • Use getter methods to retrieve the value of private variables.
  • Use setter methods to modify the value of private variables, often with validations.

Example:

java
public String getName() { // Getter return name; } public void setName(String name) { // Setter if (name != null && !name.isEmpty()) { this.name = name; } else { System.out.println("Invalid name"); } }

3. Use Validation in Setter Methods (Optional but Recommended)

  • Validate data before setting it in the setter methods to ensure correctness and consistency.

Example:

java
public void setAge(int age) { if (age > 0) { // Validation rule this.age = age; } else { System.out.println("Age must be positive"); } }

4. Avoid Direct Access to Private Variables

  • Do not access or modify private variables directly outside the class.
  • Always use the provided getter and setter methods.

Example of incorrect practice:

java
Person p = new Person(); p.name = "John"; // Not allowed because name is private

5. Keep Methods That Operate on Data Within the Same Class

  • Combine data and methods that manipulate the data within the same class. This ensures the logic related to the data is encapsulated.

Example:

java
public void incrementAge() { // Logic to manipulate data this.age++; }

6. Ensure Consistency Between Related Fields

  • Use encapsulation to maintain relationships between fields by controlling their modifications.

Example:

java
public void setWidthAndHeight(double width, double height) { if (width > 0 && height > 0) { this.width = width; this.height = height; } else { System.out.println("Width and height must be positive."); } }

7. Provide Read-Only or Write-Only Access When Needed

  • Read-only access: Provide only getter methods (no setters) for variables that shouldn’t be modified.
  • Write-only access: Provide only setter methods (no getters) for sensitive data.

Example:

java
// Read-only variable private String id; public String getId() { return id; } // Write-only variable private String password; public void setPassword(String password) { this.password = password; }

8. Use Access Modifiers Judiciously

  • Use private for sensitive data that should not be exposed.
  • Use protected or package-private for data that can be accessed within the same package or subclass.
  • Use public for methods that provide controlled access.

9. Encapsulate Utility Methods (Optional)

  • Keep utility methods (helper functions) that operate on class data private or protected if they are not meant to be accessed externally.

Example:

java
private boolean isValidEmail(String email) { // Utility method return email.contains("@"); }

10. Follow Naming Conventions

  • Use standard naming conventions for getter and setter methods:
    • Getter: getVariableName()
    • Setter: setVariableName()

Example:

java
public String getName() { return name; } public void setName(String name) { this.name = name; }

11. Avoid Overusing Getter and Setter Methods

  • Avoid exposing too many getter and setter methods for all fields.
  • Sometimes, a single method can encapsulate a higher-level operation instead of providing direct access to fields.

Example: Instead of:

java
account.setBalance(account.getBalance() + 100);

Use:

java
account.deposit(100);

12. Keep the Class Self-Contained

  • Ensure the class can manage its state and behavior without external interference.

Example:

java
public class Circle { private double radius; public double getArea() { return Math.PI * radius * radius; // Class manages its own behavior } }

13. Enforce Encapsulation at the Design Level

  • Avoid exposing too much internal functionality.
  • Carefully decide which methods and variables should be public, protected, or private.

Summary of Rules

  1. Declare variables as private.
  2. Provide public getter and setter methods.
  3. Add validation in setter methods when necessary.
  4. Avoid direct access to private variables.
  5. Group related data and methods within the same class.
  6. Provide read-only or write-only access when appropriate.
  7. Use access modifiers appropriately (private, protected, etc.).
  8. Minimize the use of getters/setters when better abstractions are possible.
  9. Follow naming conventions for methods.
  10. Design classes to manage their state and behavior independently.

Comments

Popular posts from this blog

Step-by-Step: Launch Browser, Context, and Page in Playwright and Run Test and Configuration (JavaScript)

πŸŽ₯ Setup Browser, Context, Page & Run Config Test Scripts with package.json & playwright.config.js Step-by-Step: Launch Browser, Context, and Page in Playwright and Run Test and Configuration (JavaScript) 1. Install Playwright You can install Playwright using the following command: npm init playwright@latest 2. Create a Basic Test Script Understand the core Playwright architecture: Element Description browser Controls the browser instance (like Chrome, Firefox, etc.) context Acts like a separate browser profile (cookies, localStorage are isolated) page A single browser tab where interaction happens 3. Run the Test npx playwright test example.spec.js Ways to Run TypeScript Tests Way Command Notes 🟒 Via npx npx playwright test Uses built-in TypeScript support 🟒 With s...

Playwright Test Structure in Details -Session-02

πŸŽ₯ Playwright: test.only, Hooks & Grouping with test.describe Explained Let’s go step-by-step , showing how to build from a single test , to using beforeEach / afterEach , and then organizing things with test.describe . ✅ Step 1: Basic Single Test with test.only import { test, expect } from '@playwright/test' ; test. only ( 'πŸš€ Basic test - check title' , async ({ page }) => { await page. goto ( 'https://example.com' ); await expect (page). toHaveTitle ( /Example Domain/ ); }); test.only ensures only this test runs — great for debugging. ✅ Step 2: Add beforeEach and afterEach import { test, expect } from '@playwright/test' ; test. beforeEach ( async ({ page }) => { console . log ( 'πŸ”„ Setting up before each test' ); await page. goto ( 'https://example.com' ); }); test. afterEach ( async ({ page }, testInfo) => { console . log ( `πŸ“¦ Finished test: ${testInfo.title} `); }); test. only ( ...

Playwright Locators in JavaScript (Complete Guide)

🎯 Playwright Locators in JavaScript (Complete Guide) This guide explains each Playwright locator with: ✅ What it is πŸ• When to use ⚙️ How to use it 🎯 Benefits πŸ§ͺ Code Examples πŸ”Ή 1. Locator by ID ✅ What: Selects an element with a unique id . πŸ• When: Element has a unique id . ⚙️ How: page.locator('#username') 🎯 Benefit: Fast and reliable. <input id="username" /> await page.locator('#username').fill('John'); πŸ”Ή 2. Locator by Class ✅ What: Selects by class . πŸ• When: Repeated or styled elements. ⚙️ How: page.locator('.password') 🎯 Benefit: Useful for shared styling. <input class="password" /> await page.locator('.password').fill('12345'); πŸ”Ή 3. Locator by Text ✅ What: Matches visible element text. πŸ• When: For buttons, links, etc. ⚙️ How: page.getByText('Login') 🎯 Benefit: Human-readable. <button>Login...