Zie Scherp Scherper - Hoofdstuk 17
Na dit hoofdstuk kan je:
uitleggen wat een interface is en hoe ze verschilt van een klasse
een interface definiëren en in een klasse implementeren
kiezen tussen een interface en een abstracte klasse
meerdere interfaces combineren (waar overerving tekortschiet)
met is en as objecten op een interface bevragen
interfaces inzetten voor losser gekoppelde, SOLID-code
“Interface” = tussen vlakken: de afgesproken verbinding tussen twee systemen.
Een auto
stuur en pedalen, ongeacht benzine of elektrisch
Een pc
USB, HDMI, audio, … wereldwijd afgesproken aansluitingen
Ken je de interface, dan kan je ze gebruiken zonder de interne werking te kennen.
Belangrijk
Dit gaat niet over grafische User Interfaces. U weze gewaarschuwd.
Een interface is een belofte: een lijst van publieke methoden en properties die een klasse zegt te hebben, zonder de implementatie.
Het is als een sticker USB 3.0 compatibel:
je weet wat het apparaat kan
niet hoe het binnenin werkt
I interface in plaats van class, naam start met een I
public Geen public (alles is publiek)
; Geen code: elke signatuur eindigt op ;
Geen instantievariabelen en geen constructors
Geen access modifiers: alles is public
Een interface erft niet van een klasse, wel van andere interfaces
In de regel geen code, enkel signaturen
Tip
Sinds C# 8 bestaan default interface methods (met code), maar we houden het bewust bij zuivere signaturen.
Een interface is als een blad met gaten: leg je het op een klasse die de belofte nakomt, dan vallen de gaten precies over de juiste methoden en properties.
Zolang Zorro niet alles uit ISuperHeld implementeert, compileert de klasse niet.
Tip
In VS: klik op het lampje bij de klasse-signatuur en kies “Implement interface”.
| Abstracte klasse | Interface | |
|---|---|---|
| Gedeelde code | ja | nee |
| Instantievariabelen | ja | nee |
| Constructors | ja | nee |
| Hoeveel combineren? | 1 | meerdere |
| Relatie | “is een” | “kan iets” |
Tip
Gedeelde code en een echte is-een-relatie? Abstracte klasse. Enkel afdwingen dat ongerelateerde klassen “iets kunnen” (IVliegt voor Vogel én Vliegtuig)? Interface.
Een klasse erft van maar één parent, maar mag meerdere interfaces dragen:
Eerst de parent-klasse, dan de interface(s).
Man
parent-klasse
ISuperHeld
interface
ICoureur
interface
Opmerking
Interfaces mogen ook van elkaar erven: interface IGod : ISuperHeld.
gameOfThrones is een Boek, en Boek implementeert IVerwijderbaar
Net als bij polymorfisme schitteren interfaces in een lijst vol verschillende objecten:
Een Minister zijn als “bij-job”, niet als hoofd-klasse. Definieer een interface:
Nu kan eender wie minister worden zonder z’n bestaande klasse op te geven:
Een CEO én een echte minister staan samen in één lijst.
OOP benadert de realiteit.
Wil je Array.Sort of List.Sort op je eigen objecten? Dan moet je IComparable implementeren, anders krijg je:
Tip
Het framework roept jouw CompareTo aan. Zo zie je waarvoor interfaces echt dienen: een belofte die anderen (zelfs .NET zelf) kunnen gebruiken.
Mensen spreken; enkel vloekers vloeken:
Hoe laat je in een Mens[] enkel de vloekers vloeken?
Werk tegen de interface, niet tegen de implementatie.
Het boeit je niet meer wat er in een klasse zit; aan haar interfaces zie je wat ze kan.
Dat is de kern van de SOLID-principes: abstractie en separation of concerns. De ultieme black-box-revelatie. See what I did there?
Het .NET-framework zit er vol mee. Een paar die je nog vaak zal tegenkomen:
IEnumerable
laat foreach en LINQ over je collectie lopen
IDisposable
netjes opruimen, samen met using
IComparable
maakt je objecten sorteerbaar
ICloneable
laat een object zichzelf klonen
Tip
Implementeer je zo’n interface, dan werkt je eigen klasse meteen samen met bestaande .NET-functionaliteit.
Een interface is een belofte van publieke methoden en properties, zonder code
Een klasse die een interface draagt, moet alles ervan implementeren
Kies een interface voor “kan iets” en om er meerdere te combineren; een abstracte klasse voor gedeelde code en “is een”
Met is en as (en pattern matching) bevraag je objecten op een interface
Interfaces zorgen voor losser gekoppelde, SOLID-code
Tip
Volgende halte: bestandsverwerking: lezen van en schrijven naar bestanden.
Kennisclips
Hoe doen andere programmeertalen hetzelfde? En een korte zoek-de-fout, om zo kritisch mogelijk naar code te leren kijken.
Onderstaande C#-klasse zou IComparable moeten implementeren zodat Array.Sort werkt, maar de compiler klaagt dat Land de interface niet volledig implementeert. Wat ontbreekt?
Opmerking
De methode heet Vergelijk, maar IComparable vereist exact de methode CompareTo(object obj). Een interface is een belofte op de letter: de naam (en signatuur) moet precies kloppen. Hernoem Vergelijk naar CompareTo en de klasse compileert weer.
hebben net als C# een echt interface-keyword:
doet aan duck typing: geen verplichte interface, zolang een object toevallig de juiste methoden heeft, mag je het gebruiken.
C# laat de compiler je belofte hard controleren.
Dat je meerdere interfaces maar één klasse mag erven, koos Java ook bewust. C++ laat wél meervoudige overerving van klassen toe:
Krachtig, maar het leidt tot het diamond problem: erven twee parents dezelfde methode, dan weet de compiler niet meer welke. Door enkel meervoudige interfaces (zonder eigen code) toe te laten, ontwijken C# en Java dat volledig.
Een handige samenvattende poster (Opgelet: gemaakt m.b.v. ChatGPT Image Gen 2).