Interview Questions 1 - 10  «Prev Next»

Java SE 25: Abstraction, Encapsulation, and ADTs

Distinguish behavior contracts from representation, protect invariants, and design abstract data types without confusing them with algebraic data types.

  1. What is abstraction in Java SE 25?

    Answer: Abstraction presents the behavior that clients need while leaving implementation details behind a contract. Interfaces, classes, and methods can all express abstractions. An abstraction is useful when callers can reason about its operations without reproducing its internal algorithm.

    New syntax does not automatically improve an abstraction. Records expose a data-oriented API; sealed types restrict permitted subtypes. Choose these features because they fit the model, not merely to attach a newer Java version to a design principle.

  2. What is procedural abstraction?

    Answer: It separates what an operation promises from how it performs the work. A method contract states inputs, results, failures, and side effects while its body supplies an algorithm. Callers should depend on that contract rather than internal loops, temporary variables, or storage choices.

  3. What is data abstraction?

    Answer: It models values through supported operations while hiding their representation. A stack exposes push and pop without requiring clients to know whether it uses an array or linked nodes. Its behavior remains meaningful when that representation changes.

    Records are concise data carriers with final component fields, but not necessarily deeply immutable: a record component can refer to a mutable list. Use defensive copies when the desired contract requires them. The var keyword changes local type notation, not encapsulation.

  4. How do the logical and physical views of an object differ?

    Answer: The logical view is its observable meaning and operation contract. The implementation view is how that meaning is represented with fields, helper objects, and algorithms. A queue might logically be an ordered sequence while physically using a circular array.

    Changing internals is safe only if the promised behavior remains compatible, including ordering, errors, and any specified performance guarantees. Private fields alone do not prove such compatibility.

  5. What is an advantage of procedural and data abstraction?

    Answer: They limit how many clients must change when an implementation changes. A service that uses a storage interface can be tested with an in-memory implementation and deployed with a database implementation. This depends on compatible behavior, not merely identical method names.

  6. Why should higher-level code use a DAO through its API?

    Answer: A data access object should isolate persistence details behind operations meaningful to its callers. Exposing a mutable internal cache or requiring callers to know its SQL representation spreads those details through the application.

    Define transaction boundaries, failure behavior, and result ownership explicitly. Interface-based access makes implementations replaceable only when those contracts agree. Neither records nor sealed interfaces are required for a DAO.

  7. What is information hiding?

    Answer: It hides design decisions that clients should not depend on, such as representation and algorithms. Private members and package boundaries help enforce it. Java modules add control over exported packages and reflective access, but do not replace careful API design.

    A getter returning a mutable internal collection can defeat the intended boundary. Returning a copy or a suitable unmodifiable view changes what clients can do, with different ownership and lifetime implications.

  8. What is encapsulation?

    Answer: Encapsulation groups state with the operations that maintain its invariants and controls access to that state. It does not require a setter for every private field. For a nonnegative counter, an increment operation is often more meaningful than unrestricted field assignment.

    Validate inputs before changing state. For a record, constructor validation protects construction, while defensive copying may be needed to protect referenced mutable data.

  9. What is an abstract data type?

    Answer: An abstract data type is defined by values, operations, and behavioral rules independently of a representation. A stack is an ADT whose removal operation returns the most recently added remaining element. Java interfaces can express its operations, while documentation and tests express additional laws.

    Do not confuse an abstract data type with an algebraic data type. Sealed interfaces and records can model alternatives and products, but an ADT does not require a sealed hierarchy.

  10. How should clients access an ADT?

    Answer: Through its defined operations. The following stack hides its deque and defines failure on empty removal. Its callers need not inspect the backing container.

    import java.util.ArrayDeque;
    import java.util.Deque;
    
    public class StackContract {
        interface TextStack {
            void push(String value);
            String pop();
            int size();
        }
        static final class DequeStack implements TextStack {
            private final Deque<String> values = new ArrayDeque<>();
            @Override public void push(String value) { values.push(value); }
            @Override public String pop() { return values.pop(); }
            @Override public int size() { return values.size(); }
        }
        public static void main(String[] args) {
            TextStack stack = new DequeStack();
            stack.push("first");
            stack.push("second");
            System.out.println(stack.pop());
            System.out.println(stack.size());
        }
    }
    

    This implementation rejects null and throws NoSuchElementException when empty. Those are part of its contract, not details callers should discover accidentally.

References: Java SE 25 Language Specification, Deque, ArrayDeque, Record.

SEMrush Software