Liegt das daran, dass sie je nach verwendetem Treiber unterschiedlich implementiert werden müssen?
Zum Beispiel. Es ist eine allgemeine Best Practice, auf eine Schnittstelle statt auf eine Implementierung (= Klasse, in diesem Zusammenhang) zu programmieren, und zwar aus mehreren Gründen. Einer davon wurde bereits von Ihnen erwähnt: verwandte, aber unterschiedliche Implementierungen können eine gemeinsame Schnittstelle nutzen. Ein weiterer Punkt ist, dass eine bestimmte Implementierung hinter den Kulissen geändert werden kann, ohne dass auch die Schnittstelle geändert werden muss: Nehmen wir an, die nächste Implementierung des Treibers muss eine andere Klasse verwenden. Es reicht aus, die bestehende Schnittstelle zu implementieren.
Stellen Sie sich nun vor, dass der Code anstelle von Schnittstellen mit Klassentypen arbeitet. Wenn sich nun die Implementierung ändert, müssten diese Schnittstellen ebenfalls geändert werden. Das würde bedeuten, dass jeder Nutzer (auch Sie) der API seinen Code ebenfalls ändern müsste!