-
Notifications
You must be signed in to change notification settings - Fork 219
Description
We chose in the design of class modifiers to enforce that base
transitivity applies even within the same library. This isn't necessary - we could allow you to re-open classes to implementation within the same library, while still allowing enforcement of the same invariants. The argument against that was that it might be too easy to accidentally expose an interface that you didn't intend to.
Subsequently, we've had several use cases show up where there is some desire to not have base transitivity within the same library.
This issue describes one possible use case for a non-transitive base within the same library.
@jakemac53 ran into this again today when trying to design an approach to writing a final
class while providing a mockable interface for testing. He found one clever but convoluted pattern using a sealed
class with a factory constructor, implemented by a private implementation class and visible for testing public interface.
A simpler and more intuitive pattern would be something like the following:
base class FooService {}
@visibleForTesting
abstract interface class FooServiceForTesting implements FooService {}
This is forbidden by the current transitivity rules.
While this one use case is not definitive, it is interesting that we seem to be encountering uses for this. We could choose to change this - it would be non-breaking to do so. Should we consider dropping the requirement to make base
transitive within the same library?
cc @dart-lang/language-team