Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Part 2: OOP & Core Classes
JAVA

Part 2: OOP & Core Classes

Master Java classes, interfaces, inheritance, the equals and hashCode contract, and the String class family.

1. Class Fundamentals

  • Class: blueprint — fields, methods, constructors, nested types.
  • Constructor: has no return type, name matches class; default constructor is provided only if none is declared.
  • static members belong to the class, shared across all instances, loadable without an instance.
  • final field: must be assigned exactly once (via initializer or constructor).
  • Method overloading: same name, different parameter list — resolved at compile time.
  • Method overriding: same signature in subclass → resolved at runtime (dynamic dispatch).

Gotcha: overload resolution picks the most specific applicable type at compile time. null is ambiguous between two ref types if both are applicable — compiler error unless one is more specific.

2. Inheritance & Polymorphism

  • extends for a single superclass. Java is single inheritance for classes.
  • this vs super: this(...) chains constructors; super(...) calls a parent constructor — must be the first statement.
  • Method dispatch: overridden method chosen by the runtime type of the object, not the declared type.
  • Private methods are not overridden — they’re bound statically; overriding a private method in a subclass is just a new method.
  • Static methods are hidden, not overridden — call resolution depends on the compile-time type.
  • final method/class: cannot be overridden/extended.
class Animal {
    void sound() { System.out.println("generic"); }
}
class Dog extends Animal {
    @Override
    void sound() { System.out.println("bark"); }
}
Animal a = new Dog();
a.sound();                 // "bark" — dynamic dispatch

3. Abstract Classes vs Interfaces

Abstract classInterface
extendssingleimplements multiple
Statecan hold instance fieldsfields are public static final (constants)
Constructorsyesno
Methodscan be concrete or abstractdefault/static/private methods possible, others abstract
private helperyesyes (Java 9+)
When to useshared state/behaviour among is-a subclassescapabilities/contract across unrelated classes
  • Before Java 8 interfaces were pure abstracts — legacy interview point.
  • Default methods let you add behaviour without breaking implementers; diamond problem from two defaults is resolved by overriding.

3. equals() & hashCode() Contract

  • Reflexive: a.equals(a) → true.
  • Symmetric: a.equals(b)b.equals(a).
  • Transitive, consistent, not-null safe (x.equals(null) → false).
  • The critical rule: equal objects must have equal hashCodes. Unequal hash ≠ wrong, equal hash ≠ equal (collisions are allowed).
  • Why it matters: HashMap, HashSet, Hashtable use hash → bucket; a bad hashCode breaks lookups/duplicate detection.
public class Person {
    private final String name;
    private final int age;
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person p)) return false;
        return age == p.age && name.equals(p.name);
    }
    public int hashCode() { return 31 * name.hashCode() + age; }
}

Interview tip: always override both together — after overriding equals you must override hashCode or collections break. This pairing is the single most-tested OOP detail.

4. The String Family

StringStringBuilderStringBuffer
Mutablenoyesyes
Thread-safeyesnoyes
Use forliterals, immutabilitysingle-threaded concatmulti-threaded concat
Speedslowest in loopsfastestslower (sync)
  • StringBuilder and StringBuffer have identical API — only thread-safety differs.
  • + concatenation compiles into StringBuilder calls — fine for a few, wasteful in loops.
  • String pool: literals are interned. new String(...) skips the pool → poll activity. Use .intern() consciously (rarely needed; memory cost).

Memory gotcha: str.substring() before Java 7 kept the parent char[] — modern Java copies, so no memory leak.

5. Nested Classes: static vs inner

  • Static nestedstatic class Nested: living inside outer, no reference to the outer instance.
  • Inner (non-static) — has an implicit outer reference; cannot be created without an outer instance; can access outer private fields.
  • Local class — inside a method.
  • Anonymous class — one-shot impl without a name.
  • Lambdas replaced most anonymous Runnable/Comparator implementations.

Gotcha: inner class instance retains the outer instance → memory leak risk when the inner outlives the outer (e.g., kept in a cache).

My Private Notes

Notes are auto-saved locally to this device.