89 Object-Oriented Programming Interview Questions and Answers (2026)

Blog / 89 Object-Oriented Programming Interview Questions and Answers (2026)
Object-oriented programming (OOP) interview questions and answers

Object-Oriented Programming is the backbone of most large codebases, and interviewers know it. As systems scale, they've stopped accepting textbook definitions, they want to see you reason about design, relationships, and object semantics on the spot. Walk in shaky on abstraction, inheritance, or polymorphism and the gaps show fast.

This guide gives you 89 questions with concise, interview-ready answers and code where it actually helps. It's worked Junior to Mid to Senior, so you build from class-and-object fundamentals up to the deep mechanics of binding, coupling, and identity. Work through it and you'll answer with confidence, not guesswork.

Q1.
Explain the conceptual difference between a class and an object. If a class is a blueprint, what exactly is the instance in memory?

Junior

A class is a compile-time definition (the type), while an object is a concrete, runtime allocation of memory that follows that definition. The blueprint describes fields and methods; the instance is an actual filled-in region of memory holding real values.

  • Class: the template:

    • Declares the structure (fields), operations (methods), and type identity, but holds no per-instance data itself.

    • Exists once; costs no per-object memory (aside from static members and metadata).

  • Object: the instance in memory:

    • A block of memory (usually on the heap) laid out per the class: slots for each instance field plus a hidden pointer to the class metadata / vtable.

    • Each object has its own field values, so many instances of one class hold independent state.

  • Analogy check: Blueprint (class) vs. the actual built house (object): you live in the house, not the blueprint, and you can build many houses from one blueprint.

  • Practical distinction: Methods are shared (one copy referenced via the class), but data is per-instance.

Q2.
What is the 'this' (or 'self') reference conceptually, and how does an object know its own context?

Junior

The this (or self) reference is an implicit pointer to the specific object on which a method was invoked, letting shared method code operate on that instance's own data.

  • Why it's needed: Method code exists once and is shared by all instances, so it needs a way to know "which object's fields am I acting on right now?"

  • How context is supplied:

    • When you call obj.method(), the runtime passes obj as a hidden first argument; inside the method that becomes this/self.

    • In Python this is explicit (def method(self)); in Java/C++/C# it's implicit but present.

  • What it enables: Disambiguating a field from a same-named parameter, passing the current object to other code, and method chaining by returning this.

  • Key insight: The object doesn't "know" itself magically: identity is threaded in per call. A static method has no this because it isn't bound to an instance.

Q3.
What is the difference between a Class and an Object in terms of memory allocation?

Junior

A class is a blueprint that mostly lives as code/metadata, while an object is a concrete instance that occupies real memory at runtime: defining a class allocates almost nothing per instance, but creating an object allocates space for its fields.

  • A class is a template:

    • Its definition (method code, type metadata) is loaded once into a shared area (e.g. the method area / metaspace in the JVM), not copied per object.

    • Methods are stored once and shared by all instances; only their code exists, regardless of how many objects you make.

  • An object is a runtime instance:

    • Each object gets its own memory block holding its instance fields, so N objects means N copies of the state.

    • Typically allocated on the heap; the variable you hold is usually a reference/pointer to that block (stack holds the reference in many languages).

  • Static vs instance: static/class members live with the class (one copy); instance members live with each object.

  • Lifetime: Class metadata lives as long as it is loaded; an object lives until it is no longer reachable and gets garbage-collected (or freed).

Q4.
How does Object-Oriented Programming differ from procedural or structured programming, and what specific problems does it solve?

Junior

Procedural programming organizes code around functions that act on separate, freely-shared data; OOP bundles data and the behavior that operates on it into objects. This solves the scaling problem where global data and tangled functions become impossible to reason about and change safely.

  • Procedural: functions + shared data:

    • Logic is a sequence of procedures operating on data structures that anyone can read or mutate.

    • As the program grows, data has no owner, so a change in one place can silently break many others.

  • OOP: data + behavior together:

    • An object encapsulates its state and exposes methods, so invariants are enforced in one place.

    • Objects interact through interfaces, hiding internal details.

  • Problems OOP addresses:

    • Encapsulation limits the blast radius of change and protects invariants.

    • Polymorphism replaces sprawling switch/if-type branching with substitutable types.

    • Inheritance/composition model domain relationships and share behavior.

  • Caveat: OOP is not universally better: for simple scripts or heavily data-transformation work, procedural or functional styles can be clearer.

Q5.
Explain the four pillars of OOP to a non-technical stakeholder.

Junior

The four pillars are encapsulation, abstraction, inheritance, and polymorphism. In plain terms, they are about hiding complexity, showing only what matters, reusing what already exists, and letting one instruction work sensibly across many kinds of things.

  • Encapsulation ("keep the internals private"): Like an ATM: you use buttons, you never touch the cash mechanism inside. The object protects its own workings.

  • Abstraction ("show only what matters"): Like driving a car: you use the steering wheel and pedals without knowing how the engine burns fuel.

  • Inheritance ("build on what exists"): Like a family trait passed down: a 'sports car' is a kind of 'car' and reuses everything a car already does, plus its own extras.

  • Polymorphism ("one command, many behaviors"): Like pressing 'play' on any device: the same button works, but each device responds in its own way.

  • Why it matters to the business: Together they make software cheaper to change, safer to extend, and easier for teams to work on in parallel.

Q6.
Why do we use getters and setters instead of making fields public, and what is the architectural benefit of this boilerplate?

Junior

Accessors turn a raw field into a controlled entry point: they let you add validation, lazy computation, or change internal representation later without breaking callers, whereas a public field freezes your implementation into the public API.

  • Preserve invariants: A setter can reject invalid input (e.g. negative age), so the object can never enter a bad state.

  • Decouple interface from representation: You can change the backing storage (compute a value, rename, cache) while getX() stays stable.

  • Enable extra behavior: Logging, change notifications, lazy loading, or read-only fields (getter, no setter) become possible.

  • Architectural benefit: A public field is a binding contract: once callers touch it directly, you can't intercept access without breaking them. Accessors keep that seam.

  • Caveat: blind getters/setters on every field are an anti-pattern (an anemic model); expose behavior, not raw state, when you can.

Q7.
How does Encapsulation improve the security and maintainability of a system?

Junior

By restricting access to internal state, encapsulation shrinks the surface area other code can touch or corrupt, which both limits attack/error vectors (security) and localizes change (maintainability).

  • Security / integrity:

    • State can only change through validated methods, so an object can't be forced into an invalid or inconsistent state from outside.

    • Sensitive internals aren't directly reachable, reducing the chance of accidental or malicious tampering.

  • Maintainability:

    • Internals can be refactored freely as long as the public contract holds, so changes stay local instead of rippling across the codebase.

    • A small, well-defined public API is easier to reason about, test, and debug.

  • Reduced coupling: Callers depend on behavior, not layout, so modules evolve independently.

Q8.
Explain the concept of Abstraction using a real-world example other than an ATM or a Car.

Junior

Consider a TV remote: you press "volume up" and the volume rises, but you have no idea about the infrared signals, chip logic, or circuitry involved. The remote exposes a simple interface and hides the complex mechanism, which is exactly abstraction.

  • The exposed interface: Buttons like volumeUp() or changeChannel(): what you can do.

  • The hidden complexity: IR encoding, signal modulation, and the TV's internal decoding: the how, which you never see.

  • Why it matters:

    • The manufacturer can redesign the internals entirely; as long as the buttons behave the same, users are unaffected.

    • In code this maps to a method signature or interface that a client calls without knowing the implementation.

