[{"data":1,"prerenderedAt":424},["ShallowReactive",2],{"topic-java-oop":3},{"framework":4,"topic":15,"subtopics":24},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Fjava.yml","Java interview questions on language fundamentals, object-oriented design, the Collections Framework, exception handling and concurrency — a staple of backend and enterprise technical interviews.","yml","java",{},"Java",5,"frameworks\u002Fjava",1,"jcUKEcQDoMZrreMRtZYJIVpkQlB-varlzbuwmzLr7kc",{"id":16,"description":17,"extension":7,"frameworkSlug":8,"meta":18,"name":19,"order":20,"slug":21,"stem":22,"__hash__":23},"topics\u002Ftopics\u002Fjava-oop.yml","Classes and objects, inheritance and polymorphism, interfaces vs abstract classes and the equals\u002FhashCode contract — the object model at the heart of every Java interview.",{},"Object-Oriented Programming",2,"oop","topics\u002Fjava-oop","A3ws_0D67Mc9WOPXPIFDm0mmP-46QC-BxugfwNhTWYI",[25,118,197,273,349],{"id":26,"title":27,"body":28,"description":32,"difficulty":34,"extension":35,"framework":10,"frameworkSlug":8,"meta":36,"navigation":37,"order":13,"path":38,"questions":39,"questionsCount":110,"related":111,"seo":112,"seoDescription":113,"stem":114,"subtopic":115,"topic":19,"topicSlug":21,"updated":116,"__hash__":117},"qa\u002Fjava\u002Foop\u002Fclasses-objects.md","Classes Objects",{"type":29,"value":30,"toc":31},"minimark",[],{"title":32,"searchDepth":20,"depth":20,"links":33},"",[],"easy","md",{},true,"\u002Fjava\u002Foop\u002Fclasses-objects",[40,44,48,52,56,60,65,69,73,77,81,85,89,93,98,102,106],{"id":41,"difficulty":34,"q":42,"a":43},"class-vs-object","What is the difference between a class and an object?","A **class** is a *blueprint* — it defines fields (state) and methods\n(behavior). An **object** is a concrete **instance** of that blueprint,\ncreated with `new`, living on the heap with its own copy of the instance\nfields.\n\n```java\nclass Car { String color; }       \u002F\u002F blueprint\nCar a = new Car();                \u002F\u002F object 1\nCar b = new Car();                \u002F\u002F object 2 — separate state\na.color = \"red\";                  \u002F\u002F doesn't affect b\n```\n\nOne class, many objects. **Rule of thumb:** the class is the type; the\nobject is a value of that type sitting in memory.\n",{"id":45,"difficulty":34,"q":46,"a":47},"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":49,"difficulty":34,"q":50,"a":51},"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":53,"difficulty":34,"q":54,"a":55},"constructor-vs-method","How does a constructor differ from a regular method?","- A constructor has the **same name as the class** and **no return type** (not\n  even `void`); a method has any name and a declared return type.\n- A constructor runs **once**, automatically, during `new`; a method runs when\n  you call it, as often as you like.\n- Constructors are **not inherited** and can't be `final`\u002F`static`\u002F`abstract`;\n  methods can be.\n\n```java\nclass Box {\n  int size;\n  Box(int size) { this.size = size; }   \u002F\u002F constructor\n  int size() { return size; }           \u002F\u002F method (named like a getter)\n}\n```\n\nA method *named* like the class but with a return type is just a method, not a\nconstructor — a classic trick. **Rule of thumb:** no return type + class name =\nconstructor.\n",{"id":57,"difficulty":34,"q":58,"a":59},"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":61,"difficulty":62,"q":63,"a":64},"constructor-chaining","medium","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":66,"difficulty":62,"q":67,"a":68},"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":70,"difficulty":62,"q":71,"a":72},"initializer-blocks","What are instance and static initializer blocks?","- A **static initializer block** (`static { ... }`) runs **once** when the class\n  is loaded — used to set up `static` state that needs more than one line.\n- An **instance initializer block** (`{ ... }`) runs **on every `new`**, after\n  `super()` and before the constructor body — shared setup across overloaded\n  constructors.\n\n```java\nclass Config {\n  static final Map\u003CString,String> DEFAULTS;\n  static { DEFAULTS = new HashMap\u003C>(); DEFAULTS.put(\"env\", \"dev\"); }\n  final long created;\n  { created = System.currentTimeMillis(); }   \u002F\u002F runs for each instance\n}\n```\n\n**Rule of thumb:** prefer field initializers or constructors; reach for blocks\nonly when initialization needs logic (a loop, a try\u002Fcatch) that a single\nexpression can't express.\n",{"id":74,"difficulty":62,"q":75,"a":76},"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":78,"difficulty":34,"q":79,"a":80},"instance-vs-static-members","What is the difference between instance and static members?","- An **instance member** belongs to each object — every `new` gets its own copy,\n  accessed through a reference.\n- A **static member** belongs to the class — one copy shared by all instances,\n  accessed through the class name.\n\n```java\nclass Counter {\n  static int total;     \u002F\u002F shared across all Counters\n  int id;               \u002F\u002F unique per Counter\n  Counter() { id = ++total; }\n}\nnew Counter(); new Counter();\nCounter.total;          \u002F\u002F 2 — shared\n```\n\n**Rule of thumb:** if a value or behavior is conceptually about *the type* (a\nconstant, a factory, a running count), make it `static`; if it's about *one\nobject's* state, keep it an instance member.\n",{"id":82,"difficulty":62,"q":83,"a":84},"final-class-method","What does final mean for classes, methods and fields?","- **`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; must be set by the end of construction.\n\n```java\nfinal class Constants { }          \u002F\u002F no subclassing\nclass Base {\n  final void critical() { }        \u002F\u002F subclasses can't override\n  final int id;\n  Base(int id) { this.id = id; }   \u002F\u002F final field set in ctor\n}\n```\n\nCommon reasons: immutability (a class meant to be immutable is often `final`),\nsecurity\u002Finvariant protection, and clarity of intent. Note `final` on a\nreference fixes the *reference*, not the object it points to.\n",{"id":86,"difficulty":34,"q":87,"a":88},"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":90,"difficulty":34,"q":91,"a":92},"getter-setter","Why use getters and setters instead of public fields?","Getters\u002Fsetters keep fields **private** while exposing access through methods,\nso you can add **validation**, change the internal representation, make a field\nread-only, or add logging\u002Flazy-loading **without changing callers**.\n\n```java\nclass Temperature {\n  private double celsius;\n  public double getFahrenheit() { return celsius * 9 \u002F 5 + 32; } \u002F\u002F derived\n  public void setCelsius(double c) {\n    if (c \u003C -273.15) throw new IllegalArgumentException();        \u002F\u002F validated\n    this.celsius = c;\n  }\n}\n```\n\nA `public` field locks the API to a raw value forever. **Rule of thumb:** expose\nbehavior, not data — but don't add a getter\u002Fsetter for *every* field reflexively;\nonly where encapsulation buys something (records are better for pure data).\n",{"id":94,"difficulty":95,"q":96,"a":97},"nested-classes","hard","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":99,"difficulty":62,"q":100,"a":101},"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":103,"difficulty":62,"q":104,"a":105},"private-constructor","When would you make a constructor private?","A `private` constructor blocks outside `new`, which enables several patterns:\n\n- **Singleton** — one shared instance handed out by a static accessor.\n- **Static factory only** — force creation through named methods (`of`,\n  `valueOf`) that can cache or pick a subtype.\n- **Utility class** — a class of only `static` members that should never be\n  instantiated.\n\n```java\nfinal class MathUtil {\n  private MathUtil() { }                 \u002F\u002F no instances\n  static int square(int n) { return n * n; }\n}\nenum Config { INSTANCE; }                \u002F\u002F the preferred singleton\n```\n\n**Rule of thumb:** if a class shouldn't be instantiated freely (utility,\nsingleton, factory-controlled), hide the constructor — but for singletons an\n`enum` is the safest implementation.\n",{"id":107,"difficulty":95,"q":108,"a":109},"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. (A `record` gives\nyou most of this for free.)\n",17,null,{"description":32},"Java classes and objects interview questions — constructors and chaining, this vs super, static vs instance members, final, access modifiers, initializer blocks, nested classes, immutability and the ways to create an object.","java\u002Foop\u002Fclasses-objects","Classes & Objects","2026-06-19","2pfVZGzp6e4jnHO-oLqGtkNngzqwiKj2njOAk0RZJaY",{"id":119,"title":120,"body":121,"description":32,"difficulty":62,"extension":35,"framework":10,"frameworkSlug":8,"meta":125,"navigation":37,"order":20,"path":126,"questions":127,"questionsCount":192,"related":111,"seo":193,"seoDescription":194,"stem":195,"subtopic":120,"topic":19,"topicSlug":21,"updated":116,"__hash__":196},"qa\u002Fjava\u002Foop\u002Finheritance.md","Inheritance",{"type":29,"value":122,"toc":123},[],{"title":32,"searchDepth":20,"depth":20,"links":124},[],{},"\u002Fjava\u002Foop\u002Finheritance",[128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188],{"id":129,"difficulty":34,"q":130,"a":131},"four-pillars","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":133,"difficulty":34,"q":134,"a":135},"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":137,"difficulty":34,"q":138,"a":139},"object-superclass","What is the Object class and what does every class inherit from it?","`java.lang.Object` is the **root** of every class hierarchy — if you don't\n`extends` anything, you implicitly extend `Object`. So every object has its\nmethods, the most important being:\n\n- `equals(Object)` \u002F `hashCode()` — value equality and hashing.\n- `toString()` — string representation.\n- `getClass()` — the runtime class.\n- `clone()`, `finalize()` (deprecated), and the `wait`\u002F`notify` family for\n  threading.\n\n```java\nclass Foo { }            \u002F\u002F implicitly: class Foo extends Object\nObject o = new Foo();\no.toString();            \u002F\u002F \"Foo@1b6d3586\" by default\n```\n\n**Rule of thumb:** because everything is-an `Object`, an `Object` reference (or\n`Object[]`) can hold anything — the basis of pre-generics collections.\n",{"id":141,"difficulty":34,"q":142,"a":143},"types-of-inheritance","What types of inheritance does Java support?","- **Single** — one subclass, one superclass. ✅\n- **Multilevel** — a chain (`C extends B extends A`). ✅\n- **Hierarchical** — many subclasses of one parent. ✅\n- **Multiple inheritance of *classes*** — extending two classes. ❌ (not allowed)\n- **Multiple inheritance of *types*** — implementing many interfaces. ✅\n\n```java\nclass A { }\nclass B extends A { }            \u002F\u002F single\nclass C extends B { }            \u002F\u002F multilevel\nclass D extends A { }            \u002F\u002F hierarchical (with B)\nclass E implements I1, I2 { }    \u002F\u002F multiple interfaces — OK\n```\n\n**Rule of thumb:** Java forbids multiple *class* inheritance but allows multiple\n*interface* inheritance — you get many capabilities, but a single implementation\nlineage.\n",{"id":145,"difficulty":62,"q":146,"a":147},"why-no-multiple-inheritance","Why doesn't Java support multiple inheritance of classes?","To avoid the **diamond problem**: if `B` and `C` both extended `A` and overrode\na method, and `D` extended both `B` and `C`, the compiler couldn't tell **which\nversion** `D` inherits. C++ allows it and pays for it with complexity (virtual\ninheritance).\n\n```java\n\u002F\u002F Hypothetical — illegal in Java:\n\u002F\u002F class D extends B, C { }   \u002F\u002F which greet() does D get?\ninterface B { default String greet() { return \"B\"; } }\ninterface C { default String greet() { return \"C\"; } }\nclass D implements B, C {\n  public String greet() { return B.super.greet(); } \u002F\u002F YOU resolve it\n}\n```\n\nJava permits multiple *interface* inheritance because conflicting `default`\nmethods **force the class to resolve the ambiguity explicitly**. **Rule of\nthumb:** Java trades raw power for predictability.\n",{"id":149,"difficulty":62,"q":150,"a":151},"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":153,"difficulty":62,"q":154,"a":155},"constructor-not-inherited","Are constructors inherited? How are they involved in inheritance?","**No** — constructors are not inherited. But every subclass constructor **must**\ninvoke a superclass constructor first, via an explicit `super(...)` or an\nimplicit no-arg `super()` the compiler inserts.\n\n```java\nclass Base {\n  Base(int id) { }            \u002F\u002F no no-arg constructor\n}\nclass Sub extends Base {\n  Sub() { super(1); }         \u002F\u002F MUST call super(int) explicitly\n  \u002F\u002F Sub() { }                \u002F\u002F would NOT compile — implicit super() missing\n}\n```\n\nSo if a parent defines only parameterized constructors, the child is **forced**\nto call one. **Rule of thumb:** inheritance reuses *methods and fields*, not\nconstructors — the child builds the parent's slice of itself by chaining up.\n",{"id":157,"difficulty":62,"q":158,"a":159},"upcasting-downcasting","What is the difference between upcasting and downcasting?","- **Upcasting** — treating a subclass object as its superclass type. Always\n  safe, implicit. Enables polymorphism.\n- **Downcasting** — casting a superclass reference back to a subclass. Needs an\n  **explicit cast** and can throw `ClassCastException` if the object isn't\n  actually that subtype — guard it with `instanceof`.\n\n```java\nAnimal a = new Dog();          \u002F\u002F upcast — implicit, safe\nDog d = (Dog) a;               \u002F\u002F downcast — explicit\nif (a instanceof Cat c) {      \u002F\u002F pattern: test before casting\n  c.meow();\n}\n```\n\n**Rule of thumb:** upcast freely to program to the supertype; downcast rarely,\nand only after an `instanceof` check.\n",{"id":161,"difficulty":34,"q":162,"a":163},"instanceof","What does the instanceof operator do?","`instanceof` tests whether an object is an instance of a given type (or subtype),\nreturning a `boolean`. Since Java 16, **pattern matching** lets you bind a\nvariable in the same expression, avoiding a separate cast.\n\n```java\nObject o = \"hello\";\nif (o instanceof String) { }            \u002F\u002F classic\nif (o instanceof String s) {            \u002F\u002F pattern matching\n  System.out.println(s.length());       \u002F\u002F s is already a String\n}\n```\n\n`null instanceof X` is always `false`. **Rule of thumb:** heavy `instanceof`\nchains are often a smell — prefer polymorphism (let each type implement the\nmethod) unless you're at a true type boundary (deserialization, `equals`).\n",{"id":165,"difficulty":95,"q":166,"a":167},"inheritance-vs-composition","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":169,"difficulty":34,"q":170,"a":171},"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":173,"difficulty":62,"q":174,"a":175},"aggregation-vs-composition","What is the difference between aggregation and composition?","Both are **has-a**, differing in **lifecycle ownership**:\n\n- **Composition** — the part *can't exist* without the whole; the whole owns and\n  creates it (a `House` and its `Room`s). Strong ownership.\n- **Aggregation** — the part can exist independently and may be shared (a `Team`\n  and its `Player`s; players outlive the team).\n\n```java\nclass House {\n  private final Room room = new Room();   \u002F\u002F composition: created\u002Fowned here\n}\nclass Team {\n  private final List\u003CPlayer> players;      \u002F\u002F aggregation: passed in, shared\n  Team(List\u003CPlayer> players) { this.players = players; }\n}\n```\n\n**Rule of thumb:** \"owns and destroys together\" = composition; \"references but\ndoesn't own\" = aggregation.\n",{"id":177,"difficulty":62,"q":178,"a":179},"prevent-inheritance","How do you prevent a class from being subclassed?","Three ways, by strength:\n\n- **`final` class** — outright bans `extends` (e.g. `String`).\n- **`private`\u002Fpackage-private constructors** — no outside subclass can call\n  `super(...)`, so it can't be extended elsewhere.\n- **`sealed` class** (Java 17+) — allows only a named `permits` list of\n  subclasses.\n\n```java\nfinal class Money { }                          \u002F\u002F no subclasses at all\nsealed class Shape permits Circle, Square { }  \u002F\u002F only these two\n```\n\nReasons: protect invariants (an immutable class shouldn't be subclassed into\nmutability), security, and clearer design. **Rule of thumb:** design for\ninheritance *and document it*, or prohibit it with `final`\u002F`sealed`.\n",{"id":181,"difficulty":62,"q":182,"a":183},"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":185,"difficulty":95,"q":186,"a":187},"liskov","What is the Liskov Substitution Principle?","The **L** in SOLID: a subtype must be usable **anywhere its supertype is\nexpected**, without breaking the program's correctness. A subclass that\nstrengthens preconditions, weakens postconditions, or throws on inherited\noperations violates it.\n\n```java\n\u002F\u002F Classic violation: Square is-a Rectangle?\nclass Rectangle { void setWidth(int w){} void setHeight(int h){} }\nclass Square extends Rectangle {\n  void setWidth(int w){ \u002F* also sets height — breaks setWidth's contract *\u002F }\n}\n\u002F\u002F code that sets width then expects height unchanged now fails\n```\n\nThe fix is usually composition or a shared abstraction, not inheritance. **Rule\nof thumb:** if a subclass can't honor everything the parent promises, it\nshouldn't extend it.\n",{"id":189,"difficulty":95,"q":190,"a":191},"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",16,{"description":32},"Java inheritance interview questions — extends and super, single vs multiple inheritance, the Object superclass, is-a vs has-a, composition over inheritance, upcasting and downcasting, Liskov substitution and SOLID.","java\u002Foop\u002Finheritance","5xZiWFIeS1BBeBN1394_sjmozGSS0qp9FdmN-_BRl9o",{"id":198,"title":199,"body":200,"description":32,"difficulty":62,"extension":35,"framework":10,"frameworkSlug":8,"meta":204,"navigation":37,"order":205,"path":206,"questions":207,"questionsCount":268,"related":111,"seo":269,"seoDescription":270,"stem":271,"subtopic":199,"topic":19,"topicSlug":21,"updated":116,"__hash__":272},"qa\u002Fjava\u002Foop\u002Fpolymorphism.md","Polymorphism",{"type":29,"value":201,"toc":202},[],{"title":32,"searchDepth":20,"depth":20,"links":203},[],{},3,"\u002Fjava\u002Foop\u002Fpolymorphism",[208,212,216,220,224,228,232,236,240,244,248,252,256,260,264],{"id":209,"difficulty":62,"q":210,"a":211},"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":213,"difficulty":62,"q":214,"a":215},"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":217,"difficulty":62,"q":218,"a":219},"overriding-rules","What are the rules for overriding a method?","To override (not overload), the subclass method must:\n\n1. Have the **same name and parameter list** (signature).\n2. Have the **same or a covariant (narrower)** return type.\n3. Have **the same or wider access** (you can't make it more restrictive).\n4. Throw **the same or fewer\u002Fnarrower** checked exceptions.\n\n```java\nclass Base {\n  protected Number make() throws IOException { return 1; }\n}\nclass Sub extends Base {\n  @Override public Integer make() { return 2; } \u002F\u002F wider access, covariant, no checked throws — OK\n}\n```\n\n`private`, `static`, and `final` methods **can't** be overridden. **Rule of\nthumb:** always add `@Override` — the compiler then rejects anything that's\nsecretly an overload or a typo'd signature.\n",{"id":221,"difficulty":62,"q":222,"a":223},"dynamic-dispatch","What is dynamic method dispatch?","Dynamic (virtual) dispatch is how the JVM decides, **at runtime**, which\noverridden method to call — based on the **actual object's class**, not the\nreference type. It's the mechanism that makes runtime polymorphism work.\n\n```java\nclass Shape { double area() { return 0; } }\nclass Circle extends Shape { double area() { return Math.PI; } }\n\nShape s = new Circle();\ns.area();    \u002F\u002F Circle.area() — chosen by the object, not the Shape reference\n```\n\nEach object carries a pointer to its class's method table (vtable); the call\nlooks up the override there. **Rule of thumb:** instance methods are virtual by\ndefault in Java — the runtime type wins.\n",{"id":225,"difficulty":62,"q":226,"a":227},"runtime-vs-compiletime-poly","How does compile-time polymorphism differ from runtime polymorphism?","- **Compile-time (static) polymorphism** = **overloading**. The compiler resolves\n  the call from the **declared argument types**; fixed before the program runs.\n- **Runtime (dynamic) polymorphism** = **overriding**. The JVM resolves the call\n  from the **actual object** during execution.\n\n```java\nvoid print(int x) { }\nvoid print(Object o) { }\nprint(5);            \u002F\u002F compile-time: print(int) chosen by arg type\n\nAnimal a = pickAnimal();\na.sound();           \u002F\u002F runtime: depends on what pickAnimal() returned\n```\n\n**Rule of thumb:** overloading is decided by *what the compiler sees* (reference\ntypes); overriding by *what actually exists* (object type) at runtime.\n",{"id":229,"difficulty":95,"q":230,"a":231},"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":233,"difficulty":95,"q":234,"a":235},"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":237,"difficulty":95,"q":238,"a":239},"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":241,"difficulty":62,"q":242,"a":243},"can-override-static","Can you override a static, final or private method?","No to all three, for different reasons:\n\n- **`static`** — bound to the class, not the instance; redeclaring it in a\n  subclass **hides** it (resolved by declared type), it isn't overridden.\n- **`final`** — explicitly sealed against overriding; won't compile if you try.\n- **`private`** — not visible to the subclass at all, so a same-named method is a\n  brand-new, unrelated method.\n\n```java\nclass A {\n  static void s() { }\n  final void f() { }\n  private void p() { }\n}\nclass B extends A {\n  static void s() { }    \u002F\u002F hides, not overrides\n  \u002F\u002F void f() { }        \u002F\u002F ERROR — can't override final\n  void p() { }           \u002F\u002F new method — A.p() is invisible here\n}\n```\n\n**Rule of thumb:** only **inherited, visible, non-final instance** methods are\ntruly overridable.\n",{"id":245,"difficulty":95,"q":246,"a":247},"overload-resolution","How does the compiler resolve which overload to call?","The compiler picks the **most specific** applicable overload using the\n**compile-time (declared) argument types**, in phases: exact\u002Fwidening match\nfirst, then autoboxing, then varargs — preferring the path that needs the least\nconversion.\n\n```java\nvoid m(Object o) { }\nvoid m(Integer i) { }\nvoid m(int... xs) { }\n\nm(5);          \u002F\u002F m(int...)? No — m(Integer) via boxing beats varargs?\n               \u002F\u002F Actually: widening\u002Fboxing phase -> m(Integer) chosen over varargs\nInteger n = null;\nm(n);          \u002F\u002F m(Integer) — reference match, no boxing\n```\n\nBecause it uses **static types**, `m((Object) myInteger)` calls `m(Object)` even\nif the value is an `Integer`. **Rule of thumb:** overloads are resolved by the\n*reference type you pass*, not the runtime value — avoid ambiguous overloads.\n",{"id":249,"difficulty":62,"q":250,"a":251},"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":253,"difficulty":34,"q":254,"a":255},"super-in-override","How do you call the parent's version of an overridden method?","Use `super.method()`. Inside an override, `super` skips the current class's\nversion and invokes the **immediate superclass's** implementation — useful to\n*extend* rather than *replace* behavior.\n\n```java\nclass Logger { void log(String m) { System.out.println(m); } }\nclass TimestampLogger extends Logger {\n  @Override void log(String m) {\n    super.log(java.time.Instant.now() + \" \" + m);  \u002F\u002F reuse + augment\n  }\n}\n```\n\nYou can only reach **one level up** — there's no `super.super`. **Rule of thumb:**\n`super.method()` is the \"decorate the inherited behavior\" tool.\n",{"id":257,"difficulty":62,"q":258,"a":259},"abstract-polymorphism","How do abstract methods support polymorphism?","An **abstract method** declares a contract with no body; each concrete subclass\n*must* provide an implementation. Code calling the method through the abstract\ntype gets each subclass's behavior via dynamic dispatch — polymorphism with a\ncompiler-enforced contract.\n\n```java\nabstract class Shape { abstract double area(); }\nclass Circle extends Shape { double area() { return Math.PI * r * r; } double r = 1; }\nclass Square extends Shape { double area() { return s * s; } double s = 2; }\n\nfor (Shape sh : List.of(new Circle(), new Square()))\n  sh.area();   \u002F\u002F each computes its own — caller doesn't care which\n```\n\n**Rule of thumb:** abstract methods are \"polymorphism you can't forget to\nimplement\" — the compiler stops you from leaving a hole.\n",{"id":261,"difficulty":62,"q":262,"a":263},"why-override-equals-poly","Why is calling an overridable method from a constructor dangerous?","During construction the **subclass override runs before the subclass's fields are\ninitialized**, because the superclass constructor executes first. The override\nthen sees default (`null`\u002F`0`) values.\n\n```java\nclass Base {\n  Base() { init(); }            \u002F\u002F calls the override...\n  void init() { }\n}\nclass Sub extends Base {\n  String name = \"set\";\n  @Override void init() { System.out.println(name); } \u002F\u002F prints null!\n}\nnew Sub();   \u002F\u002F null — name not assigned yet\n```\n\nThis is dynamic dispatch biting you mid-construction. **Rule of thumb:** never\ncall overridable (non-`final`, non-`private`) methods from a constructor — make\nsuch helpers `final` or `private`.\n",{"id":265,"difficulty":34,"q":266,"a":267},"polymorphism-benefits","What practical benefits does polymorphism give you?","- **Extensibility** — add a new subtype without touching code that uses the\n  supertype (open\u002Fclosed principle).\n- **Decoupling** — callers depend on an abstraction, so implementations swap\n  freely (and fakes\u002Fmocks slot in for tests).\n- **Cleaner code** — replaces `if\u002Felse`\u002F`switch` on type with one virtual call.\n\n```java\n\u002F\u002F No type-switching — each shape knows its own area\ndouble total = 0;\nfor (Shape s : shapes) total += s.area();\n```\n\n**Rule of thumb:** when you see a `switch` on an object's \"kind,\" polymorphism\nusually expresses it better — give each kind its own method.\n",15,{"description":32},"Java polymorphism interview questions — overloading vs overriding, runtime vs compile-time polymorphism, dynamic dispatch, overriding rules, covariant returns, method hiding, static\u002Fdynamic binding and programming to an interface.","java\u002Foop\u002Fpolymorphism","7o2uqyC5UrgJanCk1Qm7O3uwi92NkXboNuX1-MmHgdE",{"id":274,"title":275,"body":276,"description":32,"difficulty":62,"extension":35,"framework":10,"frameworkSlug":8,"meta":280,"navigation":37,"order":281,"path":282,"questions":283,"questionsCount":268,"related":111,"seo":344,"seoDescription":345,"stem":346,"subtopic":347,"topic":19,"topicSlug":21,"updated":116,"__hash__":348},"qa\u002Fjava\u002Foop\u002Finterfaces-vs-abstract.md","Interfaces Vs Abstract",{"type":29,"value":277,"toc":278},[],{"title":32,"searchDepth":20,"depth":20,"links":279},[],{},4,"\u002Fjava\u002Foop\u002Finterfaces-vs-abstract",[284,288,292,296,300,304,308,312,316,320,324,328,332,336,340],{"id":285,"difficulty":34,"q":286,"a":287},"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":289,"difficulty":62,"q":290,"a":291},"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":293,"difficulty":34,"q":294,"a":295},"abstract-class-purpose","What is an abstract class and when can't you instantiate one?","An **abstract class** is declared `abstract` and **cannot be instantiated** with\n`new` — it exists to be extended. It can mix abstract methods (no body, must be\nimplemented) with concrete methods and fields, providing a partial\nimplementation subclasses complete.\n\n```java\nabstract class Animal {\n  abstract String sound();                 \u002F\u002F must override\n  void describe() { System.out.println(\"Says \" + sound()); } \u002F\u002F shared\n}\n\u002F\u002F Animal a = new Animal();  \u002F\u002F ERROR — abstract, can't instantiate\nAnimal a = new Dog();        \u002F\u002F OK via a concrete subclass\n```\n\nA class with **any** abstract method must itself be `abstract` (but an abstract\nclass can have zero abstract methods). **Rule of thumb:** abstract class =\n\"shared base you're not meant to use directly.\"\n",{"id":297,"difficulty":62,"q":298,"a":299},"abstract-constructor","Can an abstract class have a constructor?","Yes. Even though you can't `new` an abstract class directly, its constructor\n**runs when a subclass is instantiated**, via the implicit\u002Fexplicit `super(...)`\ncall — it initializes the abstract class's slice of the object.\n\n```java\nabstract class Shape {\n  final String name;\n  Shape(String name) { this.name = name; }   \u002F\u002F runs during subclass construction\n}\nclass Circle extends Shape {\n  Circle() { super(\"circle\"); }               \u002F\u002F must chain to it\n}\n```\n\nInterfaces, by contrast, **cannot** have constructors (no instance state to\ninitialize). **Rule of thumb:** abstract classes initialize shared state through\ntheir constructor; interfaces can't.\n",{"id":301,"difficulty":62,"q":302,"a":303},"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":305,"difficulty":62,"q":306,"a":307},"interface-static-methods","Can an interface have static and private methods?","Yes (Java 8 added `static`, Java 9 added `private`):\n\n- **`static`** — utility methods called on the interface itself, not inherited\n  by implementers (e.g. `Comparator.comparing(...)`).\n- **`private`** \u002F `private static` — helper methods that share code **between**\n  `default`\u002F`static` methods without exposing it.\n\n```java\ninterface Validator {\n  boolean valid(String s);\n  static Validator notEmpty() { return s -> s != null && !s.isEmpty(); }\n  default boolean validAll(List\u003CString> xs) { return xs.stream().allMatch(this::valid); }\n}\n```\n\n**Rule of thumb:** `static` for factories\u002Futilities tied to the type, `private`\nto DRY up the bodies of default methods — interfaces are now mini-toolkits, not\njust contracts.\n",{"id":309,"difficulty":34,"q":310,"a":311},"interface-constants","Can interfaces have fields? What kind?","Only **constants**. Every field in an interface is implicitly `public static\nfinal`, so it must be assigned at declaration and can never change — there's\n**no instance state**.\n\n```java\ninterface Physics {\n  double SPEED_OF_LIGHT = 299_792_458;   \u002F\u002F implicitly public static final\n}\nPhysics.SPEED_OF_LIGHT;                    \u002F\u002F accessed via the interface\n```\n\nThe old \"constant interface\" pattern (implementing an interface just to inherit\nits constants) is an **anti-pattern** — use an `enum` or a `final` class with a\nprivate constructor instead. **Rule of thumb:** interfaces hold constants and\nbehavior, never mutable state.\n",{"id":313,"difficulty":62,"q":314,"a":315},"functional-interface","What is a functional interface?","A **functional interface** has exactly **one abstract method** (SAM — Single\nAbstract Method), so it can be the target type of a **lambda** or **method\nreference**. The `@FunctionalInterface` annotation makes the compiler enforce\nthe \"one abstract method\" rule.\n\n```java\n@FunctionalInterface\ninterface Transformer { String apply(String s); }\n\nTransformer upper = s -> s.toUpperCase();   \u002F\u002F lambda implements the SAM\nupper.apply(\"hi\");                           \u002F\u002F \"HI\"\n```\n\n`default`\u002F`static` methods don't count against the one-abstract-method limit.\nExamples: `Runnable`, `Comparator`, `Function`, `Predicate`. **Rule of thumb:**\none abstract method = lambda-compatible.\n",{"id":317,"difficulty":62,"q":318,"a":319},"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":321,"difficulty":62,"q":322,"a":323},"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":325,"difficulty":62,"q":326,"a":327},"interface-multiple-inheritance","How do interfaces give Java a form of multiple inheritance?","A class can `implements` **many** interfaces, inheriting **multiple type\ncontracts** — and, since Java 8, multiple `default` **implementations**. That's\nmultiple inheritance of *type* and *behavior*, without multiple inheritance of\n*state* (which is what causes the classic diamond problem).\n\n```java\ninterface Swimmer { default void move() { System.out.println(\"swim\"); } }\ninterface Flyer   { default void glide() { System.out.println(\"glide\"); } }\nclass Duck implements Swimmer, Flyer { }   \u002F\u002F inherits both behaviors\n```\n\nBecause interfaces hold no instance fields, there's no ambiguous state to merge.\n**Rule of thumb:** interfaces = safe multiple inheritance of capability; classes\n= single inheritance of implementation.\n",{"id":329,"difficulty":62,"q":330,"a":331},"when-interface-vs-abstract","How do you decide between an interface and an abstract class?","Choose by what you need to share:\n\n- **Interface** — a *capability* that unrelated classes can have, multiple\n  inheritance of type, or a lambda target. No shared state.\n- **Abstract class** — a *family* of related classes sharing **fields, a\n  constructor, or substantial implementation**.\n\n```java\ninterface Comparable\u003CT> { int compareTo(T o); }   \u002F\u002F any class can be comparable\nabstract class HttpServlet { \u002F* shared request plumbing + state *\u002F }\n```\n\nThey combine well: declare the API as an interface, offer an\n`AbstractXxx` skeletal class for implementers (like `AbstractList`). **Rule of\nthumb:** default to an interface; reach for an abstract class only when you must\nshare state\u002Fimplementation.\n",{"id":333,"difficulty":95,"q":334,"a":335},"diamond-default","If a class extends a class and implements an interface with the same method, which wins?","The **class** wins — \"**class always beats interface**.\" A concrete method\ninherited from a superclass takes priority over a `default` method from an\ninterface, even if the interface is \"more specific.\"\n\n```java\nclass Base { public String id() { return \"class\"; } }\ninterface Tagged { default String id() { return \"interface\"; } }\n\nclass Item extends Base implements Tagged { }\nnew Item().id();   \u002F\u002F \"class\" — superclass method wins over default\n```\n\nAmong *interfaces*, a more-specific interface's default beats a less-specific\none; ties must be resolved manually. **Rule of thumb:** superclass method >\ninterface default > you must override.\n",{"id":337,"difficulty":62,"q":338,"a":339},"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":341,"difficulty":62,"q":342,"a":343},"enum-implements-interface","Can an enum implement an interface or have abstract methods?","Yes. An enum can `implements` an interface, and it can declare **abstract\nmethods** that **each constant overrides** — giving per-constant behavior (a\nclean replacement for `switch` over the enum).\n\n```java\ninterface Op { int apply(int a, int b); }\nenum Math implements Op {\n  ADD { public int apply(int a, int b) { return a + b; } },\n  MUL { public int apply(int a, int b) { return a * b; } };\n}\nMath.ADD.apply(2, 3);   \u002F\u002F 5 — each constant has its own body\n```\n\nAn enum can't `extends` a class (it implicitly extends `java.lang.Enum`), but\ninterfaces are open to it. **Rule of thumb:** use constant-specific method bodies\nto attach behavior to enum values instead of branching on them.\n",{"description":32},"Java interfaces vs abstract classes interview questions — abstraction, default and static interface methods, functional and marker interfaces, multiple inheritance of behavior, interface constants, enums and when to use each.","java\u002Foop\u002Finterfaces-vs-abstract","Interfaces vs Abstract Classes","BW88jLcXhdNT2Ca6gCGI0mGHs07YWnXKYoWi87ygqtY",{"id":350,"title":351,"body":352,"description":32,"difficulty":95,"extension":35,"framework":10,"frameworkSlug":8,"meta":356,"navigation":37,"order":11,"path":357,"questions":358,"questionsCount":268,"related":111,"seo":419,"seoDescription":420,"stem":421,"subtopic":422,"topic":19,"topicSlug":21,"updated":116,"__hash__":423},"qa\u002Fjava\u002Foop\u002Fequals-hashcode.md","Equals Hashcode",{"type":29,"value":353,"toc":354},[],{"title":32,"searchDepth":20,"depth":20,"links":355},[],{},"\u002Fjava\u002Foop\u002Fequals-hashcode",[359,363,367,371,375,379,383,387,391,395,399,403,407,411,415],{"id":360,"difficulty":34,"q":361,"a":362},"equals-vs-==","What is the difference between == and equals()?","- **`==`** compares **references** for primitives' values and for objects'\n  *identity* — are these the **same object** in memory?\n- **`equals()`** compares **logical value**, as defined by the class. The\n  `Object` default is just `==`, so it means nothing useful until overridden.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false — two different objects\na.equals(b);       \u002F\u002F true  — same characters\n```\n\n`==` on objects almost always indicates a bug when you meant value equality\n(the classic `String` comparison mistake). **Rule of thumb:** `==` for\nprimitives and identity; `equals()` for value.\n",{"id":364,"difficulty":62,"q":365,"a":366},"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":368,"difficulty":34,"q":369,"a":370},"default-equals","What does the default Object.equals() do?","The `Object` implementation compares **reference identity** — it returns `true`\nonly if both references point to the **exact same object** (`this == other`).\nSo unless you override it, two distinct objects with identical state are \"not\nequal.\"\n\n```java\nclass Point { int x, y; }\nPoint a = new Point(), b = new Point();   \u002F\u002F both (0,0)\na.equals(b);   \u002F\u002F false — default equals is identity\n```\n\nThat's why value classes (`String`, `Integer`, `LocalDate`) override `equals`.\n**Rule of thumb:** if \"two of these with the same contents should be equal,\" you\nmust override `equals` (and `hashCode`).\n",{"id":372,"difficulty":95,"q":373,"a":374},"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":376,"difficulty":95,"q":377,"a":378},"why-override-both","Why must you override hashCode whenever you override equals?","Because hash-based collections (`HashMap`, `HashSet`) **find a bucket by\n`hashCode` first**, then check `equals` within it. If two `equals` objects have\n**different** hash codes, they land in different buckets and the collection\nnever finds the match.\n\n```java\nclass Key {\n  final int id;\n  @Override public boolean equals(Object o) { \u002F* by id *\u002F return o instanceof Key k && k.id == id; }\n  \u002F\u002F no hashCode override -> uses identity hash!\n}\nvar set = new HashSet\u003CKey>();\nset.add(new Key(1));\nset.contains(new Key(1));   \u002F\u002F false! equal but different hashCode\n```\n\n**Rule of thumb:** equals and hashCode are a package deal — override neither or\nboth, derived from the **same fields**.\n",{"id":380,"difficulty":95,"q":381,"a":382},"equals-properties","What properties must a correct equals() satisfy?","The `equals` contract requires five properties:\n\n- **Reflexive** — `x.equals(x)` is true.\n- **Symmetric** — `x.equals(y)` iff `y.equals(x)`.\n- **Transitive** — if `x=y` and `y=z`, then `x=z`.\n- **Consistent** — repeated calls give the same result (no random\u002Ftime inputs).\n- **Non-null** — `x.equals(null)` is false (never throws).\n\n```java\n@Override public boolean equals(Object o) {\n  if (this == o) return true;            \u002F\u002F reflexive fast-path\n  if (!(o instanceof Point p)) return false; \u002F\u002F handles null + wrong type\n  return x == p.x && y == p.y;           \u002F\u002F symmetric & transitive by construction\n}\n```\n\nSymmetry\u002Ftransitivity are the ones that break with inheritance. **Rule of\nthumb:** compare the same fields both ways and reject null\u002Fother types up front.\n",{"id":384,"difficulty":95,"q":385,"a":386},"getclass-vs-instanceof","Should equals() use instanceof or getClass()?","It's a trade-off:\n\n- **`instanceof`** allows a subclass to be `equals` to its parent, but can break\n  **symmetry** if a subclass adds state.\n- **`getClass()`** requires exact same class — preserves symmetry\u002Ftransitivity\n  but means no subclass instance is ever equal to a parent instance (breaks\n  Liskov for equality).\n\n```java\n\u002F\u002F instanceof — flexible, but Sub vs Base symmetry is fragile\nif (!(o instanceof Point p)) return false;\n\u002F\u002F getClass — strict, symmetric\nif (o == null || getClass() != o.getClass()) return false;\n```\n\nEffective Java recommends `instanceof` **plus making value classes `final`** (or\nusing composition) to sidestep the subclass problem. **Rule of thumb:** prefer\n`instanceof` on a `final`\u002Frecord value type.\n",{"id":388,"difficulty":62,"q":389,"a":390},"objects-helpers","How do java.util.Objects helpers simplify equals and hashCode?","`Objects` provides null-safe utilities so you don't hand-roll boilerplate:\n\n- `Objects.equals(a, b)` — null-safe equality (no NPE if `a` is null).\n- `Objects.hash(f1, f2, ...)` — combines fields into one hash code.\n- `Objects.requireNonNull(x)` — guard constructor args.\n\n```java\n@Override public boolean equals(Object o) {\n  if (this == o) return true;\n  if (!(o instanceof User u)) return false;\n  return age == u.age && Objects.equals(name, u.name); \u002F\u002F null-safe\n}\n@Override public int hashCode() { return Objects.hash(name, age); }\n```\n\n**Rule of thumb:** use `Objects.equals`\u002F`Objects.hash` for the fields — concise,\nnull-safe, and consistent with each other.\n",{"id":392,"difficulty":95,"q":393,"a":394},"mutable-key","Why is it dangerous to use a mutable object as a HashMap key?","A `HashMap` places an entry in a bucket based on the key's `hashCode` **at\ninsertion time**. If you then **mutate** a field that `hashCode`\u002F`equals` depend\non, the key's hash changes — it now hashes to a *different* bucket, and lookups\ncan no longer find it.\n\n```java\nvar map = new HashMap\u003CList\u003CInteger>, String>();\nvar key = new ArrayList\u003C>(List.of(1));\nmap.put(key, \"v\");\nkey.add(2);                 \u002F\u002F mutated — hashCode changed\nmap.get(key);               \u002F\u002F null! stranded in the old bucket\n```\n\n**Rule of thumb:** use **immutable** keys (`String`, `Integer`, records,\nenums). If a key must be mutable, never change the fields used by\n`equals`\u002F`hashCode` while it's in the map.\n",{"id":396,"difficulty":95,"q":397,"a":398},"compareto-consistency","Should compareTo be consistent with equals?","It **should** be (`x.compareTo(y) == 0` iff `x.equals(y)`), and sorted\ncollections assume it. When they disagree, `TreeSet`\u002F`TreeMap` — which use\n`compareTo`, **not** `equals` — behave surprisingly.\n\n```java\nvar set = new TreeSet\u003CBigDecimal>();\nset.add(new BigDecimal(\"1.0\"));\nset.add(new BigDecimal(\"1.00\"));   \u002F\u002F compareTo == 0 -> treated as duplicate!\nset.size();                         \u002F\u002F 1, even though equals() says they differ\n```\n\n`BigDecimal` deliberately violates this (scale matters to `equals` but not\n`compareTo`). **Rule of thumb:** keep `compareTo` consistent with `equals`\nunless you have a documented reason — and know `TreeSet`\u002F`TreeMap` use ordering,\nnot equality.\n",{"id":400,"difficulty":34,"q":401,"a":402},"string-equals","Why should you compare strings with equals() and not ==?","`==` compares **references**. String literals are **interned** (shared from a\npool), so `==` sometimes appears to work — but any `String` built at runtime\n(`new`, concatenation, input) is a different object, and `==` then returns\n`false` for equal text.\n\n```java\nString a = \"hi\", b = \"hi\";\na == b;              \u002F\u002F true — both the interned literal\nString c = new String(\"hi\");\na == c;              \u002F\u002F false — different object\na.equals(c);         \u002F\u002F true — same characters\n```\n\n**Rule of thumb:** always use `.equals()` (or `Objects.equals`) for string\ncontent; `==` for strings is a latent bug that \"works\" until the data comes\nfrom outside.\n",{"id":404,"difficulty":34,"q":405,"a":406},"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":408,"difficulty":62,"q":409,"a":410},"record-equals","How do records implement equals, hashCode and toString?","A `record` **auto-generates** `equals`, `hashCode`, and `toString` from its\ncomponents — value-based equality with no boilerplate and no risk of forgetting\n`hashCode`. Two records are equal iff all their components are equal.\n\n```java\nrecord Point(int x, int y) { }\nnew Point(1, 2).equals(new Point(1, 2));   \u002F\u002F true — generated equals\nnew Point(1, 2).hashCode() == new Point(1, 2).hashCode(); \u002F\u002F true\nnew Point(1, 2).toString();                 \u002F\u002F \"Point[x=1, y=2]\"\n```\n\nYou *can* override them, but rarely should. **Rule of thumb:** for an immutable\nvalue type, a `record` is the safest way to get a correct equals\u002FhashCode —\nreach for it before hand-writing them.\n",{"id":412,"difficulty":62,"q":413,"a":414},"hashcode-distribution","What makes a good hashCode implementation?","A good `hashCode`:\n\n- Is **consistent** with `equals` (equal objects -> equal hashes).\n- **Distributes** values across the `int` range so buckets fill evenly (few\n  collisions -> O(1) lookups).\n- Uses the **same fields** that `equals` uses, combined so order matters\n  (`Objects.hash` \u002F the `31 * result + field` idiom).\n\n```java\n@Override public int hashCode() {\n  return Objects.hash(name, age);   \u002F\u002F good enough for almost everything\n}\n\u002F\u002F returning a constant is *legal* but degrades HashMap to O(n)\n```\n\n**Rule of thumb:** `Objects.hash(sameFieldsAsEquals)` — never a constant, never\na field excluded from `equals`.\n",{"id":416,"difficulty":62,"q":417,"a":418},"clone-vs-copy","What is wrong with Object.clone() and what is the alternative?","`clone()` is widely considered broken: it relies on the `Cloneable` marker\ninterface, bypasses constructors, does a **shallow** copy by default (shared\nmutable sub-objects), and has an awkward `protected`\u002Fchecked-exception design.\n\n```java\n\u002F\u002F Preferred: a copy constructor or static factory\nrecord Point(int x, int y) { }\nPoint copy = new Point(p.x(), p.y());          \u002F\u002F explicit, clear\n\nclass Box { Box(Box other) { \u002F* copy fields, deep where needed *\u002F } }\n```\n\n**Rule of thumb:** prefer a **copy constructor** or static factory (`copyOf`)\nover `clone()` — they're explicit, work with `final` fields, and let you control\nshallow vs deep copying.\n",{"description":32},"Java equals and hashCode interview questions — the equals\u002FhashCode contract, why you must override both, == vs equals, identity vs equality, getClass vs instanceof, Objects helpers, mutable keys, compareTo consistency and toString.","java\u002Foop\u002Fequals-hashcode","equals & hashCode","U0sQgIK0X139rE6ovsi3Q5Ukeuz4U073XMsQhd3BUW4",1782244097136]