Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.

Learn more
Class modifiers

Dart 3.11 is live!Learn more

Class modifiers

Modifier keywords for class declarations to control external library access.

Version note

Class modifiers control how a class or mixin can be used, bothfrom within its own library, and from outside the library where it's defined.

Modifier keywords come before a class or mixin declaration. For example, writingabstract class defines an abstract class. The full set of modifiers that can appear before a class declaration include:

  • abstract
  • base
  • final
  • interface
  • sealed
  • mixin

Only thebase modifier can appear before a mixin declaration. The modifiers do not apply to other declarations likeenum,typedef,extension, orextension type.

When deciding whether to use class modifiers, consider the intended uses of the class and what behaviors the class needs to be able to rely on.

Tip

No modifier

#

To allow unrestricted permission to construct or subtype from any library, use aclass ormixin declaration without a modifier. By default, you can:

abstract

#

To define a class that doesn't require a full, concrete implementation of its entire interface, use theabstract modifier.

Abstract classes cannot be constructed from any library, whether its own or an outside library. Abstract classes often haveabstract methods.

a.dart
dart
abstractclassVehicle{voidmoveForward(intmeters);}
b.dart
dart
import'a.dart';// Error: `Vehicle` can't be instantiated because// it is marked as `abstract`.VehiclemyVehicle=Vehicle();// Can be extended.classCarextendsVehicle{intpassengers=4;@overridevoidmoveForward(intmeters){// ...}}// Can be implemented.classMockVehicleimplementsVehicle{@overridevoidmoveForward(intmeters){// ...}}

If you want your abstract class to appear to be instantiable, define afactory constructor.

base

#

To enforce inheritance of a class or mixin's implementation, use thebase modifier. A base class disallows implementation outside of its own library. This guarantees:

  • The base class constructor is called whenever an instance of a subtype of the class is created.
  • All implemented private members exist in subtypes.
  • A new implemented member in abase class does not break subtypes, since all subtypes inherit the new member.
    • This is true unless the subtype already declares a member with the same name and an incompatible signature.

You must mark any class that implements or extends a base class asbase,final, orsealed. This prevents outside libraries from breaking the base class guarantees.

a.dart
dart
baseclassVehicle{voidmoveForward(intmeters){// ...}}
b.dart
dart
import'a.dart';// Can be constructed.VehiclemyVehicle=Vehicle();// Can be extended.baseclassCarextendsVehicle{intpassengers=4;// ...}// ERROR: `Vehicle` can't be implemented in a different library because// it is marked with `base`.baseclassMockVehicleimplementsVehicle{@overridevoidmoveForward(){// ...}}

interface

#

To define an interface, use theinterface modifier. Libraries outside of the interface's own defining library can implement the interface, but not extend it. This guarantees:

  • When one of the class's instance methods calls another instance method onthis, it will always invoke a known implementation of the method from the same library.
  • Other libraries can't override methods that the interface class's own methods might later call in unexpected ways. This reduces thefragile base class problem.
a.dart
dart
interfaceclassVehicle{voidmoveForward(intmeters){// ...}}
b.dart
dart
import'a.dart';// Can be constructed.VehiclemyVehicle=Vehicle();// ERROR: `Vehicle` can't be extended in a different library because// it is marked with `interface`.classCarextendsVehicle{intpassengers=4;// ...}// Can be implemented.classMockVehicleimplementsVehicle{@overridevoidmoveForward(intmeters){// ...}}

abstract interface

#

The most common use for theinterface modifier is to define a pure interface.Combine theinterface andabstract modifiers for anabstract interface class.

Like aninterface class, other libraries can implement, but can't inherit, a pure interface. Like anabstract class, a pure interface can have abstract members.

final

#

To close the type hierarchy, use thefinal modifier. This prevents subtyping from a class outside of the current library. Disallowing both inheritance and implementation prevents subtyping entirely. This guarantees:

  • You can safely add incremental changes to the API.
  • You can call instance methods knowing that they haven't been overwritten in a third-party subclass.

Final classes can be extended or implemented within the same library. Thefinal modifier encompasses the effects ofbase, and therefore any subclasses must also be markedbase,final, orsealed.

a.dart
dart
finalclassVehicle{voidmoveForward(intmeters){// ...}}
b.dart
dart
import'a.dart';// Can be constructed.VehiclemyVehicle=Vehicle();// ERROR: `Vehicle` can't be extended in a different library// because it is marked `final`.classCarextendsVehicle{intpassengers=4;// ...}// ERROR: `Vehicle` can't be implemented in a different library because// it is marked `final`.classMockVehicleimplementsVehicle{@overridevoidmoveForward(intmeters){// ...}}

sealed

#

To create a known, enumerable set of subtypes, use thesealed modifier. This allows you to create a switch over those subtypes that is statically ensured to beexhaustive.

Thesealed modifier prevents a class from being extended or implemented outside its own library. Sealed classes are implicitlyabstract.

  • They cannot be constructed themselves.
  • They can havefactory constructors.
  • They can define constructors for their subclasses to use.

Subclasses of sealed classes are, however, not implicitly abstract.

The compiler is aware of any possible direct subtypes because they can only exist in the same library. This allows the compiler to alert you when a switch does not exhaustively handle all possible subtypes in its cases:

dart
sealedclassVehicle{}classCarextendsVehicle{}classTruckimplementsVehicle{}classBicycleextendsVehicle{}// ERROR: `Vehicle` can't be instantiated because// it is marked `sealed` and therefore, implicitly abstract.VehiclemyVehicle=Vehicle();// Subclasses of a sealed class can be instantiated unless also restricted.VehiclemyCar=Car();extensionVehicleSoundsonVehicle{Stringgetsound{// ERROR: The switch does not exhaustively account for// all possible objects of type `Vehicle`.// In this example, a `Vehicle` with a run-time type of `Bicycle`// would not match any of the cases.returnswitch(this){Car()=>'vroom',Truck()=>'VROOOOMM',};}}

If you don't wantexhaustive switching, or want to be able to add subtypes later without breaking the API, use thefinal modifier. For a more in depth comparison, readsealed versusfinal.

Combining modifiers

#

You can combine some modifiers for layered restrictions. A class declaration can be, in order:

  1. (Optional)abstract, describing whether the class can contain abstract members and prevents instantiation.
  2. (Optional) One ofbase,interface,final orsealed, describing restrictions on other libraries subtyping the class.
  3. (Optional)mixin, describing whether the declaration can be mixed in.
  4. Theclass keyword itself.

You can't combine some modifiers because they are contradictory, redundant, or otherwise mutually exclusive:

  • abstract withsealed. Asealed class is implicitlyabstract.
  • interface,final orsealed withmixin. These access modifiers preventmixing in.

For further guidance on how class modifiers can be combined, check out theClass modifiers reference.

Was this page's content helpful?

Unless stated otherwise, the documentation on this site reflects Dart 3.11.0. Page last updated on 2025-09-04.View source orreport an issue.


[8]ページ先頭

©2009-2026 Movatter.jp