Q9.
What is the difference between data hiding and encapsulation: are they the same thing?

Junior

They are related but not identical: data hiding is the goal (keeping internal state inaccessible from outside), while encapsulation is the broader technique (bundling data with the methods that operate on it, of which access restriction is one part).

  • Encapsulation: bundling + control:

    • Groups state and behavior into one unit and governs how the outside interacts with it.

    • It is a design principle, achievable even without strict access modifiers.

  • Data hiding: the access restriction part:

    • Specifically making fields inaccessible (e.g. marking them private) so they can't be read/written directly.

    • It's a consequence or subset of encapsulation, enforced by the language.

  • The distinction: You could encapsulate (bundle) data that is still publicly visible: that's encapsulation without full data hiding. Strong encapsulation usually implies data hiding.

Q10.
What is the difference between a static member and an instance member, and when is it appropriate to use a static method instead of an instance method?

Junior

An instance member belongs to a specific object and can access that object's state; a static member belongs to the class itself, shared across all instances and callable without any object. Use a static method when the behavior depends on no per-object state.

  • Instance member:

    • Each object has its own copy of instance fields; instance methods can read/write this.

    • Use when behavior varies with object state.

  • Static member:

    • One copy shared by the whole class; accessed via the class name, has no this.

    • Good for stateless utilities, factory methods, and shared constants/counters.

  • When to prefer static:

    • The operation uses only its arguments (e.g. Math.max) and needs no instance data.

    • Caveat: statics are harder to mock/override and can hide global mutable state, so don't overuse them.

Q11.
Explain the purpose of a Constructor. Can a Constructor be inherited or overridden?

Junior

A constructor's purpose is to initialize a new object into a valid state. Constructors are not inherited and cannot be overridden: they are tied to the specific class that declares them.

  • Purpose: Allocate/initialize fields, enforce invariants, and accept required dependencies at creation time.

  • Not inherited: A subclass does not receive its parent's constructors as its own; you must declare the subclass's own constructors (and they call super(...)).

  • Not overridden: Overriding requires the same name and polymorphic dispatch; constructors are name-bound to their class and are not virtual, so they can be overloaded but never overridden.

  • Related caution: Calling an overridable method from a constructor is risky: the subclass override may run before the subclass is fully initialized.

Q12.
What is the difference between a default constructor and a parameterised constructor?

Junior

A default constructor takes no arguments and initializes an object with default or predefined state, while a parameterised constructor accepts arguments to initialize an object with caller-supplied values.

  • Default constructor:

    • No parameters; sets fields to defaults (zero, null, or hard-coded values).

    • In many languages the compiler generates one automatically if you declare no constructor at all.

  • Parameterised constructor:

    • Takes one or more arguments to build an object in a specific, meaningful state.

    • Lets you enforce required fields at creation time so no object exists in an invalid state.

  • Key trap: Once you declare any parameterised constructor, the compiler stops auto-generating the default one; add it explicitly if you still need it.

java

class Point { int x, y; Point() { this.x = 0; this.y = 0; } // default Point(int x, int y) { this.x = x; this.y = y; } // parameterised }

Q13.
What is constructor overloading, and why would a class provide multiple constructors?

Junior

Constructor overloading means defining multiple constructors in the same class with different parameter lists; a class provides them so callers can create objects in several convenient ways while keeping the object valid.

  • What it is:

    • Several constructors distinguished by number, type, or order of parameters (same name, different signature).

    • The compiler picks the right one by matching the arguments at the call site.

  • Why provide multiple:

    • Flexibility: build from full data, partial data, or another object (copy).

    • Sensible defaults: a short constructor fills in defaults and delegates to the fuller one.

  • Best practice:

    • Chain them (e.g. this(...) in Java) so initialization logic lives in one place and stays consistent.

    • When there are many optional fields, prefer a builder over an explosion of overloads.

java

class Rectangle { int w, h; Rectangle() { this(1, 1); } // delegates Rectangle(int side) { this(side, side); } Rectangle(int w, int h) { this.w = w; this.h = h; } }

Q14.
Explain the difference between 'Is-A' and 'Has-A' relationships.

Junior

'Is-A' expresses inheritance (a subtype is a kind of its supertype), while 'Has-A' expresses composition (an object contains or uses another object as a field). They answer different design questions: type identity versus ownership of parts.

  • Is-A (inheritance):

    • A Dog is-a Animal, so Dog extends Animal and inherits its behavior.

    • Should hold to the Liskov principle: the subclass must be usable anywhere the parent is expected.

  • Has-A (composition):

    • A Car has-a Engine, so Car holds an Engine reference as a member.

    • Reuses behavior by delegating to the contained object rather than inheriting it.

  • Guideline: Prefer composition (Has-A) over inheritance (Is-A) when there is no true subtype relationship: it is more flexible and avoids fragile hierarchies.

Q15.
Can you explain the different types of inheritance, single, multilevel, hierarchical, and hybrid?

Junior

These are classifications of how classes derive from one another. Single, multilevel, and hierarchical describe the shape of the class tree, while hybrid combines several forms (often involving multiple inheritance).

  • Single inheritance: One subclass derives from one superclass (B extends A).

  • Multilevel inheritance: A chain of derivation (C extends B, B extends A), so each level adds specialization.

  • Hierarchical inheritance: Multiple subclasses derive from one common superclass (B and C both extend A).

  • Hybrid inheritance:

    • A mix of two or more of the above, frequently combined with multiple inheritance (a class with more than one parent).

    • Can produce the diamond problem, where an ambiguous inherited member comes from two paths.

  • Language note: Java and C# disallow multiple class inheritance (so pure multiple/hybrid needs interfaces); C++ and Python support it directly.

Q16.
What is the difference between Method Overloading and Method Overriding?

Junior

Overloading is defining multiple methods with the same name but different parameter lists in the same class (compile-time), while overriding is redefining an inherited method with the same signature in a subclass to change behavior (runtime).

  • Method overloading:

    • Same name, different parameter types/count/order; return type alone is not enough.

    • Resolved at compile time by the static argument types (static polymorphism).

    • Lives within one class (or an inheritance hierarchy) and is about convenience.

  • Method overriding:

    • Same signature as a superclass method, redefined in a subclass.

    • Resolved at runtime by the object's actual type (dynamic dispatch).

    • Requires an inheritance relationship; enables substitutability.

  • Quick contrast: Overloading = "same name, different arguments, same class." Overriding = "same signature, different class (subclass), new behavior."

java

class Printer { void print(int i) {} // overload void print(String s) {} // overload } class Base { void speak() { System.out.println("base"); } } class Child extends Base { @Override void speak() { System.out.println("child"); } // override }

Q17.
What is 'Method Overriding,' and what happens if a child class calls a method that exists in both the parent and the child?

Junior

Method overriding is when a subclass provides its own implementation of a method already defined in its superclass, using the same signature; when called on an object, the child's version runs due to dynamic dispatch, but the child can still explicitly invoke the parent's version.

  • Definition: Same name, parameters, and compatible return type as the inherited method, replacing its behavior for instances of the subclass.

  • Which method runs: The child's overriding method wins based on the object's actual runtime type, not the reference's declared type (runtime polymorphism).

