ItTechGenie-Subject - Java OOP (Warm-up + 10 Questions)

Java Question Bank

Java OOP | Q0 Warm‑up (Show/Hide Answer) + Q1–Q10 Scenario Questions (5 Moderate + 5 Complex) — With Answers

Instruction: Full boilerplate is visible by default. Students implement ONLY methods/members marked // ✅ TODO.
Answers: Q0 and Q1–Q10 include answers (logic + code) behind Show/Hide Answer.
Warm‑up: 1 (Q0) Moderate: 5 (Q1–Q5) Complex: 5 (Q6–Q10) Sample Inputs: spaces + quotes + unicode α/β + emoji ✅ + special chars
0

Warm‑up: Map Requirements to OOP Pillars (with answer)

EncapsulationAbstractionInheritancePolymorphismWarm-up

Warm‑up (with answer): You are building a small "Ticketing" system. Choose and justify the best OOP feature for each requirement: 1) Hide internal state (e.g., password/token) 2) Allow multiple payment types (UPI/Card/Cash) with same API 3) Reuse common logic for all ticket types (Bus/Train/Flight) 4) Customize behavior per ticket type without changing caller Write short reasoning + print sample output lines. ✅ Warm-up answer should mention: Encapsulation, Abstraction (interface), Inheritance, Polymorphism.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;                                          // Collections

public class Main {                                                   // entry class
    // ✅ TODO: Student must implement only this method
    static void explainOOP() {
        // TODO:
        // - Print 4 lines, each mapping requirement -> OOP concept
        // - Use clear words: Encapsulation/Abstraction/Inheritance/Polymorphism
        throw new UnsupportedOperationException("TODO");
    }

    public static void main(String[] args) {                          // program entry
        explainOOP();                                                 // print explanation
    }
}

Warm‑up Answer (Concept Map)

Mapping: 1) Hide internal state => Encapsulation (private fields + controlled access) 2) Multiple payment types => Abstraction (Payment interface) + Polymorphism 3) Reuse common logic => Inheritance (BaseTicket with shared fields/methods) 4) Customize behavior => Polymorphism (override methods; call via base type)

System.out.println("1) Hide token => Encapsulation (private fields + controlled access).");
System.out.println("2) UPI/Card/Cash => Abstraction (Payment interface).");
System.out.println("3) Common ticket logic => Inheritance (BaseTicket).");
System.out.println("4) Different behavior => Polymorphism (override + dynamic dispatch).");
1

SecureProfile — Encapsulation + Validation (Setters)

EncapsulationValidationClassesModerate

Scenario: User profile must store email and phone safely. Rules: - email must contain '@' and '.' - phone must be 10 digits (ignore spaces + '-' in input) Implement ONLY TODO methods: - setEmail(String email) - setPhone(String phone) Print final stored values.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;                                              // utilities

class SecureProfile {                                                // domain model
    private String email;                                            // private => encapsulation
    private String phone;                                            // stored normalized

    // ✅ TODO: Student must implement only this method
    public void setEmail(String email) {
        // TODO:
        // - trim
        // - validate contains '@' and '.'
        // - store normalized email
        throw new UnsupportedOperationException("TODO");
    }

    // ✅ TODO: Student must implement only this method
    public void setPhone(String phone) {
        // TODO:
        // - keep digits only
        // - validate length==10
        // - store digits
        throw new UnsupportedOperationException("TODO");
    }

    public String getEmail() { return email; }                       // controlled read
    public String getPhone() { return phone; }                       // controlled read
}

public class Main {
    public static void main(String[] args) {
        SecureProfile p = new SecureProfile();                       // create object
        p.setEmail("  gopi.suresh@ittechgenie.com ✅  ");             // set email
        p.setPhone("  98-76 54 32 10 !@#  ");                         // set phone
        System.out.println(p.getEmail());                             // print email
        System.out.println(p.getPhone());                             // print phone
    }
}

Answer (Logic + Code)

Encapsulation: keep fields private; validate & normalize in setters; expose safe getters.

