[{"data":1,"prerenderedAt":178},["ShallowReactive",2],{"qa-\u002Fjava\u002Ffundamentals\u002Foop":3},{"page":4,"siblings":169,"blog":175},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":12,"path":20,"questions":21,"related":160,"seo":161,"seoDescription":162,"stem":163,"subtopic":164,"topic":165,"topicSlug":166,"updated":167,"__hash__":168},"qa\u002Fjava\u002Ffundamentals\u002Foop.md","Oop",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Java","java",{},true,"\u002Fjava\u002Ffundamentals\u002Foop",[22,27,31,35,39,43,47,51,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156],{"id":23,"difficulty":24,"q":25,"a":26},"four-pillars","easy","What are the four pillars of object-oriented programming?","- **Encapsulation** — bundle data with the methods that operate on it and hide\n  internal state behind a public API (private fields + getters\u002Fsetters).\n- **Abstraction** — expose *what* an object does, hide *how*, via interfaces\n  and abstract classes.\n- **Inheritance** — a subclass reuses and extends a superclass's members\n  (`extends`).\n- **Polymorphism** — one reference type, many runtime forms; the actual\n  object's overridden method is called.\n\n```java\nclass Animal { String sound() { return \"...\"; } }\nclass Dog extends Animal { String sound() { return \"Woof\"; } } \u002F\u002F inheritance + override\nAnimal a = new Dog();   \u002F\u002F polymorphism\na.sound();              \u002F\u002F \"Woof\"\n```\n\nA good one-liner: encapsulation hides data, abstraction hides complexity,\ninheritance reuses behavior, polymorphism varies it.\n",{"id":28,"difficulty":24,"q":29,"a":30},"encapsulation","What is encapsulation and why does it matter?","Encapsulation means keeping fields **private** and exposing controlled access\nthrough methods, so an object protects its own invariants and you can change the\ninternals without breaking callers.\n\n```java\nclass Account {\n  private double balance;           \u002F\u002F hidden state\n  public void deposit(double amt) {\n    if (amt \u003C= 0) throw new IllegalArgumentException();\n    balance += amt;                 \u002F\u002F validated mutation\n  }\n  public double getBalance() { return balance; }\n}\n```\n\nBenefits: validation in one place, freedom to refactor representation, easier\ndebugging (state changes go through known methods), and thread-safety hooks. A\npublic mutable field gives up all of these.\n",{"id":32,"difficulty":24,"q":33,"a":34},"abstraction","What is abstraction and how is it achieved in Java?","Abstraction is exposing a **simplified contract** while hiding implementation\ndetail. In Java you achieve it with **interfaces** (pure contract) and\n**abstract classes** (partial implementation). Callers depend on the abstract\ntype, not the concrete class.\n\n```java\ninterface PaymentGateway { void charge(int cents); }\n\nclass StripeGateway implements PaymentGateway {\n  public void charge(int cents) { \u002F* API calls hidden here *\u002F }\n}\n\nPaymentGateway gw = new StripeGateway(); \u002F\u002F code depends only on the contract\n```\n\nThe payoff is decoupling: you can swap `StripeGateway` for `PayPalGateway`\nwithout touching the calling code — the basis of \"program to an interface.\"\n",{"id":36,"difficulty":24,"q":37,"a":38},"inheritance","What is inheritance and what does Java not allow?","Inheritance lets a subclass acquire the fields and methods of a superclass with\n`extends`, modeling an **is-a** relationship and enabling reuse + polymorphism.\n\n```java\nclass Vehicle { void start() { } }\nclass Car extends Vehicle { void honk() { } } \u002F\u002F Car is-a Vehicle\n```\n\nJava allows **single inheritance** of classes only — a class can extend exactly\none superclass (to avoid the \"diamond problem\"). It *can* implement **multiple\ninterfaces**, which is how Java gets multiple-type flexibility without\nmultiple class inheritance. `final` classes can't be extended at all.\n",{"id":40,"difficulty":14,"q":41,"a":42},"polymorphism","What is polymorphism and what are its forms?","Polymorphism = \"many forms.\" Java has two kinds:\n\n- **Runtime (dynamic) polymorphism** — method **overriding**. The JVM picks the\n  method based on the *actual object* at runtime (dynamic dispatch).\n- **Compile-time (static) polymorphism** — method **overloading**. The compiler\n  picks the method based on the *declared argument types*.\n\n```java\nAnimal a = new Dog();\na.sound();   \u002F\u002F runtime: Dog's override is chosen\n\nprint(5);    \u002F\u002F compile-time: print(int)\nprint(\"hi\"); \u002F\u002F compile-time: print(String)\n```\n\n\"Polymorphism\" in interviews usually means the runtime kind — the engine behind\n`List\u003CShape>` calling each shape's own `area()`.\n",{"id":44,"difficulty":14,"q":45,"a":46},"overloading-vs-overriding","What is the difference between overloading and overriding?","| | Overloading | Overriding |\n| --- | --- | --- |\n| What | Same name, **different parameters** | Subclass **replaces** a superclass method |\n| Signature | Must differ (type\u002Fcount) | Must be **identical** |\n| Bound | **Compile time** (static) | **Run time** (dynamic) |\n| Return type | Can differ | Same or covariant |\n\n```java\nclass Calc {\n  int add(int a, int b) { return a + b; }          \u002F\u002F overload 1\n  double add(double a, double b) { return a + b; }  \u002F\u002F overload 2\n}\nclass Base { void greet() { } }\nclass Sub extends Base { @Override void greet() { } } \u002F\u002F override\n```\n\nOverloading is about offering variations of an operation; overriding is about\nspecializing inherited behavior. Use `@Override` so the compiler verifies you\nactually overrode (and didn't accidentally overload).\n",{"id":48,"difficulty":14,"q":49,"a":50},"abstract-vs-interface","What is the difference between an abstract class and an interface?","- **Abstract class** — can have state (fields), constructors, and a mix of\n  concrete and abstract methods. A class extends **one**. Models an\n  *is-a* with shared implementation.\n- **Interface** — a contract; historically only abstract methods, now also\n  `default`\u002F`static`\u002F`private` methods, but **no instance state** (only\n  `public static final` constants). A class implements **many**.\n\n```java\nabstract class Shape {\n  private String name;            \u002F\u002F state allowed\n  abstract double area();         \u002F\u002F subclasses must implement\n  String describe() { return name + \": \" + area(); }\n}\ninterface Drawable { void draw(); default void hide() { } }\n```\n\nRule of thumb: use an **interface** for a capability multiple unrelated classes\ncan have (`Comparable`, `Runnable`); use an **abstract class** when subclasses\nshare state or implementation and form a tight family.\n",{"id":52,"difficulty":53,"q":54,"a":55},"inheritance-vs-composition","hard","When should you favor composition over inheritance?","**Inheritance** (is-a) tightly couples a subclass to its parent's\nimplementation; changes to the base can silently break subclasses (the \"fragile\nbase class\" problem). **Composition** (has-a) builds behavior by *holding*\nother objects and delegating — looser coupling, more flexible.\n\n```java\n\u002F\u002F inheritance misused: a Stack is-a List? leaks all List methods\nclass Stack\u003CT> extends ArrayList\u003CT> { }\n\n\u002F\u002F composition: Stack HAS a list, exposes only stack operations\nclass Stack\u003CT> {\n  private final List\u003CT> items = new ArrayList\u003C>();\n  void push(T t) { items.add(t); }\n  T pop() { return items.remove(items.size() - 1); }\n}\n```\n\nGuideline (\"favor composition over inheritance\"): use inheritance only for a\ntrue is-a with a stable base designed for extension; otherwise compose. It also\nsidesteps single-inheritance limits.\n",{"id":57,"difficulty":14,"q":58,"a":59},"super-keyword","What does the super keyword do?","`super` refers to the **immediate superclass**. It does two jobs: call the\nparent **constructor** (`super(args)`, must be the first statement) and call an\n**overridden** parent method or access a parent field (`super.method()`).\n\n```java\nclass Animal {\n  Animal(String name) { }\n  void describe() { System.out.println(\"an animal\"); }\n}\nclass Dog extends Animal {\n  Dog(String name) {\n    super(name);              \u002F\u002F chain to parent constructor\n  }\n  @Override void describe() {\n    super.describe();         \u002F\u002F reuse parent behavior\n    System.out.println(\"...specifically a dog\");\n  }\n}\n```\n\nIf you don't call `super(...)` explicitly, the compiler inserts a no-arg\n`super()` — which fails to compile if the parent has no no-arg constructor.\n",{"id":61,"difficulty":24,"q":62,"a":63},"this-keyword","What does the this keyword refer to in Java?","`this` is a reference to the **current object**. Uses: disambiguate a field\nfrom a same-named parameter, call another constructor in the same class\n(`this(...)`, constructor chaining), and pass the current instance to other\nmethods.\n\n```java\nclass Point {\n  int x, y;\n  Point(int x, int y) {\n    this.x = x;          \u002F\u002F field vs parameter\n    this.y = y;\n  }\n  Point() { this(0, 0); } \u002F\u002F chain to the other constructor\n}\n```\n\n`this(...)` for constructor chaining, like `super(...)`, must be the first\nstatement — so you can't use both in one constructor.\n",{"id":65,"difficulty":24,"q":66,"a":67},"constructor","What is a constructor and what are its rules?","A constructor initializes a new object. It has the **class's name**, **no\nreturn type**, and runs when you use `new`. If you write none, the compiler\nsupplies a **default no-arg** constructor.\n\n```java\nclass User {\n  String name;\n  User() { this(\"anon\"); }      \u002F\u002F no-arg, chains\n  User(String name) { this.name = name; } \u002F\u002F parameterized\n}\n```\n\nRules interviewers probe: defining *any* constructor removes the free default\none; constructors can be overloaded; they're **not inherited** (but a subclass\nmust call one via `super`); and `private` constructors enable singletons and\nfactory-only construction.\n",{"id":69,"difficulty":14,"q":70,"a":71},"constructor-chaining","What is the order of execution when an object is constructed?","Construction runs **top-down** through the hierarchy:\n\n1. Static fields\u002Fblocks run **once** when the class first loads.\n2. On `new`: the superclass constructor runs first (via `super`), all the way\n   up to `Object`.\n3. Then instance field initializers and instance initializer blocks run.\n4. Then the rest of the subclass constructor body.\n\n```java\nclass A { A() { System.out.println(\"A ctor\"); } }\nclass B extends A {\n  int x = init();\n  int init() { System.out.println(\"B field\"); return 1; }\n  B() { System.out.println(\"B ctor\"); }\n}\n\u002F\u002F new B() prints: A ctor -> B field -> B ctor\n```\n\nA famous trap: calling an **overridable method from a constructor** runs the\nsubclass override *before* the subclass's fields are initialized — so it may see\n`null`\u002F`0`.\n",{"id":73,"difficulty":24,"q":74,"a":75},"access-modifiers","What are the four access modifiers in Java?","From most to least restrictive:\n\n- `private` — same class only.\n- *(default \u002F package-private)* — same package only (no keyword).\n- `protected` — same package **plus** subclasses (even in other packages).\n- `public` — everywhere.\n\n```java\npublic class Api {\n  private int secret;       \u002F\u002F class only\n  int packageScoped;        \u002F\u002F package\n  protected int forSubs;    \u002F\u002F package + subclasses\n  public int open;          \u002F\u002F everyone\n}\n```\n\nDefault the most restrictive that works (usually `private` fields) — it\nminimizes coupling. Note `protected` also grants package access, which surprises\npeople who think it's \"subclasses only.\"\n",{"id":77,"difficulty":14,"q":78,"a":79},"static-keyword","What does static mean for methods, fields and nested classes?","`static` binds a member to the **class** rather than an instance:\n\n- **static field** — one shared copy across all instances.\n- **static method** — called on the class, has **no `this`**, can't access\n  instance members directly (utility methods, factories).\n- **static nested class** — doesn't hold a reference to an outer instance.\n- **static block** — runs once at class load for static setup.\n\n```java\nclass MathUtil {\n  static final double PI = 3.14159;\n  static int square(int n) { return n * n; } \u002F\u002F MathUtil.square(5)\n}\n```\n\nBecause static methods aren't tied to an object, they **can't be overridden**\n(only *hidden*) and don't participate in runtime polymorphism.\n",{"id":81,"difficulty":14,"q":82,"a":83},"final-class-method","What does final mean for classes and methods?","- **`final` class** — cannot be extended (e.g. `String`, `Integer`). Locks the\n  design and lets the JIT optimize.\n- **`final` method** — cannot be overridden by subclasses; preserves critical\n  behavior.\n- **`final` field** — assign-once (constant once set).\n\n```java\nfinal class Constants { }          \u002F\u002F no subclassing\nclass Base {\n  final void critical() { }        \u002F\u002F subclasses can't override\n}\n```\n\nCommon reasons: immutability (a class meant to be immutable is often `final`),\nsecurity\u002Finvariant protection, and clarity of intent. It's the opposite of\n\"open for extension,\" so use it deliberately.\n",{"id":85,"difficulty":53,"q":86,"a":87},"equals-hashcode","What is the equals\u002FhashCode contract?","If you override `equals`, you **must** override `hashCode`, obeying:\n\n1. Equal objects (`a.equals(b)`) **must** have equal hash codes.\n2. `equals` must be reflexive, symmetric, transitive, and consistent.\n3. Unequal objects *may* share a hash code (collisions are allowed).\n\n```java\nclass Point {\n  final int x, y;\n  @Override public boolean equals(Object o) {\n    if (this == o) return true;\n    if (!(o instanceof Point p)) return false;\n    return x == p.x && y == p.y;\n  }\n  @Override public int hashCode() { return Objects.hash(x, y); }\n}\n```\n\nBreak the contract and **hash-based collections silently misbehave**: a\n`HashMap`\u002F`HashSet` may fail to find an object whose `hashCode` doesn't match\nits `equals`. Use `Objects.hash(...)` \u002F `Objects.equals(...)` to implement them.\n",{"id":89,"difficulty":24,"q":90,"a":91},"tostring","Why and how do you override toString?","The default `toString` returns `ClassName@hexHashCode` — useless in logs. Override\nit to return a readable representation, which is automatically used in string\nconcatenation, `println`, and debuggers.\n\n```java\nclass User {\n  String name; int age;\n  @Override public String toString() {\n    return \"User{name=\" + name + \", age=\" + age + \"}\";\n  }\n}\nSystem.out.println(new User()); \u002F\u002F User{name=null, age=0}\n```\n\nIt's purely for human-readable diagnostics — don't parse it programmatically.\nIDEs and `record`s can generate it for you.\n",{"id":93,"difficulty":14,"q":94,"a":95},"interface-default","What are default methods in interfaces and why were they added?","A **default method** provides a body inside an interface using the `default`\nkeyword. They were added in Java 8 so interfaces could **evolve** — e.g. adding\n`forEach` to `Iterable` — **without breaking** every existing implementer.\n\n```java\ninterface Greeter {\n  String name();\n  default String greet() { return \"Hello, \" + name(); } \u002F\u002F optional to override\n}\n```\n\nIf a class inherits conflicting defaults from two interfaces, it **must\noverride** to resolve the ambiguity (it can call `Iface.super.method()`).\nInterfaces can also have `static` and `private` helper methods now — but still\nno instance state.\n",{"id":97,"difficulty":14,"q":98,"a":99},"marker-interface","What is a marker interface?","A marker interface has **no methods** — it just *tags* a class so that code (or\nthe JVM) can detect a capability at runtime via `instanceof`. Classic examples:\n`Serializable`, `Cloneable`, `RandomAccess`.\n\n```java\nclass Config implements Serializable { } \u002F\u002F \"this class may be serialized\"\n```\n\nThe JVM checks `if (obj instanceof Serializable)` before serializing. Modern\nJava often prefers **annotations** for metadata, but marker interfaces still\ngive you compile-time type checking and `instanceof` support that annotations\ndon't.\n",{"id":101,"difficulty":14,"q":102,"a":103},"enum-basics","What are enums and what can they do beyond constants?","An `enum` defines a fixed set of named instances. Unlike `int` constants,\nenums are **type-safe**, can have **fields, constructors, and methods**, and\neach constant can even override behavior.\n\n```java\nenum Planet {\n  EARTH(9.81), MARS(3.71);\n  private final double gravity;\n  Planet(double g) { this.gravity = g; }   \u002F\u002F constructor\n  double weight(double mass) { return mass * gravity; }\n}\nPlanet.MARS.weight(70);  \u002F\u002F type-safe, behavior attached\n```\n\nEnums are implicitly `final` singletons (one instance per constant), work in\n`switch`, provide `values()`\u002F`valueOf()`\u002F`ordinal()`, and are the recommended\nway to implement singletons.\n",{"id":105,"difficulty":14,"q":106,"a":107},"record-class","What are records in Java?","A `record` (Java 16+) is a concise, **immutable** data carrier. From a one-line\ndeclaration the compiler generates a canonical constructor, `private final`\nfields, accessors, and `equals`\u002F`hashCode`\u002F`toString`.\n\n```java\nrecord Point(int x, int y) { }\n\nPoint p = new Point(1, 2);\np.x();                       \u002F\u002F accessor (no \"get\" prefix)\np.equals(new Point(1, 2));   \u002F\u002F true — value-based\n```\n\nThey're for transparent data aggregates (DTOs, value objects). Limits: records\nare `final`, can't extend a class (they implicitly extend `Record`), and all\nstate is in the header — you can still add a **compact constructor** for\nvalidation.\n",{"id":109,"difficulty":53,"q":110,"a":111},"nested-classes","What are the types of nested classes in Java?","- **Static nested class** — declared `static`; no link to an outer instance, a\n  namespaced helper.\n- **Inner (non-static) class** — holds an implicit reference to its enclosing\n  instance; can access its outer fields.\n- **Local class** — declared inside a method.\n- **Anonymous class** — an unnamed inner class created and instantiated at once.\n\n```java\nclass Outer {\n  static class Helper { }            \u002F\u002F static nested\n  class Inner { }                    \u002F\u002F inner — needs an Outer instance\n  Runnable r = new Runnable() {      \u002F\u002F anonymous\n    public void run() { }\n  };\n}\n```\n\nGotcha: a non-static inner class keeps the outer object alive (potential memory\nleak), so prefer `static` nested classes unless you actually need the enclosing\ninstance.\n",{"id":113,"difficulty":14,"q":114,"a":115},"object-equality-identity","What is the difference between identity, equality and equivalence?","- **Identity** — `a == b`: are they the *same object* in memory?\n- **Equality** — `a.equals(b)`: are they *logically the same value*, per the\n  class's definition?\n- Some classes also expose **ordering equivalence** via `compareTo == 0`.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false (identity)\na.equals(b);       \u002F\u002F true  (equality)\n\nBigDecimal x = new BigDecimal(\"1.0\"), y = new BigDecimal(\"1.00\");\nx.equals(y);       \u002F\u002F false! (scale differs)\nx.compareTo(y) == 0; \u002F\u002F true  (numeric equivalence)\n```\n\n`BigDecimal` is the classic gotcha where `equals` and `compareTo` disagree.\n",{"id":117,"difficulty":53,"q":118,"a":119},"covariant-return","What is a covariant return type?","When overriding, the subclass method may return a **subtype** of the\nsuperclass method's return type — a covariant return. It lets overrides return\nmore specific types without a cast.\n\n```java\nclass Animal { Animal reproduce() { return new Animal(); } }\nclass Dog extends Animal {\n  @Override Dog reproduce() { return new Dog(); } \u002F\u002F narrower return — legal\n}\nDog puppy = new Dog().reproduce(); \u002F\u002F no cast needed\n```\n\nCommon in builder patterns and `clone()` overrides. (Parameters, by contrast,\nare *not* covariant — changing a parameter type makes it an overload, not an\noverride.)\n",{"id":121,"difficulty":53,"q":122,"a":123},"static-vs-dynamic-binding","What is the difference between static and dynamic binding?","**Static binding** is resolved by the compiler from the **declared type** —\nused for `static`, `private`, `final`, and overloaded methods, plus fields.\n**Dynamic binding** is resolved at runtime from the **actual object type** —\nused for overridden instance methods (virtual dispatch).\n\n```java\nclass A { static void s() { } void v() { } int f = 1; }\nclass B extends A { static void s() { } @Override void v() { } int f = 2; }\n\nA x = new B();\nx.v();   \u002F\u002F B.v()  — dynamic binding (overridden)\nx.s();   \u002F\u002F A.s()  — static binding (hidden, by declared type)\nx.f;     \u002F\u002F 1      — fields are static-bound, not polymorphic\n```\n\nKey insight: **fields and static methods are *hidden*, not overridden** — they\nbind to the declared type, which is a classic trick question.\n",{"id":125,"difficulty":53,"q":126,"a":127},"immutable-class","How do you design an immutable class?","Make the state impossible to change after construction:\n\n1. Mark the class `final` (no subclass can add mutability).\n2. Make all fields `private final`.\n3. Set everything in the constructor; provide **no setters**.\n4. **Defensively copy** mutable fields in and out (don't leak internal refs).\n\n```java\nfinal class Range {\n  private final int[] bounds;\n  Range(int[] bounds) { this.bounds = bounds.clone(); } \u002F\u002F copy in\n  int[] bounds() { return bounds.clone(); }             \u002F\u002F copy out\n}\n```\n\nImmutables are inherently **thread-safe**, cacheable, and safe as map keys —\n`String`, `Integer`, and `LocalDate` are all built this way.\n",{"id":129,"difficulty":14,"q":130,"a":131},"this-vs-super-ctor","Can a constructor call both this() and super()?","No. Both `this(...)` (chain to another constructor in the same class) and\n`super(...)` (chain to the parent) must be the **first statement** in a\nconstructor — and there can only be one first statement, so you use **at most\none** of them.\n\n```java\nclass Base { Base(int n) { } }\nclass Sub extends Base {\n  Sub() { this(5); }          \u002F\u002F delegates within Sub...\n  Sub(int n) { super(n); }    \u002F\u002F ...which then reaches super\n}\n```\n\nThe pattern is to funnel overloaded constructors through `this(...)` down to one\n\"primary\" constructor that finally calls `super(...)`.\n",{"id":133,"difficulty":14,"q":134,"a":135},"object-creation","What are the ways to create an object in Java?","- **`new`** — the normal path, invokes a constructor.\n- **Factory method** — e.g. `List.of()`, `Integer.valueOf()`, your own\n  `Builder.build()`.\n- **`Class.getDeclaredConstructor().newInstance()`** — reflection.\n- **`clone()`** — copy an existing object.\n- **Deserialization** — reconstruct from bytes (bypasses constructors).\n\n```java\nUser a = new User();                          \u002F\u002F new\nList\u003CInteger> b = List.of(1, 2);              \u002F\u002F factory\nUser c = User.class.getDeclaredConstructor().newInstance(); \u002F\u002F reflection\n```\n\nNote that reflection and deserialization can create objects **without running a\nconstructor**, which is why immutability\u002Fsingletons sometimes need extra guards.\n",{"id":137,"difficulty":24,"q":138,"a":139},"ducktyping-isa-hasa","What is the difference between an is-a and a has-a relationship?","- **is-a** -> inheritance. A `Car` *is a* `Vehicle` -> `class Car extends\n  Vehicle`.\n- **has-a** -> composition\u002Faggregation. A `Car` *has an* `Engine` -> the `Car`\n  holds an `Engine` field.\n\n```java\nclass Engine { }\nclass Car extends Vehicle {   \u002F\u002F is-a Vehicle\n  private final Engine engine = new Engine(); \u002F\u002F has-a Engine\n}\n```\n\nModeling tip: if you can't truthfully say \"X is a Y,\" don't use inheritance —\nreach for has-a (composition) instead. Misusing is-a (e.g. `Stack extends\nVector`) is a classic design smell.\n",{"id":141,"difficulty":53,"q":142,"a":143},"method-hiding","What is method hiding and how does it differ from overriding?","When a subclass declares a `static` method with the same signature as a parent\n`static` method, it **hides** rather than overrides it. The version called\ndepends on the **declared (compile-time) type**, not the runtime object — the\nopposite of overriding.\n\n```java\nclass A { static String who() { return \"A\"; } }\nclass B extends A { static String who() { return \"B\"; } }\n\nA ref = new B();\nref.who();   \u002F\u002F \"A\"  — static method, resolved by declared type (hiding)\n\u002F\u002F If who() were an instance method, this would be \"B\" (overriding)\n```\n\nBecause of this confusion, call static methods on the **class** (`A.who()`),\nnever through an instance reference.\n",{"id":145,"difficulty":14,"q":146,"a":147},"interface-vs-abstract-when","Can a class implement multiple interfaces with the same method?","Yes. If two interfaces declare the **same abstract** method, one implementation\nsatisfies both. But if they provide **conflicting `default`** methods, the class\n**must override** to break the tie, optionally delegating with\n`Interface.super.method()`.\n\n```java\ninterface A { default String hi() { return \"A\"; } }\ninterface B { default String hi() { return \"B\"; } }\n\nclass C implements A, B {\n  @Override public String hi() {\n    return A.super.hi();   \u002F\u002F explicitly choose A's default\n  }\n}\n```\n\nThis is Java's controlled answer to the multiple-inheritance \"diamond problem\":\nmultiple *types* are allowed, but conflicting *behavior* must be resolved\nexplicitly.\n",{"id":149,"difficulty":14,"q":150,"a":151},"polymorphism-collections","How does polymorphism enable programming to an interface?","By declaring variables and parameters as the **interface\u002Fsupertype**, your code\nworks with *any* implementation — the runtime calls the actual object's\nmethods. This decouples callers from concrete classes.\n\n```java\nvoid process(List\u003CString> items) { }   \u002F\u002F accepts ArrayList, LinkedList, List.of...\nList\u003CString> list = new ArrayList\u003C>();  \u002F\u002F swap impl freely\n\u002F\u002F list = new LinkedList\u003C>();           \u002F\u002F no caller changes needed\n```\n\n\"Program to an interface, not an implementation\" — depend on `List`, `Map`,\n`Collection`, not `ArrayList`\u002F`HashMap`. It makes code testable (inject fakes)\nand flexible (change implementations without ripple effects).\n",{"id":153,"difficulty":14,"q":154,"a":155},"cohesion-coupling","What are cohesion and coupling?","- **Cohesion** — how focused a class is on a single responsibility. **High\n  cohesion is good**: a `UserValidator` that only validates users.\n- **Coupling** — how dependent classes are on each other's internals. **Low\n  coupling is good**: classes interact through small, stable interfaces.\n\n```java\n\u002F\u002F low coupling: depends on an interface, not a concrete logger\nclass OrderService {\n  private final Logger log;            \u002F\u002F injected abstraction\n  OrderService(Logger log) { this.log = log; }\n}\n```\n\nThe goal of good OO design is **high cohesion, low coupling** — classes that do\none thing well and lean on each other as little as possible, which makes systems\neasier to change and test.\n",{"id":157,"difficulty":53,"q":158,"a":159},"solid","What do the SOLID principles stand for?","Five OO design principles for maintainable code:\n\n- **S** — Single Responsibility: a class has one reason to change.\n- **O** — Open\u002FClosed: open for extension, closed for modification.\n- **L** — Liskov Substitution: subtypes must be usable wherever their base is.\n- **I** — Interface Segregation: prefer small, specific interfaces over fat ones.\n- **D** — Dependency Inversion: depend on abstractions, not concretions.\n\n```java\n\u002F\u002F Dependency Inversion: high-level code depends on an interface\ninterface Repository { void save(Order o); }\nclass OrderService {\n  private final Repository repo;       \u002F\u002F not a concrete DB class\n  OrderService(Repository repo) { this.repo = repo; }\n}\n```\n\nLiskov is the one interviewers probe most: a subclass that throws on, or\nweakens, an inherited method (the `Square extends Rectangle` problem) violates\nit.\n",null,{"description":11},"Java OOP interview questions — the four pillars, inheritance vs composition, abstract classes vs interfaces, overloading vs overriding, polymorphism, the equals\u002FhashCode contract, records and enums.","java\u002Ffundamentals\u002Foop","Object-Oriented Programming","Fundamentals","fundamentals","2026-06-18","unDNeaf0bQsd2Gz0CAYtw3utDO8XyOVtZREhMpXE9oI",[170,174],{"subtopic":171,"path":172,"order":173},"Data Types & Variables","\u002Fjava\u002Ffundamentals\u002Fdata-types-variables",1,{"subtopic":164,"path":20,"order":12},{"path":176,"title":177},"\u002Fblog\u002Fjava-oop-inheritance-polymorphism-encapsulation","Java OOP — Inheritance, Polymorphism, Abstraction & Encapsulation",1781808676707]