  • Reaching the parent version: Use super.method() (Java), base.Method() (C#), or super().method() (Python) to call the inherited implementation, often to extend rather than fully replace it.

  • Requirements: The method must be inheritable (not private/final/static in Java) and virtual where required (C# needs virtual + override).

Q18.
At a high level, what is polymorphism and why is it considered central to object-oriented design?

Junior

Polymorphism ("many forms") lets a single interface or call site operate on objects of different types, with the actual behavior selected by the object's real type. It is central to OOP because it lets you write code against abstractions and add new implementations without changing existing callers.

  • Main forms:

    • Subtype (runtime) polymorphism: a base reference invokes overridden methods on derived objects via dynamic dispatch.

    • Parametric polymorphism: generics/templates write one algorithm over many types.

    • Ad-hoc polymorphism: overloading, where the same name has type-specific implementations.

  • Why it's central:

    • Enables the Open/Closed Principle: open for extension (new subtypes) but closed for modification of callers.

    • Decouples "what" from "how": callers depend on an interface, not concrete classes.

    • Replaces sprawling if/switch type checks with clean virtual dispatch.

  • Example: a draw() call on a Shape runs Circle.draw() or Square.draw() depending on the actual object, with no change to the loop that draws them.

Q19.
What is a pure virtual (abstract) method, and how does it force subclasses to provide behaviour?

Junior

A pure virtual (abstract) method is a method declared without an implementation: it defines a contract the class promises but leaves the body for subclasses to supply.

  • It has a signature but no body: Declared with = 0 in C++, abstract in Java/C#, or @abstractmethod in Python.

  • It makes the class abstract: You cannot instantiate a class with an unimplemented pure virtual method; the compiler/runtime forbids it.

  • It forces subclasses to provide behaviour: A concrete subclass must override every abstract method or it too remains abstract and cannot be instantiated.

  • It enables polymorphism: Callers program to the base type and dispatch dynamically to whatever concrete implementation the subclass supplied.

python

from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self) -> float: ... class Circle(Shape): def __init__(self, r): self.r = r def area(self): return 3.14159 * self.r ** 2 # Shape() -> TypeError: can't instantiate abstract class

Q20.
What is the purpose of an object's string representation (toString), and why is overriding it useful?

Junior

An object's string representation (toString in Java, __str__/__repr__ in Python) produces a human-readable description of the object; overriding it makes logs, debugging, and error messages meaningful instead of showing a useless default like a class name plus a hash.

  • Purpose: Gives a concise textual view of an object's identity or state for humans, not the machine.

  • Why the default is unhelpful: Defaults typically print type plus memory reference (e.g. User@1b6d3586), telling you nothing about the actual data.

  • Where overriding pays off:

    • Logging and debugging: variables print their real state.

    • Automatic string contexts: concatenation, formatting, and collection printing all invoke it.

  • Distinguish audiences: Python separates __str__ (friendly, end-user) from __repr__ (unambiguous, developer/debugging).

  • Not for parsing: It's a display aid, not a serialization format: use dedicated serializers (JSON, etc.) for machine round-tripping.

Q21.
How does the lifecycle of an object work, and explain the concept of garbage collection or manual destruction at a high level?

Mid

An object's lifecycle runs from allocation and initialization, through use, to reclamation when it's no longer reachable or needed. Cleanup is either automatic (garbage collection) or manual (explicit destruction), depending on the language.

  • Creation: Memory is allocated, then a constructor initializes the object into a valid state.

  • Use: The object is referenced and its methods/state are exercised while it remains reachable.

  • Destruction / reclamation:

    1. Garbage-collected languages (Java, C#, Python): the runtime reclaims objects that are no longer reachable. Reachability is traced from roots (stack, statics); unreachable objects are freed automatically.

    2. Manual languages (C++): the programmer frees memory (delete), and a destructor runs deterministically; forgetting causes leaks, doing it twice causes corruption.

  • Determinism caveat: GC timing is non-deterministic, so relying on finalizers for resource release is risky; use explicit disposal patterns (try-with-resources, using, with, RAII) for files/sockets.

  • Common GC approaches: Reference counting (frees when count hits zero, but struggles with cycles) and tracing/mark-and-sweep generational collectors.

Q22.
Can you have an object without a class?

Mid

It depends on the paradigm: in class-based languages every object has a class, but in prototype-based and some dynamic languages you can create objects directly without any class definition.

  • Class-based languages (Java, C++, C#): No: every object is an instance of some class, even if it's an anonymous or synthesized one.

  • Prototype-based languages (JavaScript pre-ES6 semantics): Yes: objects are created from other objects (prototypes) or as plain literals ({}), with no class required. class is just syntactic sugar over prototypes.

  • Ad hoc / structural objects: Some languages allow anonymous records or dictionaries acting as objects (bundles of named data + functions) with no named type.

  • Bottom line: The concept "object" (identity + state + behavior) doesn't strictly require the concept "class"; classes are one common mechanism for producing objects, not the only one.

Q23.
What happens conceptually during Object Instantiation?

Mid

Instantiation is the process of turning a class definition into a live object: memory is reserved, the object is wired to its type, fields are initialized, and the constructor runs to leave it in a valid state.

  • Allocation: Enough memory for all instance fields is reserved (typically on the heap).

  • Type binding: A hidden link to the class metadata / vtable is set so the object knows its type and dynamic dispatch works.

  • Default zeroing then initialization: Fields are set to defaults, then field initializers and the constructor assign real values.

  • Constructor execution: Runs setup logic and enforces invariants; base-class constructors run before derived ones.

  • Reference returned: You get back a handle/reference to the initialized object (e.g. via new or calling the class).

Q24.
What is the 'Root Object' concept (e.g., Object class) found in many OO languages?

Mid

Many OO languages define a single universal base type that every class implicitly inherits from, so all objects share a common set of operations and can be treated uniformly as "the most general type."

  • Examples: Java/Kotlin Object/Any, C# System.Object, Python object. C++ notably has no universal root.

  • Why it exists:

    • Guarantees a common interface: methods like toString(), equals(), hashCode() (or __str__, __eq__) are available on any object.

    • Enables generic containers and APIs to hold "any object" before generics or via the root type.

  • Trade-off: Provides uniformity and reflection support, but overly relying on the root type (instead of specific types/generics) weakens type safety.

Q25.
Explain the difference between state, behavior, and identity of an object.

Mid

State is what an object knows, behavior is what it can do, and identity is what makes it distinct from every other object even if their state is identical.

  • State: The current values of its fields/attributes; it changes over time (mutable) or stays fixed (immutable).

  • Behavior: The methods it exposes: operations that read or modify state and let it interact with other objects.

  • Identity:

    • A unique existence independent of state, usually backed by its memory address / reference.

    • Two objects can be equal (same state) yet not identical (different references).

  • The equality distinction: Identity comparison (== on references / is in Python) asks "same object?"; equality (equals()/__eq__) asks "same state?".

Q26.
Explain the order of initialization when an object is instantiated.

Mid

When an object is instantiated, initialization proceeds top-down through the inheritance chain and, within each class, static setup happens once before any instance setup, followed by field initializers and then the constructor body.

  • Static (class-level) initialization: once: Static fields and static initializer blocks run the first time the class is loaded/used, before any instance exists.

  • Per-instance, base before derived:

    1. Memory allocated and fields default-zeroed.

    2. The superclass is fully initialized first (super() / base constructor), all the way up the chain.

    3. Instance field initializers and initializer blocks run in source order.

    4. The class's own constructor body executes.

  • Why order matters: A base constructor runs before the derived object's fields are initialized, so calling an overridden method from a base constructor can see uninitialized derived state (a classic bug).

  • Language variation: Java/C# follow this static-then-base-then-fields-then-constructor order closely; C++ initializes base classes then members in declaration order via initializer lists.

Q27.
What are the primary goals of OOP, and how does it improve modularity, reusability, and maintainability in a large-scale codebase?

Mid

The primary goal of OOP is to manage complexity by modeling a system as cooperating objects with clear boundaries. It improves large codebases by making each unit independently understandable (modularity), shareable (reusability), and safe to change (maintainability).

  • Core goals:

    • Manage complexity through abstraction: expose intent, hide mechanism.

    • Model the problem domain in terms the team can talk about.

  • Modularity:

    • Encapsulation gives each object a well-defined interface, so teams work on parts in parallel without stepping on each other.

    • Well-defined boundaries localize bugs.

  • Reusability:

    • Composition and inheritance let proven objects be reused across features.

    • Polymorphism lets generic code work with new types without modification.

  • Maintainability:

    • Programming to interfaces means internals can change without breaking callers.

    • Changes are localized behind an object's public API, reducing regression risk.

  • Reality check: These benefits come from good design (SOLID, low coupling), not from using classes alone.

Q28.
Explain the concept of 'Message Passing' in OOP.

Mid

Message passing is the idea that objects communicate by sending each other messages (requests to do something) rather than by directly manipulating each other's data. The receiving object decides how to respond, which is the essence of encapsulation and polymorphism.

  • A message is a request, not a command to specific code: The sender says what it wants; the receiver chooses which method actually runs.

  • Late binding: The mapping from message to method can be resolved at runtime, enabling polymorphism: the same message yields different behavior per object.

  • Reinforces encapsulation: Objects interact only through their public message interface, never by poking internal state.

  • Language flavors:

    • Smalltalk and Objective-C model it literally (an object can receive unknown messages and handle them dynamically).

    • In Java/C++ it appears as method calls resolved via v-tables; more static but the same conceptual model.

    • Ruby's method_missing and Python's __getattr__ show the dynamic message idea.

Q29.
What is the difference between Abstraction and Encapsulation? They both hide things, so why do we need both?

Mid

They hide different things for different reasons: abstraction hides complexity (the "what" vs the "how") at the design level, while encapsulation hides data (bundling state with the code that guards it) at the implementation level.

  • Abstraction: hides complexity:

    • Exposes a simplified model (interface) and suppresses irrelevant detail; it answers "what does this do?"

    • A design-time concern: expressed via interfaces, abstract classes, and method signatures.

  • Encapsulation: hides data:

    • Bundles state and behavior together and restricts direct access so invariants stay valid; it answers "how is this protected?"

    • An implementation-time mechanism: expressed via access modifiers like private.

  • Why both are needed:

    • You can encapsulate without abstracting (a private field with a getter, no conceptual model) and abstract without encapsulating (an interface over exposed data).

    • Together: abstraction defines a clean contract, encapsulation protects the internals that fulfill it.

Q30.
Explain the conceptual difference between public, private, and protected access, and why is package-private or internal visibility useful in large systems?

Mid

Access modifiers define who may reference a member: public is open to everyone, private is limited to the declaring class, and protected extends access to subclasses; package-private/internal fills the crucial middle ground of "visible within my module, hidden from the outside world."

  • public: Part of the API contract; any code anywhere can use it, so it's the hardest to change later.

  • private: Only the declaring class sees it; the strongest encapsulation and the safest to refactor.

  • protected: Accessible to subclasses (and often the same package); an extension point for inheritance without going fully public.

  • Why package-private / internal matters:

    • Lets classes in a module collaborate freely while hiding those internals from external consumers.

    • Enables a small, deliberate public surface: you expose only what clients need and keep helper/implementation types invisible, so the module can evolve without breaking outside code.

Q31.
What is an 'Inner Class' (or Nested Class), and when is it conceptually appropriate to use one?

Mid

An inner (nested) class is a class defined inside another class, expressing that the two are tightly coupled; it's appropriate when the nested type only makes sense in the context of its enclosing type and shouldn't clutter the wider namespace.

  • Kinds (Java-style):

    • Non-static inner class: tied to an enclosing instance and can access its private members.

    • Static nested class: a namespaced helper that doesn't need an outer instance.

  • When it's appropriate:

    • The class is a logical helper of the outer class (e.g. a Node inside a LinkedList) and has no independent use.

    • It strengthens encapsulation: implementation-only types stay hidden from the rest of the codebase.

    • For short, one-off behaviors like listeners/callbacks (often anonymous or lambda).

  • Caution: A non-static inner class holds an implicit reference to its outer instance, which can cause memory leaks; prefer static nesting unless you truly need the outer object.

Q32.
What is an anonymous class, and in what situations is it conceptually appropriate to use one?

Mid

An anonymous class is a class with no name, declared and instantiated in a single expression, typically to provide a one-off implementation of an interface or abstract type right where it is needed.

  • What it is: A local, unnamed subclass or interface implementation created inline; you get one instance and never reference the type by name.

  • When it is appropriate:

    • A short, single-use implementation: an event listener, callback, or comparator used in exactly one place.

    • When naming a full class would add noise without adding meaning.

  • When to avoid:

    • If the logic is reused, complex, or needs testing in isolation, give it a real named class.

    • In modern languages a lambda often replaces a functional-interface anonymous class more cleanly.

java

button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("clicked"); } });

Q33.
What is the purpose of a sealed or final class, and when would you prevent a class from being extended?

Mid

A sealed/final class prevents inheritance, guaranteeing that its behavior and invariants cannot be altered by a subclass. You use it when extension would be unsafe or meaningless.

  • Protect invariants: Immutable or security-sensitive types (e.g. String) stay trustworthy because no subclass can break their guarantees.

  • Prevent fragile-base-class problems: If a class was not designed for extension (as the Open/Closed and "design for inheritance or prohibit it" advice says), sealing avoids subclasses depending on internal behavior.

  • Express intent: It documents "this is a complete, self-contained type" and can enable compiler/JIT optimizations (devirtualization).

  • Restricted hierarchies: Some languages' sealed (Kotlin, modern Java) instead means a fixed, known set of subclasses, useful for exhaustive pattern matching.

Q34.
What is the purpose of a constructor, and can you explain constructor chaining and why it is used in inheritance hierarchies?

Mid

A constructor initializes a newly created object, setting its fields to a valid starting state. Constructor chaining is one constructor calling another (in the same class or the parent) so initialization happens once, in order, without duplication.

  • Purpose of a constructor: Establish invariants and required dependencies before the object is used; runs automatically at instantiation.

  • Chaining within a class: An overloaded constructor delegates to a fuller one (this(...) in Java) to avoid repeating initialization logic.

  • Chaining up the hierarchy:

    • A subclass constructor calls the superclass constructor (super(...)) first, so the base part of the object is initialized before the derived part.

    • If you don't call it explicitly, the compiler inserts a call to the no-arg super constructor.

  • Why it matters in inheritance: Guarantees the whole object is fully and correctly built bottom-up, preventing subclasses from operating on uninitialized base state.

java

class Animal { Animal(String name) { /* init base */ } } class Dog extends Animal { Dog(String name) { super(name); // chain to parent first } Dog() { this("unnamed"); // chain to sibling constructor } }

Q35.
Under what circumstances would you define a constructor as private, and what does this achieve conceptually?

Mid

You make a constructor private to take control of how (and whether) instances are created, preventing arbitrary code from calling new. It centralizes object creation behind the class itself.

  • Singleton: Only the class can create the single instance and hand it out via a static accessor.

