Your BankAccount class has a balance field. If it's public, anyone can set it to negative values. Encapsulation makes fields private and provides methods that validate changes - protecting your data from misuse.

Private fields

Hide internal data from direct access.

PrivateFields.java
public class PrivateFields {
    public static void main(String[] args) {
        System.out.println("=== Private Fields ===\n");

        // Create a bank account
        BankAccount account = new BankAccount("John Doe", 1000);

        // Can't access private fields directly!
        // System.out.println(account.balance);  // Compile error!
        // account.balance = 1000000;  // Compile error!

        // Must use methods
        System.out.println("Account holder: " + account.getOwner());
        System.out.println("Balance: $" + account.getBalance());

        // Change balance through method
        account.deposit(500);
        System.out.println("After deposit: $" + account.getBalance());

        // This would have been possible without private:
        // account.balance = -1000000;  // Steal money!
        // account.owner = "";  // Remove owner!

        System.out.println("\n=== Why Private? ===");
        System.out.println("✓ Can't set invalid balance");
        System.out.println("✓ Can't bypass business rules");
        System.out.println("✓ Implementation can change safely");
    }
}

class BankAccount {
    private String owner;
    private double balance;

    BankAccount(String owner, double initialBalance) {
        this.owner = owner;
        this.balance = Math.max(0, initialBalance);  // Ensure non-negative
    }

    // Public methods to access private data
    public String getOwner() {
        return owner;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited $" + amount);
        } else {
            System.out.println("Invalid deposit amount");
        }
    }
}

private makes fields inaccessible from outside the class.

private Access modifier: only visible within the same class.

Getter methods

Provide read access to private fields.

Getters.java
public class Getters {
    public static void main(String[] args) {
        System.out.println("=== Getter Methods ===\n");

        Person person = new Person("Alice", "Smith", 30);

        // Access data through getters
        System.out.println("First name: " + person.getFirstName());
        System.out.println("Last name: " + person.getLastName());
        System.out.println("Age: " + person.getAge());

        // Computed getter
        System.out.println("Full name: " + person.getFullName());

        // Boolean getter uses 'is' prefix
        System.out.println("Is adult: " + person.isAdult());

        System.out.println("\n=== Naming Convention ===");
        System.out.println("getXxx() - for regular types");
        System.out.println("isXxx()  - for boolean types");
    }
}

class Person {
    private String firstName;
    private String lastName;
    private int age;

    Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    // Standard getters
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    // Computed property - not stored, calculated
    public String getFullName() {
        return firstName + " " + lastName;
    }

    // Boolean getter uses 'is' prefix
    public boolean isAdult() {
        return age >= 18;
    }
}

Getters return field values. Convention: getFieldName().

getter Method that returns field value: `public int getAge() { return age; }`

Setter methods with validation

Control how fields are modified.

SettersValidation.java
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}
public class SettersValidation {
    public static void main(String[] args) {
        System.out.println("=== Setters with Validation ===\n");

        double initialPrice = ;
        double newPrice = ;
        int newStock = ;
        Product product = new Product("Laptop", initialPrice, 10);
        System.out.println("Initial: " + product.describe());

        // Valid updates
        product.setPrice(newPrice);
        System.out.println("Price updated: " + product.describe());

        product.setStock(newStock);
        System.out.println("Stock updated: " + product.describe());

        // Invalid updates - rejected!
        System.out.println("\n=== Invalid Attempts ===");

        product.setPrice(-100);  // Rejected
        System.out.println("After negative price: " + product.describe());

        product.setStock(-5);  // Rejected
        System.out.println("After negative stock: " + product.describe());

        product.setName("");  // Rejected
        System.out.println("After empty name: " + product.describe());

        System.out.println("\n=== Values Unchanged ===");
        System.out.println("Invalid values were rejected!");
    }
}

class Product {
    private String name;
    private double price;
    private int stock;