public void setEmail(String email) {
    String e = (email == null ? "" : email.trim());                   // normalize
    if (!e.contains("@") || !e.contains("."))                         // basic validation
        throw new IllegalArgumentException("Invalid email");          // reject
    this.email = e;                                                   // store
}

public void setPhone(String phone) {
    String s = (phone == null ? "" : phone);                          // null-safe
    StringBuilder digits = new StringBuilder();                       // collect digits
    for (int i = 0; i < s.length(); i++) {                            // scan chars
        char ch = s.charAt(i);
        if (Character.isDigit(ch)) digits.append(ch);                 // keep digit
    }
    if (digits.length() != 10)                                        // validate
        throw new IllegalArgumentException("Phone must be 10 digits");
    this.phone = digits.toString();                                   // store digits-only
}
2

Payment Gateway — Interface Abstraction (Strategy)

AbstractionInterfacePolymorphismModerate

Scenario: Checkout should support multiple payment types with same API. Create: - Payment interface: pay(amount) -> String receipt - UpiPayment / CardPayment implementations Implement ONLY TODO: - PaymentFactory.create(String mode) Modes may include spaces and quotes.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;                                              // utilities

interface Payment {                                                  // abstraction
    String pay(int amount);                                          // common contract
}

class UpiPayment implements Payment {                                // concrete type
    public String pay(int amount) {
        return "UPI_RECEIPT:" + amount;                              // sample receipt
    }
}

class CardPayment implements Payment {                               // concrete type
    public String pay(int amount) {
        return "CARD_RECEIPT:" + amount;                             // sample receipt
    }
}

class PaymentFactory {
    // ✅ TODO: Student must implement only this method
    static Payment create(String mode) {
        // TODO:
        // - normalize mode: trim, remove quotes
        // - if mode equals "UPI" => return new UpiPayment()
        // - else if "CARD" => return new CardPayment()
        // - else throw IllegalArgumentException
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        String mode = "  \"UPI\" ✅ ";                            // messy input
        int amount = 499;                                             // sample amount

        Payment p = PaymentFactory.create(mode);                      // abstraction
        System.out.println(p.pay(amount));                            // polymorphic call
    }
}

Answer (Logic + Code)

Abstraction: interface defines contract; factory selects implementation; caller stays unchanged.

static Payment create(String mode) {
    String m = (mode == null ? "" : mode.trim());                     // trim spaces
    m = m.replace(""", "");                                          // remove quotes
    m = m.replace("✅", "").trim();                                   // remove marker if present

    if (m.equalsIgnoreCase("UPI")) return new UpiPayment();           // select UPI
    if (m.equalsIgnoreCase("CARD")) return new CardPayment();         // select Card

    throw new IllegalArgumentException("Unknown mode: " + m);         // invalid mode
}
3

Ticket Types — Inheritance (BaseTicket)

InheritanceBase classReuseModerate

Scenario: All ticket types share: id, passengerName, baseFare. Different types add their own fee: - Bus: +10 service fee - Train: +20 platform fee - Flight: +200 airport fee Implement ONLY TODO method: - BaseTicket.totalFare()

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
abstract class BaseTicket {                                       // base class
    protected String id;                                              // shared field
    protected String passenger;                                       // shared field
    protected int baseFare;                                           // shared field

    BaseTicket(String id, String passenger, int baseFare) {           // constructor
        this.id = id;                                                 // assign
        this.passenger = passenger;                                   // assign
        this.baseFare = baseFare;                                     // assign
    }

    protected abstract int extraFee();                                // subclass-specific

    // ✅ TODO: Student must implement only this method
    public int totalFare() {
        // TODO:
        // - return baseFare + extraFee()
        throw new UnsupportedOperationException("TODO");
    }
}

class BusTicket extends BaseTicket {
    BusTicket(String id, String passenger, int baseFare) { super(id, passenger, baseFare); }
    protected int extraFee() { return 10; }                           // bus fee
}

class TrainTicket extends BaseTicket {
    TrainTicket(String id, String passenger, int baseFare) { super(id, passenger, baseFare); }
    protected int extraFee() { return 20; }                           // train fee
}

class FlightTicket extends BaseTicket {
    FlightTicket(String id, String passenger, int baseFare) { super(id, passenger, baseFare); }
    protected int extraFee() { return 200; }                          // flight fee
}

public class Main {
    public static void main(String[] args) {
        BaseTicket t = new TrainTicket("TKT-α12 ✅", "Aryan Kumar", 1500);
        System.out.println(t.totalFare());                             // expected 1520
    }
}

Answer (Logic + Code)

Inheritance: shared fields and algorithm in base class; subclasses only provide extra fee.

public int totalFare() {
    return baseFare + extraFee();
}
4

Notification Sender — Runtime Polymorphism (override)

PolymorphismOverrideOpen/ClosedModerate

Scenario: A system sends notifications. - EmailNotification: adds subject line - SmsNotification: adds sender-id Caller uses base type Notification. Implement ONLY TODO methods: - Notification.format(String message) - overrides for Email and SMS.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
abstract class Notification {                                     // base abstraction
    // ✅ TODO: Student must implement only this method
    public String format(String message) {
        // TODO:
        // - base: trim and return
        throw new UnsupportedOperationException("TODO");
    }
}

class EmailNotification extends Notification {
    private final String subject;                                     // email subject
    EmailNotification(String subject) { this.subject = subject; }     // ctor

    // ✅ TODO: Student must implement only this method
    @Override
    public String format(String message) {
        // TODO:
        // - return "EMAIL[" + subject + "]:" + trimmedMessage
        throw new UnsupportedOperationException("TODO");
    }
}

class SmsNotification extends Notification {
    private final String senderId;                                    // sms sender
    SmsNotification(String senderId) { this.senderId = senderId; }

    // ✅ TODO: Student must implement only this method
    @Override
    public String format(String message) {
        // TODO:
        // - return "SMS[" + senderId + "]:" + trimmedMessage
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        String msg = "  Password reset for user \"gopi\" ✅ !@#  ";

        Notification n1 = new EmailNotification("Security Alert");    // upcast
        Notification n2 = new SmsNotification("ITQ-OTP");             // upcast

        System.out.println(n1.format(msg));                            // dynamic dispatch
        System.out.println(n2.format(msg));                            // dynamic dispatch
    }
}

Answer (Logic + Code)

Polymorphism: caller uses base type; runtime chooses overridden method; behavior varies per subclass.

public String format(String message) {
    return (message == null ? "" : message.trim());
}

@Override
public String format(String message) {
    String m = (message == null ? "" : message.trim());
    return "EMAIL[" + subject + "]:" + m;
}

@Override
public String format(String message) {
    String m = (message == null ? "" : message.trim());
    return "SMS[" + senderId + "]:" + m;
}
5

Order Total — Composition (TaxCalculator)

CompositionHas-aSRPModerate

Scenario: Order uses a TaxCalculator component instead of inheriting it. Compute final amount: final = subtotal + tax + shippingFee Implement ONLY TODO: - TaxCalculator.computeTax(int subtotal) - Order.finalAmount() Rules: - Tax: 18% (round down) - Shipping: 50 if subtotal < 500 else 0

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
class TaxCalculator {
    // ✅ TODO: Student must implement only this method
    public int computeTax(int subtotal) {
        // TODO:
        // - 18% tax, integer math (floor)
        throw new UnsupportedOperationException("TODO");
    }
}

class Order {
    private final int subtotal;                                       // base amount
    private final TaxCalculator taxCalc;                              // has-a dependency

    Order(int subtotal, TaxCalculator taxCalc) {
        this.subtotal = subtotal;                                     // store subtotal
        this.taxCalc = taxCalc;                                       // store dependency
    }

    // ✅ TODO: Student must implement only this method
    public int finalAmount() {
        // TODO:
        // - tax = taxCalc.computeTax(subtotal)
        // - shipping = (subtotal < 500) ? 50 : 0
        // - return subtotal + tax + shipping
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        Order o = new Order(499, new TaxCalculator());                // composition
        System.out.println(o.finalAmount());                           // expected 638
    }
}

Answer (Logic + Code)

Composition: Order delegates tax responsibility; SRP improves maintainability and testing.

public int computeTax(int subtotal) {
    if (subtotal < 0) throw new IllegalArgumentException("subtotal");
    return (subtotal * 18) / 100;
}

public int finalAmount() {
    int tax = taxCalc.computeTax(subtotal);
    int shipping = (subtotal < 500) ? 50 : 0;
    return subtotal + tax + shipping;
}
6

Immutable Customer — Builder + Defensive Copy

ImmutabilityBuilderEncapsulationComplex

Scenario: Customer object must be immutable after creation. Fields: id, name, tags (list). Tags input may contain quotes/spaces/emoji. Implement ONLY TODO: - Customer constructor should make defensive copy of tags - CustomerBuilder.build() Rules: - External list mutation must NOT affect Customer.tags. - Expose tags as unmodifiable list.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;                                               // List, Collections

final class Customer {                                               // final => cannot extend
    private final String id;                                         // immutable field
    private final String name;                                       // immutable field
    private final List<String> tags;                                 // immutable view

    // ✅ TODO: Student must implement only this constructor
    Customer(String id, String name, List<String> tags) {
        // TODO:
        // - normalize id/name (trim)
        // - defensive copy: new ArrayList<>(tags)
        // - normalize each tag (trim)
        // - store as Collections.unmodifiableList(copy)
        throw new UnsupportedOperationException("TODO");
    }

    public String id() { return id; }                                // getter
    public String name() { return name; }                            // getter
    public List<String> tags() { return tags; }                      // unmodifiable list
}

class CustomerBuilder {
    private String id;
    private String name;
    private final List<String> tags = new ArrayList<>();

    public CustomerBuilder id(String id) { this.id = id; return this; }
    public CustomerBuilder name(String name) { this.name = name; return this; }
    public CustomerBuilder addTag(String tag) { this.tags.add(tag); return this; }

    // ✅ TODO: Student must implement only this method
    public Customer build() {
        // TODO:
        // - create new Customer(id,name,tags)
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        List<String> external = new ArrayList<>(Arrays.asList(" premium ", " \"trainer\" ", "azure✅"));
        CustomerBuilder b = new CustomerBuilder().id("C-α12 ✅").name("  Gopi Suresh  ");
        for (String t : external) b.addTag(t);

        Customer c = b.build();
        external.add("MUTATE !@#");                                  // should NOT affect Customer

        System.out.println(c.id());
        System.out.println(c.name());
        System.out.println(c.tags());
    }
}

Answer (Logic + Code)

Immutability: defensive copy + unmodifiable view + final fields/class; builder controls construction.

Customer(String id, String name, List<String> tags) {
    this.id = (id == null ? "" : id.trim());
    this.name = (name == null ? "" : name.trim());

    List<String> copy = new ArrayList<>();
    if (tags != null) {
        for (String t : tags) {
            String v = (t == null ? "" : t.trim());
            if (!v.isEmpty()) copy.add(v);
        }
    }
    this.tags = Collections.unmodifiableList(copy);
}

public Customer build() {
    return new Customer(id, name, tags);
}
7

Report Export — DIP with Interface + Mockable Service

DIPInterfacesTestabilityComplex

Scenario: Export reports to CSV or JSON. Business logic depends on abstraction, not concrete classes. Implement ONLY TODO: - ExporterFactory.create(String type) Rules: - type input may contain spaces/quotes/unicode - return CsvExporter or JsonExporter

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
interface Exporter {
    String export(String reportName, String[] lines);
}

class CsvExporter implements Exporter {
    public String export(String reportName, String[] lines) {
        return "CSV:" + reportName + ":" + lines.length;
    }
}

class JsonExporter implements Exporter {
    public String export(String reportName, String[] lines) {
        return "JSON:" + reportName + ":" + lines.length;
    }
}

class ExporterFactory {
    // ✅ TODO: Student must implement only this method
    static Exporter create(String type) {
        // TODO:
        // - normalize input (trim, remove quotes)
        // - if CSV => new CsvExporter()
        // - if JSON => new JsonExporter()
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        Exporter ex = ExporterFactory.create("  JSON ✅  ");
        System.out.println(ex.export("Sales α/β", new String[]{"a,b", "c,d ✅"}));
    }
}

Answer (Logic + Code)

DIP: high-level code uses Exporter; factory selects implementation; easy to test using mocks.

static Exporter create(String type) {
    String t = (type == null ? "" : type.trim());
    t = t.replace(""", "");
    t = t.replace("✅", "").trim();

    if (t.equalsIgnoreCase("CSV")) return new CsvExporter();
    if (t.equalsIgnoreCase("JSON")) return new JsonExporter();

    throw new IllegalArgumentException("Unknown exporter: " + t);
}
8

Subscription Pricing — Template Method + Overrides

Template MethodInheritancePolymorphismComplex

Scenario: Plans compute bill using same steps. 1) base = monthlyRate * months 2) discount = plan-specific 3) tax = 18% on (base-discount) Implement ONLY TODO: - Plan.bill(int months) Subclasses override discount(base).

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
abstract class Plan {
    protected final int monthlyRate;

    Plan(int monthlyRate) { this.monthlyRate = monthlyRate; }

    protected abstract int discount(int base);

    // ✅ TODO: Student must implement only this method
    public int bill(int months) {
        // TODO:
        // - validate months > 0
        // - base = monthlyRate * months
        // - disc = discount(base)
        // - taxable = base - disc
        // - tax = (taxable * 18) / 100
        // - return taxable + tax
        throw new UnsupportedOperationException("TODO");
    }
}

class BasicPlan extends Plan {
    BasicPlan() { super(200); }
    protected int discount(int base) { return 0; }
}

class ProPlan extends Plan {
    ProPlan() { super(500); }
    protected int discount(int base) { return (base * 10) / 100; }
}

public class Main {
    public static void main(String[] args) {
        Plan p = new ProPlan();
        System.out.println(p.bill(6)); // 3186
    }
}

Answer (Logic + Code)

Template method: shared billing flow in base; discount hook in subclasses; consistent algorithm across plans.

public int bill(int months) {
    if (months <= 0) throw new IllegalArgumentException("months");
    int base = monthlyRate * months;
    int disc = discount(base);
    int taxable = base - disc;
    int tax = (taxable * 18) / 100;
    return taxable + tax;
}
9

Money Value Object — equals/hashCode + Safe Addition

Value Objectequals/hashCodeEncapsulationComplex

Scenario: Money equals by amount + currency (case-insensitive). add() only allowed for same currency. Implement ONLY TODO: - Money.equals(Object o) - Money.hashCode() - Money.add(Money other)

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;

final class Money {
    private final int amount;
    private final String currency;

    Money(int amount, String currency) {
        this.amount = amount;
        this.currency = (currency == null ? "" : currency.trim().toUpperCase());
    }

    public int amount() { return amount; }
    public String currency() { return currency; }

    // ✅ TODO: Student must implement only this method
    public Money add(Money other) {
        // TODO:
        // - validate other not null
        // - if currency differs => throw exception
        // - return new Money(this.amount + other.amount, currency)
        throw new UnsupportedOperationException("TODO");
    }

    // ✅ TODO: Student must implement only this method
    @Override public boolean equals(Object o) {
        // TODO:
        // - standard equals contract
        throw new UnsupportedOperationException("TODO");
    }

    // ✅ TODO: Student must implement only this method
    @Override public int hashCode() {
        // TODO:
        // - use Objects.hash(amount, normalizedCurrency)
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        Money m1 = new Money(100, "INR ✅");
        Money m2 = new Money(100, "inr");
        System.out.println(m1.equals(m2));
        System.out.println(m1.add(new Money(20, "INR")).amount());
    }
}