  • Factory methods: Static creation methods can validate inputs, return cached/subtype instances, and give meaningful names, while the raw constructor stays hidden.

  • Utility/static-only classes: A private constructor prevents instantiation of a class meant to hold only static members.

  • Controlled instances: Enums or a fixed pool of instances, where the set of objects is bounded.

  • Conceptual gain: Encapsulation of construction: the class enforces its own creation rules and invariants at a single point.

Q36.
What is a copy constructor, and when would you use one instead of relying on default copying?

Mid

A copy constructor creates a new object initialized from an existing object of the same type. You use it when the default (shallow, member-by-member) copy would share mutable state or otherwise be incorrect, and you need control over how the copy is made.

  • What it does: Takes an instance of the same class and produces an independent duplicate.

  • When you need one:

    • Deep copy: the object owns mutable references (arrays, collections, pointers) that must be cloned so the copy doesn't alias the original.

    • Resource ownership (C++): managing heap memory, file handles, etc., where a shallow copy would cause double-free or shared-handle bugs.

  • Default copying is fine when: The type holds only value/immutable fields, so a shallow copy is already safe.

  • Language note: C++ provides an implicit copy constructor you can override; Java/C# have no built-in copy constructor and instead use clone() or an explicit copy constructor you write yourself.

cpp

class Buffer { int* data; size_t n; public: Buffer(const Buffer& other) : n(other.n) { data = new int[n]; // deep copy, not shared std::copy(other.data, other.data + n, data); } };

Q37.
What is the concept of a static factory method as a language feature, and how does it differ from using a constructor directly?

Mid

A static factory method is a static method that returns an instance of the class instead of calling the constructor directly; it offers naming, control, and flexibility that a plain constructor cannot.

  • What it is: A static method (e.g. of(), valueOf(), getInstance()) that constructs and returns an object.

  • Advantages over a constructor:

    • Meaningful names: several factories can have descriptive names, unlike constructors that all share the class name.

    • Need not create a new object: can return a cached or shared instance (caching, singletons, pooling).

    • Can return a subtype: the return type can be an interface or subclass, hiding the concrete implementation.

  • Trade-offs:

    • A class with only private constructors and factories cannot be subclassed.

    • Factory methods are harder to spot than constructors, so use conventional names.

java

// Static factory vs constructor Integer a = Integer.valueOf(42); // may return a cached instance List<String> l = List.of("x", "y"); // returns some immutable List impl

Q38.
Explain the difference between association, aggregation, and composition, and how does ownership and lifetime define a composition versus an aggregation?

Mid

All three model 'Has-A' object relationships, but they differ in strength of ownership and lifetime coupling: association is a loose 'uses' link, aggregation is a 'whole-part' with independent lifetimes, and composition is a 'whole-part' where the part cannot outlive the whole.

  • Association:

    • Objects simply reference or use each other with no ownership (a Teacher and a Student).

    • Lifetimes are fully independent.

  • Aggregation (weak 'has-a'):

    • A whole holds parts it does not own; a Department has Professors, but professors exist without the department.

    • Parts are usually passed in from outside and can be shared among multiple wholes.

  • Composition (strong 'has-a'):

    • The whole owns and controls its parts; a House has Rooms that have no meaning without it.

    • The whole typically creates the parts, and when it is destroyed the parts are destroyed too.

  • Ownership and lifetime as the deciding test:

    • Ask: if the whole is destroyed, do the parts die with it? Yes means composition, no means aggregation.

    • Ask: who creates the part? If the whole creates it internally it leans composition; if it is injected from outside it leans aggregation.

Q39.
Explain the is-a relationship, and what are the risks of creating an inheritance hierarchy that is too deep?

Mid

The is-a relationship means a subclass is a specialized kind of its superclass and can substitute for it; inheritance expresses this. But making hierarchies too deep couples classes tightly and makes them fragile and hard to reason about.

  • Is-a explained:

    • A SavingsAccount is-a Account, so it inherits state and behavior and can be used wherever an Account is expected.

    • Must satisfy the Liskov Substitution Principle: the subtype must honor the contract of the parent.

  • Risks of deep hierarchies:

    • Fragile base class: a change high up ripples down and can break many descendants.

    • Hard to understand: behavior is scattered across many levels, so you must trace the whole chain to know what an object does.

    • Tight coupling and rigidity: subclasses inherit everything, even things they do not need, making change costly.

    • Forced fit: real concepts rarely form clean deep trees, tempting misuse of inheritance where composition fits.

  • Guideline: Keep hierarchies shallow and favor composition or interfaces to add behavior.

Q40.
What is the difference between Aggregation and Composition in terms of object lifetime?

Mid

Both are 'whole-part' relationships, but they differ in lifetime coupling: in composition the part's lifetime is bound to the whole, whereas in aggregation the part lives independently of the whole.

  • Composition (dependent lifetime):

    • The whole owns the part and usually creates it; when the whole is destroyed, the part is destroyed too.

    • Example: an Order and its OrderLine items: the lines do not exist without the order.

  • Aggregation (independent lifetime):

    • The whole references parts it does not own; destroying the whole leaves the parts alive.

    • Example: a Playlist and its Songs: songs continue to exist and can belong to other playlists.

  • Quick test: If the parts are meaningless once the whole is gone, it is composition; if they carry on independently, it is aggregation.

Q41.
Why can a class implement multiple interfaces but not inherit from multiple classes in many languages?

Mid

Interfaces only declare a contract (method signatures) with no state or implementation, so combining many is unambiguous; classes carry state and implementation, so inheriting from several creates conflicts the compiler cannot resolve.

  • The diamond problem: If two parent classes both provide the same method or field, which one does the child get? Multiple class inheritance makes this ambiguous.

  • Interfaces avoid the ambiguity:

    • Traditionally they had no implementation or fields, so implementing two interfaces with the same method signature still means just one method to define.

    • There is no conflicting state or behavior to merge.

  • State is the real problem, not method count: Multiple base classes could each hold their own copy of fields, complicating layout, initialization, and identity.

  • Caveat: default methods blur the line: Java default methods and C# interface implementations reintroduce mild diamond issues, which languages resolve by forcing the class to override the conflict explicitly.

  • Alternative: C++ allows multiple class inheritance: It exists but requires virtual inheritance to tame the diamond, which is exactly the complexity most languages chose to avoid.

Q42.
What is a dependency relationship between classes, and how does it differ from an association?

Mid

A dependency is a weak, transient "uses" relationship: one class relies on another only momentarily (e.g., as a method parameter or return type), whereas an association is a stronger structural link, usually a field, that persists over the object's lifetime.

  • Dependency ("uses-a"):

    • Class A uses class B temporarily: B appears as a local variable, argument, or return value.

    • Change in B may affect A, but A does not hold a reference to B long-term.

    • UML: dashed arrow from A to B.

  • Association ("has-a"):

    • A structural relationship where A keeps a reference to B (typically a field).

    • Persists across method calls and has multiplicity (one-to-one, one-to-many).

    • UML: solid line, optionally with arrowhead for navigability.

  • Rule of thumb: If removing the parameter still leaves the relationship (because it is stored), it is an association; if the link vanishes when the method returns, it is a dependency.

Q43.
How do UML class diagrams represent relationships like inheritance, composition, and association, including multiplicity?

Mid

UML uses distinct line and arrowhead styles for each relationship, and multiplicity numbers at the line ends state how many instances participate.

  • Inheritance / generalization:

    • Solid line with a hollow triangle arrowhead pointing to the parent ("is-a").

    • Interface realization uses the same triangle but a dashed line.

  • Association: Plain solid line; an open arrowhead shows navigability direction.

  • Aggregation vs composition (both "has-a"):

    • Aggregation: hollow diamond at the whole. The part can outlive the whole (a Team and its Players).

    • Composition: filled diamond at the whole. Strong ownership; parts die with the whole (a House and its Rooms).

  • Dependency: Dashed line with open arrowhead ("uses-a").

  • Multiplicity (at each line end):

    • 1 exactly one, 0..1 optional, * or 0..* many, 1..* one or more.

    • Example: an Order end marked 1 and a LineItem end marked 1..* means one order has one or more line items.

Q44.
Explain the difference between compile-time (static) and runtime (dynamic) polymorphism with a conceptual example of each.

Mid

Compile-time polymorphism is resolved by the compiler based on static type/signature (method overloading), while runtime polymorphism is resolved during execution based on the object's actual type (method overriding via virtual dispatch).

  • Compile-time (static) polymorphism:

    • The compiler picks the target method by matching argument types at compile time.

    • Achieved by overloading (and, in some languages, generics/templates).

    • Example: print(int) vs print(String): which runs is decided by the argument's declared type.

  • Runtime (dynamic) polymorphism:

    • The actual runtime object determines which overridden method executes.

    • Achieved by overriding through inheritance and virtual methods.

    • Example: Shape s = new Circle(); s.area(); calls Circle's area() even though the reference is typed as Shape.

  • Core distinction: Static: same name, different signatures, chosen by the compiler. Dynamic: same signature, different implementations, chosen at runtime.

Q45.
What is method overriding, and how does it differ from method hiding or shadowing?

Mid

Overriding replaces a superclass's method for the actual object type via dynamic dispatch, so the subclass version runs regardless of the reference type; hiding (shadowing) happens with static/non-virtual members or fields, where the reference's declared type, not the object, decides which is used.

  • Overriding (virtual, runtime):

    • Subclass provides a new body for a virtual/instance method with the same signature.

    • The runtime object's type is what gets dispatched, so it is truly polymorphic.

  • Hiding / shadowing (static, compile-time):

    • Occurs with static methods, fields, or non-virtual methods that share a name in a subclass.

    • There is no dispatch: the declared (compile-time) type of the reference decides which member is accessed.

    • In C# you signal intent with new; in Java a subclass field or static method with the same name hides the parent's.

  • The telltale difference: With overriding, casting the reference to the parent type still calls the child method; with hiding, casting changes which member you see.

Q46.
What is the difference between Upcasting and Downcasting, and what are the risks of the latter?

Mid

Upcasting treats a derived object as its base type and is always safe and implicit; downcasting converts a base reference back to a derived type and is risky because the object may not actually be that derived type.

  • Upcasting (derived to base):

    • Implicit and always valid: a Dog is-a Animal, so the reference is guaranteed compatible.

    • You lose static access to derived-only members, but virtual methods still dispatch to the real type.

  • Downcasting (base to derived):

    • Explicit and only safe if the object really is that subtype at runtime.

    • Used to regain access to members specific to the subclass.

  • Risks of downcasting:

