The Final Class Modifier

Elias Reis
2 min readMay 14, 2024

--

In an effort to meet all the expectations of modern programming languages, Dart, supported by Google, has been adding several features to the language. One of the latest additions to Dart is the introduction of the final class modifier, which brings a new level of control and safety to Dart programming. In this blog post, we’ll dive into what the final class modifier is, why it’s important, and how it can improve your Dart code.

What is the “final” class modifier?

You probably already know the final keyword; it’s been used to declare constants or values that cannot be changed after initialization. However, Dart 3 has extended this to classes as well. So when the final keyword is applied to a class, it ensures the class cannot be extended or subclassed by any other.

final class MyFinalClass {
// Class definition
}

What is important to know about this class modifier?

The final class modifier brings several benefits to Dart developers:

  1. Immutability: By marking a class as final, you’re essentially declaring it as immutable. This means that once the class is defined, its structure cannot be altered by extending it with additional properties or methods.
  2. Predictability: Final classes provide a clear signal to other developers that the class is not intended to be extended. This can help in understanding the design intent and prevent unintended subclassing, reducing potential bugs and maintenance headaches.
  3. Performance: Since final classes cannot be subclassed, the Dart runtime can optimize the code more aggressively, potentially leading to better performance.
  4. Security: Final classes help in enforcing encapsulation and preventing unintended changes to the class hierarchy, thus enhancing the security of your codebase.

Let's take a look at the code:

final class Shape {
final double area;

Shape(this.area);
}

class Circle extends Shape {
final double radius;

Circle(this.radius) : super(pi * radius * radius);
}

class Square extends Shape {
final double side;

Square(this.side) : super(side * side);
}

In this example, we have the Shapeas a final class, ensuring that it cannot be subclassed, effectively closing the type hierarchy. Then, we have Circle and Squareclasses that extend Shape. However, if we try to extend Shape directly, Dart will throw a compile-time error, ensuring the immutability of the Shape class.

The type 'Circle' must be 'base', 'final' or 'sealed' 
because the supertype 'Shape' is 'final'.

In conclusion…

The introduction of the final class modifier in Dart 3 means that Google is committed to making Dart a modern, efficient, and developer-centric language. With this class modifier, you can enforce immutability, foster code predictability, optimize performance, and bolster security.

As you go deeper into your Dart journey, consider the final class modifier a tool to fortify your codebase and streamline your development process.

--

--