Answer (Logic + Code)

Value object: content-based equals, stable hashCode, safe operations (add only same currency).

public Money add(Money other) {
    if (other == null) throw new IllegalArgumentException("other");
    if (!this.currency.equalsIgnoreCase(other.currency))
        throw new IllegalArgumentException("Currency mismatch");
    return new Money(this.amount + other.amount, this.currency);
}

@Override public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Money)) return false;
    Money m = (Money) o;
    return this.amount == m.amount && this.currency.equalsIgnoreCase(m.currency);
}

@Override public int hashCode() {
    return Objects.hash(amount, currency.toUpperCase());
}
10

Command Processor — OOP Command Pattern (Extensible)

PolymorphismOpen/ClosedCommand PatternComplex

Scenario: CLI supports commands: ADD_USER, DELETE_USER, LIST_USERS. Each command is a class implementing Command interface. Implement ONLY TODO: - CommandParser.parse(String input) Rules: - messy inputs with spaces, quotes, ✅ marker, special chars - Unknown command => exception - Parse name="..." for ADD/DELETE

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and edge cases.
Java OOP scenario (students implement ONLY TODO methods) Ctrl+C
import java.util.*;

interface Command {
    void execute(UserStore store);
}

class UserStore {
    private final List<String> users = new ArrayList<>();

    void add(String u) { users.add(u); }
    void delete(String u) { users.remove(u); }
    List<String> list() { return users; }
}

class AddUserCommand implements Command {
    private final String user;
    AddUserCommand(String user) { this.user = user; }
    public void execute(UserStore store) { store.add(user); }
}

class DeleteUserCommand implements Command {
    private final String user;
    DeleteUserCommand(String user) { this.user = user; }
    public void execute(UserStore store) { store.delete(user); }
}

class ListUsersCommand implements Command {
    public void execute(UserStore store) { System.out.println(store.list()); }
}

class CommandParser {
    // ✅ TODO: Student must implement only this method
    static Command parse(String input) {
        // TODO:
        // - normalize: trim, remove ✅ marker
        // - extract first token as command name
        // - for ADD_USER/DELETE_USER parse name="..." portion
        // - return new AddUserCommand(name) / DeleteUserCommand(name) / ListUsersCommand()
        throw new UnsupportedOperationException("TODO");
    }
}

public class Main {
    public static void main(String[] args) {
        UserStore s = new UserStore();

        Command c1 = CommandParser.parse("  ADD_USER  name=\"Gopi Suresh\" role=Admin ✅ !@#  ");
        c1.execute(s);

        Command c2 = CommandParser.parse(" LIST_USERS ");
        c2.execute(s);
    }
}

Answer (Logic + Code)

Command pattern: parse input to polymorphic Command; execution decoupled; extend by adding new Command classes.

static Command parse(String input) {
    String s = (input == null ? "" : input.trim());
    s = s.replace("✅", "").trim();

    if (s.isEmpty()) throw new IllegalArgumentException("Empty command");

    String[] parts = s.split("\\s+", 2);                           // command + rest
    String cmd = parts[0].toUpperCase();
    String rest = (parts.length > 1) ? parts[1] : "";

    if (cmd.equals("LIST_USERS")) return new ListUsersCommand();

    // Extract name="..."
    String name = "";
    int idx = rest.indexOf("name=");
    if (idx >= 0) {
        int start = rest.indexOf('"', idx);
        int end = (start >= 0) ? rest.indexOf('"', start + 1) : -1;
        if (start >= 0 && end > start) name = rest.substring(start + 1, end).trim();
    }
    if (name.isEmpty()) throw new IllegalArgumentException("Missing name");

    if (cmd.equals("ADD_USER")) return new AddUserCommand(name);
    if (cmd.equals("DELETE_USER")) return new DeleteUserCommand(name);

    throw new IllegalArgumentException("Unknown command: " + cmd);
}