    • A wrong cast fails at runtime (ClassCastException in Java, InvalidCastException in C#), bypassing compile-time safety.

    • It often signals a design smell: heavy downcasting usually means polymorphism should be used instead.

  • Safe practice: Guard with a type check before casting: instanceof / is, or use pattern matching / as which yields null instead of throwing.

Q47.
What is a 'Virtual Method' conceptually, and how does 'Late Binding' work?

Mid

A virtual method is one whose implementation is selected based on the object's actual runtime type rather than the reference's compile-time type; late binding is the mechanism that resolves that call at runtime instead of at compile time.

  • Virtual method (concept):

    • Declares an overridable point in behavior: subclasses can substitute their own version, and callers get the most-derived implementation.

    • In Java methods are virtual by default; C++/C# require virtual.

  • Late binding (how it works):

    • The compiler doesn't hardcode the target address; instead the correct method is looked up when the call executes.

    • Commonly implemented with a virtual method table (vtable): each object references a table of function pointers, and a virtual call indexes into it at runtime.

  • Why it matters:

    • It enables subtype polymorphism: code written against a base type automatically uses subclass behavior.

    • Small cost: an indirection per call and it can inhibit inlining, which is why non-virtual methods can be faster.

Q48.
What are the rules for method overloading versus overriding, and can you overload a method by changing only the return type?

Mid

Overloading defines multiple methods with the same name but different parameter lists in the same scope (resolved at compile time), while overriding replaces an inherited method with an identical signature (resolved at runtime). You cannot overload by changing only the return type, because the compiler picks overloads by arguments, not return value.

  • Overloading rules:

    • Same name, different parameter count/types/order; return type and modifiers may differ but are not enough on their own.

    • Resolved by the compiler based on argument types (static/early binding). Also called ad-hoc polymorphism.

  • Overriding rules:

    • Same signature as the inherited method; return type must be identical or covariant.

    • Access can't be more restrictive, and the exception list can't broaden (Java checked exceptions). Resolved at runtime.

  • Return-type-only overload: Not allowed: two methods differing only by return type are ambiguous, since a call like foo() gives the compiler no way to choose.

java

// Overloading (compile-time): different parameters int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } // ILLEGAL: differ only by return type // int process() { ... } // long process() { ... } // compile error

Q49.
Explain the concept of 'Subtype Polymorphism' without using code.

Mid

Subtype polymorphism is the ability to treat objects of different derived types uniformly through a common supertype (a base class or interface), where each object responds to the same request in its own way. The caller depends only on the shared contract and never needs to know the concrete type.

  • Core idea: One interface, many implementations: a single operation name behaves differently depending on the actual object receiving it.

  • Substitutability: Anywhere the supertype is expected, any subtype can be supplied (the Liskov Substitution Principle).

  • Analogy: A manager tells different employees to "submit your report." Each does it their own way; the manager issues one instruction without knowing each person's method.

  • Benefit: Code is open to new subtypes without modification: add a new implementation and existing callers work unchanged.

Q50.
What is the difference between 'Early Binding' and 'Late Binding'?

Mid

Early binding resolves which method or member a call refers to at compile time, while late binding defers that resolution until runtime based on the object's actual type. Late binding is what makes polymorphic (virtual) method calls possible.

  • Early binding (static):

    • The target is fixed at compile time: applies to non-virtual methods, static methods, overloaded methods, and field access.

    • Faster and inlinable, but no runtime substitution of behavior.

  • Late binding (dynamic):

    • The target is chosen at runtime from the object's actual type, typically via a vtable lookup.

    • Enables overriding and subtype polymorphism at a small indirection cost.

  • Key distinction:

    • Overloading uses early binding (chosen by argument types); overriding uses late binding (chosen by runtime type).

    • Dynamically typed languages (Python, Ruby) resolve almost all calls late.

Q51.
What is the difference between an Abstract Class and an Interface, and when would you choose one over the other?

Mid

An abstract class is a partially implemented base that shares state and behavior with its subclasses (an "is-a" relationship), while an interface is a pure contract of capabilities that unrelated types can implement (a "can-do" relationship). Choose an abstract class to share code among closely related types; choose an interface to define a capability across unrelated types.

  • Abstract class:

    • Can hold fields/state, constructors, and concrete method implementations alongside abstract ones.

    • A class typically extends only one (single inheritance of implementation).

    • Best when subtypes share substantial common code and a common identity.

  • Interface:

    • Traditionally declares method signatures with no state (constants aside).

    • A class can implement many, so it models multiple independent capabilities.

    • Best for defining a role/contract that varied, unrelated classes can fulfill (e.g. Comparable, Serializable).

  • Rule of thumb:

    • Need shared implementation/state and one clear hierarchy: abstract class.

    • Need to plug a capability into many types, or need "multiple inheritance" of type: interface.

Q52.
What is a 'Marker Interface,' and what is its purpose if it has no methods?

Mid

A marker interface is an empty interface (no methods, no fields) whose mere implementation "tags" a class with metadata: the presence of the type itself signals a capability or intent that other code checks at runtime.

  • How it conveys meaning:

    • Code queries the tag with a type check (instanceof) and then enables special handling.

    • Classic examples: Serializable (JVM permits serialization), Cloneable (Object.clone() is allowed).

  • Why use one instead of no marker: It attaches a type-safe, checkable attribute at the type level that the compiler and runtime understand.

  • Modern alternative: Annotations/attributes (@Annotation) now often replace markers, since they carry data and don't affect the type hierarchy; markers remain useful when you want the tag to participate in the type system (e.g. usable as a bound).

Q53.
What does it mean to say an interface is a contract, and how does this facilitate decoupled development between teams?

Mid

Saying an interface is a contract means it specifies what operations are available (names, parameters, return types, and expected behavior) without dictating how they are implemented. Callers rely on the contract, implementers fulfill it, and neither needs to know the other's internals.

  • Two sides of the contract:

    • Consumers program to the interface, trusting the promised behavior.

    • Providers guarantee that behavior (including semantics/pre- and post-conditions, not just signatures).

  • How it decouples teams:

    • Once the interface is agreed, both sides work in parallel against it.

    • The consumer team can develop and test against a mock/stub implementing the interface before the real one exists.

    • Implementations can be swapped or upgraded without touching callers, as long as the contract holds.

  • Design payoff: Enables dependency inversion: high-level code depends on the abstraction, and concrete details are injected.

Q54.
Can an Interface have a constructor? Why or why not?

Mid

No, a traditional interface cannot have a constructor, because it can't be instantiated and holds no instance state to initialize. A constructor's job is to build and initialize an object, and an interface is never itself an object.

  • Why it makes no sense:

    • Interfaces (classically) declare no instance fields, so there is nothing for a constructor to set up.

    • You never write new SomeInterface(); you instantiate a concrete class that implements it.

  • What actually happens:

    • The implementing class's own constructor runs to initialize its state.

    • An interface's constants are static and initialized at the type level, not per object.

  • Contrast with abstract classes: An abstract class can have a constructor (invoked via super() by subclasses) precisely because it can carry state, even though it also can't be instantiated directly.

Q55.
Why is it often said that you should favour composition over inheritance, and what are the specific trade-offs in flexibility?

Mid

Favour composition over inheritance because composition assembles behaviour from independent parts through their interfaces, giving flexibility and encapsulation, whereas inheritance welds a subclass to a base class's implementation for the life of the program.

  • Inheritance is rigid:

    • The relationship is fixed at compile time; you cannot change a base class at runtime.

    • It exposes the base's internals (fragile base class) and forces a single "is-a" axis of variation.

  • Composition is flexible:

    • Swap collaborators at runtime by injecting a different implementation (strategy pattern).

    • Combine behaviours from many sources without a rigid hierarchy or multiple-inheritance conflicts.

  • Encapsulation is preserved: You depend only on a collaborator's public interface, not its internals, so changes stay contained.

  • The trade-offs:

    • Composition adds indirection and more wiring/boilerplate (delegation methods, constructor injection).

    • Inheritance is genuinely appropriate for true "is-a" relationships with stable, well-designed base classes.

  • Rule of thumb: use inheritance for "is-a", composition for "has-a" or "uses-a".

Q56.
Explain the concept of substitutability: why should a derived class be able to stand in for its base class without breaking the program?

Mid

Substitutability (the Liskov Substitution Principle) says an object of a derived class must be usable anywhere its base class is expected without changing the program's correctness: the subtype must honour the promises callers rely on.

  • Why it matters:

    • Polymorphism depends on it: code written against the base type must behave correctly for every subtype it receives.

    • Violations force callers to add type checks (if instanceof), which defeats abstraction.

  • Behavioural contract, not just signatures:

    • A subtype may not strengthen preconditions (demand more) or weaken postconditions (deliver less).

    • It must preserve invariants and not throw new unexpected exceptions.

  • Classic violation: A Square extending Rectangle: setting width independently of height breaks code that assumes a rectangle's sides vary freely.

  • Practical payoff: When honoured, you can extend a system with new subtypes without touching existing client code (open/closed).

Q57.
What does it mean for two objects to be 'Tightly Coupled,' and how does OOP help achieve 'Loose Coupling'?

Mid

Two objects are tightly coupled when one depends on the concrete details of the other, so a change in one forces a change in the other; loose coupling means they interact through stable abstractions so each can change independently.

  • Signs of tight coupling:

    • A class instantiates its collaborators directly (new PaymentGateway()) or reaches into their internal fields.

    • It knows a concrete type's structure, so it breaks when that type changes.

  • How OOP achieves loose coupling:

    • Program to interfaces/abstractions, not concrete classes.

    • Dependency injection: pass collaborators in rather than creating them internally.

    • Encapsulation hides internals behind a public contract, limiting what others can depend on.

    • Polymorphism lets you substitute implementations without callers noticing.

  • Why it pays off: Easier testing (inject mocks/stubs), independent evolution, and safer refactoring.

java

// Tight: hard-wired to a concrete class class OrderService { private StripeGateway gw = new StripeGateway(); } // Loose: depends on an abstraction, injected in class OrderService { private final PaymentGateway gw; OrderService(PaymentGateway gw) { this.gw = gw; } }

Q58.
How do you identify potential classes and responsibilities from a set of requirements?

Mid

A common starting technique is noun-verb analysis: scan the requirements for nouns as candidate classes and verbs as candidate responsibilities/methods, then refine by grouping related data and behaviour and discarding what isn't relevant.

  • Find candidate classes (nouns):

    • Underline nouns and noun phrases: Customer, Order, Invoice.

    • Discard synonyms, vague terms, and nouns that are really attributes (e.g. "name" is a field, not a class).

  • Find responsibilities (verbs): Verbs suggest behaviour: "place an order", "calculate total" become methods and hint who owns them.

  • Assign responsibilities with CRC:

    • Use Class-Responsibility-Collaborator cards to decide which class owns each responsibility and whom it collaborates with.

    • Apply information expert: give a responsibility to the class that holds the data it needs.

  • Refine against principles:

    • Aim for high cohesion (each class one clear purpose) and single responsibility; split classes doing too much.

    • Iterate: initial candidates are a first draft, not final design.

Q59.
What does 'High Cohesion' mean for a class, and why is it desirable?

Mid

High cohesion means a class's members (data and methods) are all focused on a single, well-defined responsibility: everything in the class genuinely belongs together and works toward one purpose.

  • What it looks like:

    • Methods operate on the same core data and serve one clear concept (a Invoice handles invoice logic only).

    • The class is easy to name in one sentence without "and".

  • Low cohesion (the anti-pattern): A "god class" or utility grab-bag mixing unrelated jobs (parsing, logging, DB access, and UI in one place).

  • Why it is desirable:

    • Understandability: a focused class is easy to read and reason about.

    • Maintainability: changes are localised, reducing ripple effects and bugs.

    • Reusability and testability: a single-purpose unit is easy to reuse and test in isolation.

  • Relationship to coupling: High cohesion tends to produce loose coupling; together they are the hallmark of good modular design (closely tied to the Single Responsibility Principle).

Q60.
In the context of object design, what does it mean to have high cohesion and low coupling, and why is this the gold standard?

Mid

High cohesion means a class or module focuses on a single, well-defined responsibility, while low coupling means it depends minimally on the internals of other components. Together they produce systems that are easy to understand, change, and test in isolation.

  • High cohesion:

    • All the parts of a class relate to one purpose, so it has a single reason to change (aligns with the Single Responsibility Principle).

    • Low cohesion is a "god class" doing unrelated jobs: hard to name, hard to reuse.

  • Low coupling:

    • Components interact through small, stable interfaces rather than reaching into each other's internals.

    • A change in one class doesn't ripple across many others.

  • Why it's the gold standard: Changes stay local, testing is easier (fewer collaborators to mock), and components are reusable and replaceable.

  • They work together: Cohesion decides what belongs inside a unit; coupling decides how units connect. Pursue both, not one at the expense of the other.

Q61.
How do you decide what should be a class versus what should be an attribute when modeling a real-world system?

Mid

Make something a class when it has its own identity, behavior, and lifecycle worth modeling; make it an attribute when it's just a value or property that describes another thing. The deciding questions are whether it does anything and whether it needs to be referenced independently.

  • Signs it should be a class:

    • It has behavior (methods) and enforces its own rules or invariants.

    • It has identity and lifecycle: created, changed, and referenced on its own.

    • It groups several related attributes that always travel together (e.g. an Address with street, city, zip).

  • Signs it should be an attribute:

    • It's a simple value describing the owner (a name, a count, a color) with no behavior of its own.

    • It has no meaning independent of its container.

  • Grammar heuristic: Nouns in the domain often become classes; adjectives and descriptive facts often become attributes.

  • Let it evolve: An attribute that starts sprouting rules and related data is a hint to promote it into its own class ("primitive obsession" is the anti-pattern to watch for).

Q62.
What is the difference between a Shallow Copy and a Deep Copy when cloning an object?

Mid

A shallow copy duplicates the top-level object but shares the same referenced sub-objects, while a deep copy recursively duplicates everything so the copy is fully independent. The difference only matters when the object contains references to other mutable objects.

  • Shallow copy:

    • Copies the outer object's fields; reference fields still point to the same nested objects.

    • Mutating a shared nested object shows up in both copies (a common source of bugs).

  • Deep copy:

    • Recursively clones nested objects, so the copies share nothing.

    • More expensive, and must handle cycles and non-copyable resources (file handles, sockets).

  • When it doesn't matter: If the object only holds immutable values, shallow and deep are effectively equivalent.

python

import copy original = {"tags": ["a", "b"]} shallow = copy.copy(original) deep = copy.deepcopy(original) original["tags"].append("c") print(shallow["tags"]) # ['a', 'b', 'c'] -> shared list print(deep["tags"]) # ['a', 'b'] -> independent

Q63.
Explain the concept of 'Object Equality' versus 'Object Identity.' How do they differ?

Mid

Object identity asks "are these the same object in memory?" while object equality asks "do these objects represent the same value?" Two distinct objects can be equal without being identical.

  • Identity:

    • Compares references: same location in memory. In Java that's ==, in Python is.

    • Always true for an object compared to itself.

  • Equality:

    • Compares logical value, defined by the type via equals() (Java) or __eq__ (Python).

    • Two separately constructed objects with the same contents can be equal but not identical.

  • Key relationship:

    • Identity implies equality, but equality does not imply identity.

    • Default equals() is often identity-based until you override it to compare fields.

python

a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True -> equal values print(a is b) # False -> different objects

Q64.
What is an immutable object, and what are the benefits of designing classes to be immutable by default?

Mid

An immutable object is one whose state cannot change after construction: any "modification" returns a new object instead. Designing for immutability by default eliminates entire categories of bugs around shared, changing state.

  • What makes an object immutable:

    • All fields set at construction and never reassigned (final / read-only), with no mutating methods.

    • Defensive copies of any mutable inputs so callers can't mutate internals through a shared reference.

  • Benefits:

    • Thread-safe by default: no shared state to guard with locks.

    • Safe to share, cache, and use as map/set keys since their hash and equality never change.

    • Easier to reason about: no "who changed this?" surprises, no defensive copying on every read.

  • Cost: Frequent updates create new objects, which can add allocation overhead (often mitigated with builders or persistent data structures).

Q65.
What is the contract between equals and hashCode, and why must two 'equal' objects produce the same hash code?

Mid

The contract says that if two objects are equal according to equals(), they must return the same hashCode(). This is required because hash-based collections use the hash code to pick a bucket first, and only compare with equals() within that bucket.

  • The rules:

    1. Equal objects must have equal hash codes.

    2. Unequal objects should ideally have different hash codes (for performance, not required).

    3. The hash code must stay consistent while the object's equality-relevant state is unchanged.

  • Why the direction matters: A HashMap locates a key by its hash code, then confirms with equals(). If two equal objects hash differently, they land in different buckets and the lookup never finds the match.

  • Practical consequences:

    • Always override both together, using the same fields in each.

    • Never base the hash on mutable fields you'll change while the object is in a hash-based collection.

Q66.
What is the purpose of generics in OOP, and how do they improve type safety without sacrificing reusability?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q67.
What is operator overloading conceptually, and what are the risks of abusing it?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q68.
What is a finalizer or destructor conceptually, and why are finalizers considered unreliable for resource cleanup?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q69.
What are the common criticisms of the object-oriented paradigm?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q70.
What are the trade-offs of using OOP, and in what scenarios might a different paradigm like functional or procedural be more effective?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q71.
What is the 'Message Passing' view of OOP versus the 'Method Call' view?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q72.
Can a class be both Abstract and Final? Why or why not?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q73.
What is name mangling, and what problem does it solve in the context of overloading or private members?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q74.
What is the conceptual difference between class-based and prototype-based object orientation?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q75.
Explain the concept of 'Dynamic Dispatch' or 'Late Binding'.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q76.
Explain 'Covariance' and 'Contravariance' in the context of method overriding and return types.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q77.
What is the difference between subtype, parametric, and ad-hoc polymorphism?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q78.
How does Run-Time Type Information (RTTI) allow a program to determine an object's actual type at runtime?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q79.
What is method resolution order as a concept, and why does it matter when a method exists at multiple levels of a hierarchy?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q80.
How do 'Default Methods' in interfaces change the traditional definition of an interface?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q81.
What is the difference between a default (interface) method and a regular abstract method, and how do default methods affect interface evolution?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q82.
What is the fragile base class problem, and how does it affect the long-term maintenance of a system?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q83.
What are the tradeoffs of using deep Inheritance hierarchies?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q84.
Explain the gorilla-banana problem in inheritance.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q85.
What is 'Reflection' (or Introspection) in OOP, and what are its use cases and risks?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q86.
What is the 'Diamond Problem' in multiple inheritance, and how do different languages conceptually resolve it?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q87.
What are mixins or traits conceptually, and how do they provide a middle ground for languages that don't support multiple inheritance?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q88.
What is the purpose of a Virtual Destructor?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q89.
What is virtual inheritance conceptually, and what problem in inheritance hierarchies is it meant to address?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.