In Dart, what makes a class abstract, how do you declare an abstract member, and what must a concrete subclass do with it?
answer
- the abstract modifier on the class
- a signature ending in a semicolon
- cannot be constructed anywhere
- concrete subclass implements every one
- abstract fields exist too
basics
~20 sA class marked abstract cannot be instantiated and may declare members with no body, written as a signature ending in a semicolon. A concrete subclass must implement every inherited abstract member, or be declared abstract itself.
solid answer
~40 sAn `abstract class` is a partial implementation: it can mix concrete members with **abstract** ones, and it can never be constructed, from any library. An abstract method, getter or setter is written as a signature ending in `;`, like `double get area;` — there is no `abstract` keyword on methods. Abstract members may only appear in abstract classes and mixins. A concrete class that extends it must supply every abstract member it inherits, otherwise the analyzer reports missing concrete implementations; declaring the subclass abstract postpones the obligation. Abstract classes can still have constructors for subclasses to call, and a factory constructor can make the type *look* instantiable by returning a concrete subtype. `super.area` on a member that is abstract in the superclass is an error.
go deeper
Recall that abstract classes cannot be constructed and that abstract members are signatures ending in a semicolon.
Explain the subclass obligation, abstract fields, why super calls to abstract members fail, and how a factory can return a concrete subtype.
Use abstract members to turn missing behaviour into compile errors instead of runtime UnimplementedError, and keep shared logic in the base.
Decide which abstractions carry shared implementation and which are pure contracts, since each commits future maintainers differently.
## Abstract classes An **abstract class** is declared with the `abstract` modifier. It describes a family of types and may provide part of their behaviour, but it is **never instantiated directly** — not from another library, and not from its own library either (`instantiate_abstract_class`). ```dart abstract class Shape { Shape(this.label); final String label; double get area; // abstract getter double get perimeter; // abstract getter Shape scaled(double k); // abstract method String describe() => // concrete method '$label: ${area.toStringAsFixed(2)} m2, perimeter ${perimeter.toStringAsFixed(2)} m'; } ``` An abstract class still has constructors. They cannot be called with `Shape(...)`, but a subclass calls them through `super(...)` to initialise the fields the abstract class owns, such as `label`. ## Declaring abstract members - **Methods, getters and setters** become abstract by ending the declaration with `;` instead of a body: `void recalc();`, `double get area;`, `set area(double v);`. - There is **no `abstract` keyword on methods**; `abstract void recalc();` is an error (`abstract_class_member`). - **Fields** are the exception: `abstract double width;` declares an abstract getter and setter pair. Abstract fields cannot have initializers or be `late`. - Abstract members can only exist in **abstract classes** (or mixins). A concrete class with a body-less method is `concrete_class_with_abstract_member`. ## Obligations of a concrete subclass ```dart class Rect extends Shape { Rect(this.width, this.height) : super('rect'); final double width, height; @override double get area => width * height; @override double get perimeter => 2 * (width + height); @override Rect scaled(double k) => Rect(width * k, height * k); } ``` 1. A **concrete** class must have an implementation for every abstract member it inherits — declared itself or inherited from further up (or supplied by a mixin). Otherwise: `non_abstract_class_inherits_abstract_member`. 2. A subclass that cannot supply them all can be declared **`abstract`** itself. 3. Inside an override, `super.area` is only valid if some superclass provides a **concrete** `area`; calling an always-abstract member via `super` is `abstract_super_member_reference`. 4. The override may **narrow the return type**: `Rect scaled(...)` legally overrides `Shape scaled(...)`. ## Looking instantiable: factory constructors An abstract class may declare a **factory constructor** that returns a concrete subtype, so callers write `Shape.square(3)` and never see the implementation class: ```dart abstract class Shape { // ... factory Shape.square(double side) = Square; } ``` ## Abstract class or plain class as interface? | Need | Choose | |---|---| | Shared code plus required hooks | abstract class, subclasses `extend` it | | Only a contract, no shared code | abstract class with only abstract members, implementers `implement` it | | Prevent direct construction | abstract class | | A usable default implementation | a concrete class | In the floor-plan calculator, `Shape` owns the reusable `describe()` and forces each concrete shape to answer `area` and `perimeter`. Code that sums a floor plan depends only on `Shape`. ## Common mistakes - Writing a method with an empty body `{}` and calling it abstract: it is concrete, and subclasses are no longer forced to override it. - Using `throw UnimplementedError()` as a body to fake abstraction: the error moves from compile time to runtime. - Expecting `Shape()` to work inside the declaring library.
- In Dart, why write `double get area;` rather than `double get area => throw UnimplementedError();` in a base class?The abstract form makes the analyzer require every concrete subclass to implement `area`, so a forgotten override is a compile error. The throwing body is a concrete implementation: subclasses compile without overriding it, and the mistake only appears when `area` is read at runtime.
- In Dart, what does `abstract double width;` declare in an abstract class?An abstract getter and setter pair named `width`, with no storage. Concrete subclasses must provide both, typically with an ordinary non-final field, or with an explicit getter and setter. Abstract fields cannot have an initializer and cannot be `late`.
saying these in an interview costs you the question
- An abstract class can be instantiated from inside its own library
- Abstract methods are declared with the abstract keyword before the return type
- An empty method body {} makes a method abstract
- A concrete subclass may leave inherited abstract members unimplemented and fail at runtime
- Abstract classes cannot declare constructors