Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Dart (3.13) Module 9

Inheritance, mixins, class modifiers and extensions interview questions

Interview questions on inheritance, mixins, class modifiers and extensions: warm-ups, then what each harder question tests and how a good answer starts.

18 questions: 4 warm-ups and 14 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher

    When should you use implements instead of extends in Dart?

    Answered in the lesson Inheritance, abstract classes and interfaces

  2. Fresher to mid

    What is the difference between final class and sealed class in Dart, and when do you choose each?

    Both prevent extending and implementing outside the library, but sealed also prevents constructing and makes the class implicitly abstract. Choose final when you want users to use instances but never subtype them, such as a Money value type. Choose sealed when you want the compiler to know every subtype for exhaustive switches, such as a PaymentResult with Success and Failure subtypes in the same library. A final class Money can be constructed; a sealed class PaymentResult cannot, and its subtypes must appear in the same library.

    From the lesson Class modifiers: base, interface, final, sealed

  3. Fresher

    In Dart 3, when must a type be declared with mixin or mixin class rather than class?

    Answered in the lesson Mixins and the mixin class

  4. Fresher to mid

    A shop has four order statuses (placed, packed, shipped, delivered) with no data attached. Would you model them as an enum or as a sealed class, and what changes if Cancelled has to carry a refund amount?

    An enum fits: the four are plain values, and a switch over an enum must list every constant. Once Cancelled alone needs a refund amount, an enum constant cannot hold it, because every constant of an enum has the same fields. Move to a sealed class with a final subclass per status; Cancelled gets its own refundPaise, a switch binds it with Cancelled(:final refundPaise), and the compiler still lists every switch that forgets a status.

    From the lesson Sealed classes and exhaustive switches

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Mid to senior

    A Dart library ships a Logger that most apps extend and override one method of. One team wants a stricter contract: no subclass may skip a method, and no app may call Logger directly. Compare an abstract class, an interface class and an abstract interface class, and say what each costs the library and its users.

    What it tests
    Knowing that an abstract class may still carry concrete bodies, that interface class forbids extends from outside the library, and that abstract interface class gives the strictest shape; and how each choice affects evolution.
    First step
    Write down what Logger has today: a few abstract methods and a few concrete helpers that most subclasses reuse. Then ask what the team's "stricter contract" means in Dart terms: no instantiation (abstract), no reuse of bodies (every method abstract), and no extends from outside (interface class). The combination picks the modifier.
    Follow-ups

    From the lesson Inheritance, abstract classes and interfaces

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  2. Mid to senior

    A support app routes a message to one of three channels at run time. Draft one is a Notifier with an if/else over an enum; draft two an inheritance tree of SmsNotifier, EmailNotifier and WhatsAppNotifier; draft three a Dispatcher holding a Map<Channel, Notifier> that delegates. Which would you ship, and where does each fail first?

    What it tests
    Knowing why a tagged if/else and a wide inheritance tree are both hard to extend, and how composition keeps each channel a short, testable class the dispatcher looks up by key.
    First step
    List the forces: three channels today, more later; each channel's send has its own quirks; tests must not call a real gateway. Then ask which design lets a new channel ship without editing a shared method, and which lets a test swap in a fake with a one-line change.
    Follow-ups

    From the lesson Inheritance, abstract classes and interfaces

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  3. Mid to senior

    A payments library published version 1.0.0 with an open Gateway class. Some users extend it, others implement it. You want to add interface to Gateway in the next release. Plan the migration so that users have time to adapt, and explain which code breaks and when.

    What it tests
    Knowing that adding a modifier is a breaking change, how @Deprecated.extend() warns users before the break, and what semantic versioning says about the version numbers.
    First step
    List who breaks: users who extend Gateway will see compile errors when interface is added. Users who only implement it are fine because interface allows implementing. Start by deprecating the extending.
    Follow-ups

    From the lesson Class modifiers: base, interface, final, sealed

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  4. Mid to staff

    Your library exports base class Ledger. A user's code compiles today with class AppLedger extends Ledger. In a new release you add a private method _auditEntry() that record() calls. Does the user's code still compile, and if not, what do they see?

    What it tests
    Knowing that base transitivity requires subtypes to be base, final, or sealed, how the compiler enforces this, and what happens to existing code that extends a base class without the marker.
    First step
    Recall what base transitivity enforces: any subtype of a base class must itself be marked base, final, or sealed. Check whether the user's class AppLedger has such a marker.
    Follow-ups

    From the lesson Class modifiers: base, interface, final, sealed

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Senior to staff

    You maintain a Dart package with a class that users extend, implement, and mix in. You want to restrict it to implementing only. Describe the deprecation and release sequence, naming the exact annotation constructors available since Dart 3.10 and what each one warns about.

    What it tests
    Knowing the @Deprecated constructors for subtyping (extend, implement, mixin, subclass), what each warns about, and how to combine them with semantic versioning for a multi-release migration.
    First step
    List the subtype relationships you need to forbid: extending and mixing in, but not implementing. Then map each to the @Deprecated constructor that warns about it.
    Follow-ups

    From the lesson Class modifiers: base, interface, final, sealed

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Mid to senior

    Four services and three repositories need the same log, metrics and retry behaviour. Draft one is a base class LoggedRetrying the seven extend; draft two is three mixins the seven list in with; draft three is a Pipeline that wraps every call. Which would you ship, and where does each fail first?

    What it tests
    Knowing when "has-a" beats "is-a", when a mixin layered left to right beats a parent, and how composition through a wrapper differs from both at the API that callers see.
    First step
    Write down the shared behaviours and ask whether the services and repositories are of one kind. They are not; the base class forces them under one parent for behaviours none of them owns. Then ask whether a new behaviour should be opt-in by host (a mixin), applied to every host at once (a parent) or wrap each call from outside (composition).
    Follow-ups

    From the lesson Mixins and the mixin class

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 5 minutes
  7. Senior to staff

    A payments service uses class Pay extends GatewayBase with Log, Metrics, Retry. A new "verify after retry" check runs twice for every retry, and the team suspects the super chain. Walk through how you would read the order, the measurement you would take to confirm it, and the one-token fix if the chain is wrong.

    What it tests
    Knowing that the with list reads left to right but applies bottom to top, that super from each mixin goes to the next slot below in the linearization, and how a measurement proves which body runs between two sends.
    First step
    Read the with list: Log, Metrics, Retry puts Retry on top, with Metrics below it and Log at the bottom just above the base. So a call on Pay().charge(...) starts at Retry.send, which calls super.send into Metrics, which calls super.send into Log, which calls super.send into GatewayBase. The team's hunch, "verify runs twice", fits Retry over Metrics: Metrics.send runs on every retry, so a counter inside it doubles when Retry loops.
    Follow-ups

    From the lesson Mixins and the mixin class

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 5 minutes
  8. Mid to senior

    The team asks why mixin Metrics on Notifier cannot take a MetricsClient in its constructor. Explain what Dart forbids there and show two patterns that keep every host independent: the mixin's own abstract getter, and a static Metrics.of lookup. Say which you would ship and why.

    What it tests
    Knowing that a mixin may declare no generative constructor, how an abstract getter lets the host supply the state it needs, and when a service locator inside the mixin beats a getter on every host.
    First step
    Dart's rule is one line: a mixin or mixin class may not declare a generative constructor (dart.dev/language/mixins). no_ctor.dart in the lesson shows the exact error, "Mixins can't declare constructors." The design question is then where the MetricsClient should come from, and the two usual answers are the host (through an abstract getter) and the environment (through a static lookup on the mixin or its own package).
    Follow-ups

    From the lesson Mixins and the mixin class

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 5 minutes
  9. Mid to senior

    A pipeline stores rows as List<dynamic> and calls rows.first.toUpperCase() on each batch. Upstream starts sending ints alongside strings, and the crash says NoSuchMethodError. A colleague suggests an extension on Object with toUpperCase. Explain why that fix cannot work here, what the real cause is, and how you would redesign the pipeline to fail earlier.

    What it tests
    Knowing that extensions are resolved by static type, not runtime type, why an extension on Object still does not apply to a variable typed dynamic, and how moving the type boundary earlier surfaces type errors at compile time.
    First step
    Start with what the compiler sees: rows.first has static type dynamic, and extensions are picked at compile time by static type. No extension applies to dynamic, no matter what type it extends. The call becomes a dynamic dispatch that fails when the object has no toUpperCase.
    Follow-ups

    From the lesson Extension methods in Dart

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  10. Mid to senior

    A Flutter app imports two packages that each define extension ParseHelpers on String with a toDateTime(). One parses ISO 8601, the other parses dd-MM-yyyy. Different screens need different formats. How do you use both extensions without renaming either package, and how do you organise imports so each screen gets the right parser?

    What it tests
    Knowing that two extensions with the same name and same member cause an ambiguity error, how explicit application with ExtensionName(value).method() selects one extension, how import prefixes qualify extension names, and how file-level import strategies keep each screen unambiguous.
    First step
    Identify the conflict: both libraries export ParseHelpers with toDateTime(). Importing both in one file makes '2025-01-15'.toDateTime() ambiguous. Resolve it file by file: each screen imports only what it needs, or uses explicit application when both are needed.
    Follow-ups

    From the lesson Extension methods in Dart

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  11. Mid to senior

    You are designing a utility library for an e-commerce team. Some helpers format prices, others validate product codes. Should these be extensions or static utility classes, when should an extension be named versus unnamed, and what type should each extension extend? Walk through the trade-offs and give your recommendation.

    What it tests
    Knowing that extensions read left-to-right while static calls read inside-out, that named extensions can be imported and applied explicitly, that unnamed extensions stay private, and that narrower types reduce conflict risk and improve discoverability.
    First step
    List the helpers and their natural receivers: a price formatter works on num or int, a product code validator works on String. Extensions let callers write price.toRupees() instead of PriceFormat.toRupees(price), which chains naturally and shows up in autocomplete.
    Follow-ups

    From the lesson Extension methods in Dart

    Model answer, Pro.

    In the answer:

    • Model answer
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  12. Mid to senior

    Your package shop_payments 2.3.0 exports a sealed class Payment with Upi and Card, and apps across the company switch on it with no wildcard. You must add NetBanking. Explain what breaks for those apps, which version you ship, and when you would have chosen a final class with a documented default instead.

    What it tests
    Knowing that a new subtype of a sealed class is a breaking change for exhaustive switches, how semantic versioning treats it, what happens to switches that end in a wildcard, and the sealed against final trade-off.
    First step
    List who is affected before choosing anything: a switch over Payment with no wildcard stops compiling after the upgrade, and a switch with a wildcard keeps compiling but gives NetBanking its default. Then read the version constraints your consumers use, because they decide how loud the release must be.
    Follow-ups

    From the lesson Sealed classes and exhaustive switches

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  13. Mid to senior

    A returns team tracks a return request through Requested, Accepted, PickedUp, Refunded and Declined, with events Accept, Decline, Pickup and Refund, and Refund carries an amount in paise. Design the types and the transition function, say what an illegal event returns, and decide where a wildcard is acceptable.

    What it tests
    Modelling states, events and refusals as sealed families, a transition that returns the next state or a typed error, testing every pair of state and event, and a deliberate choice about where wildcards are allowed.
    First step
    Write the legal moves as a table before any code: for each state, which events are allowed and what each one produces. Count the pairs and the legal ones, because the table becomes both the cases of the switch and the inputs of the test.
    Follow-ups

    From the lesson Sealed classes and exhaustive switches

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  14. Mid to staff

    A 200-file Dart app has about 60 switches over a sealed Payment, and 35 of them end in a wildcard. Last month a new subtype went live and one wildcard silently priced it wrong. Plan a sweep that finds the wildcards hiding behaviour, decide which to keep, and say how you stop new ones from arriving unnoticed.

    What it tests
    Knowing that a wildcard hides new subtypes, how to review many wildcards in bulk without changing behaviour, which ones are worth keeping, and what keeps new ones from arriving unnoticed.
    First step
    Count first: search for wildcard cases and group the hits by the type being switched. Then order the hits on sealed types by what a wrong default would cost, since that order is the order of the sweep.
    Follow-ups

    From the lesson Sealed classes and exhaustive switches

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes

All Dart (3.13) interview questions · The Dart (3.13) track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.