    Product(String name, double price, int stock) {
        // Use setters for validation even in constructor!
        setName(name);
        setPrice(price);
        setStock(stock);
    }

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter with validation
    public void setName(String name) {
        if (name == null || name.isBlank()) {
            System.out.println("  [Rejected: name cannot be blank]");
            return;
        }
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    // Setter with validation
    public void setPrice(double price) {
        if (price < 0) {
            System.out.println("  [Rejected: price cannot be negative]");
            return;
        }
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    // Setter with validation
    public void setStock(int stock) {
        if (stock < 0) {
            System.out.println("  [Rejected: stock cannot be negative]");
            return;
        }
        this.stock = stock;
    }

    String describe() {
        return name + " - $" + price + " (" + stock + " in stock)";
    }
}

Setters can validate before assigning. Reject invalid values.

setter Method that sets field value: `public void setAge(int age) { this.age = age; }`

Read-only properties

Some fields should never be changed after creation.

Readonly.java
public class Readonly {
    public static void main(String[] args) {
        System.out.println("=== Read-Only Properties ===\n");

        // Create a circle
        Circle circle = new Circle(5.0);

        // Can read all properties
        System.out.println("Radius: " + circle.getRadius());
        System.out.println("Area: " + circle.getArea());
        System.out.println("Circumference: " + circle.getCircumference());

        // Cannot change radius - no setter!
        // circle.setRadius(10);  // No such method!
        // circle.radius = 10;    // Private field!

        System.out.println("\n=== Order Example ===");

        Order order = new Order("ORD-12345", 99.99);

        System.out.println("Order ID: " + order.getId());
        System.out.println("Total: $" + order.getTotal());
        System.out.println("Created: " + order.getCreatedTime());

        // ID and creation time are read-only
        // order.setId("ORD-99999");        // No such method
        // order.setCreatedTime(...);       // No such method

        // But total can be updated
        order.setTotal(149.99);
        System.out.println("Updated total: $" + order.getTotal());
    }
}

class Circle {
    private final double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    // Only getter, no setter
    public double getRadius() {
        return radius;
    }

    // Computed properties are naturally read-only
    public double getArea() {
        return Math.PI * radius * radius;
    }

    public double getCircumference() {
        return 2 * Math.PI * radius;
    }
}

class Order {
    private final String id;
    private final long createdTime;
    private double total;              // This one can change

    Order(String id, double total) {
        this.id = id;
        this.createdTime = System.currentTimeMillis();
        this.total = total;
    }

    // Read-only: no setters
    public String getId() {
        return id;
    }

    public long getCreatedTime() {
        return createdTime;
    }

    // Read-write: has getter AND setter
    public double getTotal() {
        return total;
    }

    public void setTotal(double total) {
        if (total >= 0) {
            this.total = total;
        }
    }
}

Provide getter but no setter. Field set only in constructor.

Computed properties

Return calculated values, not stored fields.

ComputedProperties.java
public class ComputedProperties {
    public static void main(String[] args) {
        System.out.println("=== Computed Properties ===\n");

        Rectangle rect = new Rectangle(5, 3);

        // Stored properties
        System.out.println("Width: " + rect.getWidth());
        System.out.println("Height: " + rect.getHeight());

        // Computed properties
        System.out.println("Area: " + rect.getArea());
        System.out.println("Perimeter: " + rect.getPerimeter());
        System.out.println("Is square: " + rect.isSquare());

        // Change dimensions
        System.out.println("\n--- After resize ---");
        rect.setWidth(4);
        rect.setHeight(4);

        System.out.println("Width: " + rect.getWidth());
        System.out.println("Height: " + rect.getHeight());
        System.out.println("Area: " + rect.getArea());
        System.out.println("Is square: " + rect.isSquare());

        System.out.println("\n=== Temperature Example ===");
        Temperature temp = new Temperature(100, "C");
        System.out.println("Celsius: " + temp.getCelsius());
        System.out.println("Fahrenheit: " + temp.getFahrenheit());
        System.out.println("Kelvin: " + temp.getKelvin());
    }
}

class Rectangle {
    private double width;
    private double height;
    // Note: no area or perimeter fields!

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() { return width; }
    public double getHeight() { return height; }

    public void setWidth(double width) {
        if (width > 0) this.width = width;
    }

    public void setHeight(double height) {
        if (height > 0) this.height = height;
    }

    // Computed: calculated from width and height
    public double getArea() {
        return width * height;
    }

    public double getPerimeter() {
        return 2 * (width + height);
    }

    public boolean isSquare() {
        return width == height;
    }
}

class Temperature {
    private double celsius;
    // Store only one value, compute others

    Temperature(double value, String unit) {
        switch (unit.toUpperCase()) {
            case "C" -> this.celsius = value;
            case "F" -> this.celsius = (value - 32) * 5 / 9;
            case "K" -> this.celsius = value - 273.15;
            default -> this.celsius = value;
        }
    }

    // All three are getters, only one is stored
    public double getCelsius() {
        return celsius;
    }

    public double getFahrenheit() {
        return celsius * 9 / 5 + 32;
    }

    public double getKelvin() {
        return celsius + 273.15;
    }
}

Getters can compute values from other fields. Caller doesn't know the difference.

computed property Value calculated from other data: `getArea()` returns `width * height`.

Exercise: ImmutableClass.java

Create a fully immutable class - no changes after construction