Menu
Coddy logo textTech

The final Class Keyword

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 40 of 110.

Sometimes you want to prevent a class from being extended. The final keyword, when applied to a class, stops any other class from inheriting from it.

final class DatabaseConnection {
  String connectionString;
  
  DatabaseConnection(this.connectionString);
  
  void connect() {
    print('Connected to $connectionString');
  }
}

// This would cause a compile-time error:
// class CustomConnection extends DatabaseConnection { }

Marking a class as final is useful when extending it could break its intended behavior or security guarantees. For example, a class that manages sensitive resources might need to ensure its methods aren't overridden in unexpected ways.

Dart 3 also introduced related modifiers: base forces subclasses to use extends (not implements), and sealed restricts inheritance to the same library. For now, focus on final as the simplest way to lock down a class completely.

Use final classes when you're certain the class design is complete and inheritance would only cause problems. However, don't overuse it - most classes benefit from remaining open for extension.

challenge icon

Challenge

Easy

Let's build a secure configuration system that demonstrates when and why you'd want to prevent a class from being extended. You'll create a final class that manages application settings, ensuring its behavior can't be altered through inheritance.

You'll organize your code into two files:

  • config.dart: Define your configuration classes here:
    • A final class AppConfig that cannot be extended. It should have a String appName and String version property, a constructor that takes both values, and a method display() that prints [appName] v[version]
    • A regular (non-final) Feature class with a String name and bool enabled property, a constructor for both, and a method status() that prints [name]: [enabled ? 'ON' : 'OFF']
    • An ExperimentalFeature class that extends Feature and adds a String warning property. Override status() using @override to first call the parent's version with super.status(), then print Warning: [warning]
  • main.dart: Import your config file and demonstrate the difference between final and regular classes:
    • Create an AppConfig with appName 'MyApp' and version '2.0.1', then call display()
    • Print an empty line
    • Create a Feature with name 'Dark Mode' and enabled true, then call status()
    • Print an empty line
    • Create an ExperimentalFeature with name 'AI Assistant', enabled false, and warning 'May be unstable', then call status()

Notice how AppConfig is marked as final because its configuration behavior should remain consistent and secure - no subclass should be able to alter how settings are managed. Meanwhile, Feature remains open for extension, allowing ExperimentalFeature to add specialized behavior.

Expected output:

MyApp v2.0.1

Dark Mode: ON

AI Assistant: OFF
Warning: May be unstable

Cheat sheet

The final keyword prevents a class from being extended:

final class DatabaseConnection {
  String connectionString;
  
  DatabaseConnection(this.connectionString);
  
  void connect() {
    print('Connected to $connectionString');
  }
}

// This would cause a compile-time error:
// class CustomConnection extends DatabaseConnection { }

Use final classes when extending them could break intended behavior or security guarantees. Most classes should remain open for extension unless there's a specific reason to lock them down.

Dart 3 also provides base (forces subclasses to use extends) and sealed (restricts inheritance to the same library) modifiers.

Try it yourself

import 'config.dart';

void main() {
  // TODO: Create an AppConfig with appName 'MyApp' and version '2.0.1'
  // Then call display()
  
  // TODO: Print an empty line
  
  // TODO: Create a Feature with name 'Dark Mode' and enabled true
  // Then call status()
  
  // TODO: Print an empty line
  
  // TODO: Create an ExperimentalFeature with name 'AI Assistant',
  // enabled false, and warning 'May be unstable'
  // Then call status()
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming