OLD [G_PRO] Programmeren en OO programmeren
1.0.0
1.0.0
  • Welkom
  • Inleiding
    • Benodigdheden
    • Afspraken code
    • Afspraken oefeningen
    • Nuttige extras
    • Dankwoord
    • Mee helpen?
  • Semester 1: Programming Principles
    • H1: Werken met Visual Studio
      • Introductie tot C#
      • Visual Studio en .NET Core installeren
      • Een C# project maken in Visual Studio
      • Fouten in je code
      • Je eerste stappen in C#
      • Input/Output: ReadLine/WriteLine
      • Kleuren in Console
      • Oefeningen
    • H2: Variabelen en datatypes
      • De syntaxis van C#
      • Datatypes
      • Variabelen
      • Expressies en operators
      • Oefeningen
    • H3: Strings en hun methoden
      • Strings
      • Strings samenvoegen
      • Omzetten van en naar strings
      • Functionaliteit van strings
      • Oefeningen
    • H4: Beslissingen
      • Beslissingen intro
      • Enkelvoudige booleaanse expressies
      • If, else, else if
      • Samengestelde booleaanse expressies
      • Scope van variabelen
      • Oefeningen
    • H5: Loops
      • Loops intro
      • While en Do While
      • For
      • Debuggen
      • Oefeningen
    • H6: Arrays
      • Array principes
      • Alternatieve syntax
      • Werken met arrays
      • Defaultwaarden
      • List<T>
      • Oefeningen
    • H7: Methoden
      • Methoden intro
      • Parameters
      • Return waarden
      • Geavanceerde methoden
      • Oefeningen
    • Intermezzo: TextCell
    • H8: Numerieke data
      • De Math klasse
      • Random
      • Casting en conversie
      • Oefeningen
    • H9: Meerdimensionaal werken
      • N-dimensionale arrays
      • Geneste iteratie
      • Oefeningen
    • H10: Gevorderde tekstverwerking
      • Voorstelling van tekst
      • Interpolatie met formattering
      • Werken met arrays van strings
      • Input en output van tekstbestanden
      • Oefeningen
    • Afsluiter: TextCell2D
  • Semester 2 : OOP
    • H10: Klassen en objecten
      • OOP Intro
      • Klassen en objecten aanmaken
      • DateTime: leren werken met objecten
      • Enumeraties: nog een eigen datatype
      • Klassen en objecten weergeven deel 1
      • Attributen
      • Methoden
      • Access modifiers
      • Properties
      • Oefeningen
    • H11: Objecten (al dan niet) aanmaken
      • Constructors
      • Spelen met strings
      • Oefeningen
    • H12: Geheugenmanagement bij klassen
      • value en reference met eigen objecten
      • nullable value types
      • NullReference exception
      • Labo
    • H13: Datastructuren
      • Foreach en var
      • List
      • Dictionary
      • Immutable datastructuren
      • Verdere datastructuren
      • Labo
    • H14: Overerving
      • Overerving intro
      • Virtual en override
      • Abstract
      • Constructors bij overerving
      • Oefeningen
    • H15: Geavanceerde overerving
      • protected access modifier
      • Base keyword
      • System.Object
      • Labo
    • H16: Exception handling
      • Werken met exceptions
      • Zelf uitzonderingen maken
      • Wanneer exceptions en handling gebruiken
      • Labo
    • H17: polymorfisme en interfaces
      • Polymorfisme
      • Polymorfisme in de praktijk
      • Interfaces
      • Losse koppeling
      • Labo
  • Appendix
    • Visual Studio Tips & Tricks
    • Ea-ict coding guidelines
    • Oefeningen kerkhof
  • Semester 1 appendix
    • Nice to know stuff
      • Out en Ref parameters
      • Jagged arrays
    • All-In-Projecten
      • Overzicht
      • Console Matrix
      • Ascii filmpjes maken met loops
      • Ascii filmpjes maken met methoden
      • Fun with methods: een verhaalgenerator
      • Tekst-gebaseerd Maze game
      • Conway game of life
  • Semester 2 appendix
    • Operator overloading
    • Object Initializer Syntax
    • Compositie en aggregatie
    • Nice to know stuff
      • Klassen herbruiken
      • Expression bodied members
    • All-In-Projecten
      • Overzicht
      • OO Textbased Game
      • War Simulator
      • Map Maker
      • Magic The Gathering API
      • SchoolAdmin
  • Pro (geen leerstof en/of in opbouw)
    • Bitwise operators
    • Generics en collections
      • Generics methoden en types
      • Generic classes en constraints
      • Collections
      • Labo-oefeningen
    • Events
      • Events
      • Chat server
    • Software engineering
      • SOLID
Powered by GitBook
On this page
  • Betekenissen
  • Interfaces in C#
  • Regels voor interfaces
  • Toepassing interfaces
  • Meerdere interfaces
  • Interfaces vs. overerving

Was this helpful?

Export as PDF
  1. Semester 2 : OOP
  2. H17: polymorfisme en interfaces

Interfaces

PreviousPolymorfisme in de praktijkNextLosse koppeling

Last updated 3 years ago

Was this helpful?

Betekenissen

Het woord "interface" heeft meerdere betekenissen:

  • de totale verzameling methodes en properties van een bepaalde klasse

    • hierin wordt soms onderscheid gemaakt tussen de publieke interface en de totale interface

  • een language construct dat toestaat vast te leggen dat bepaalde methodes of properties deel uitmaken van de publieke interface in de eerste zin van het woord

Je moet beide betekenissen begrijpen. De eerste is meer een abstract concept, de tweede kan je programmeren in C# en staat toe nog meer polymorfisme toe te passen.

Deze pagina heeft niet echt iets te maken met "grafische user interface". Ook daar wil "interface" zeggen "wat je kan gebruiken", maar verder is er geen verband.

Een interface als language construct is een garantie dat bepaalde methodes en properties geïmplementeerd zijn door een bepaalde klasse. Dit vertelt ons niets over hoe deze methodes en properties geïmplementeerd zijn.

Interfaces in C#

Volgende code toont hoe we een interface implementeren voor data die we naar een CSV-file willen kunnen wegschrijven en die we terug willen kunnen uitlezen.

interface ICSVSerializable
{
    string ToCsv();
    
    string Separator
    {
        get;
        set;
    }
}

Enkele opmerkingen:

  • Het woord class wordt niet gebruikt, in de plaats daarvan gebruiken we interface.

  • Het is een vrij algemene afspraak om interfaces met een I te laten starten in hun naamgeving

  • Methoden en properties gaan niet vooraf van public: interfaces zijn van nature net publiek, dus alle methoden en properties van de interface zijn dat bijgevolg ook.

  • Er wordt geen code/implementatie gegeven: iedere methode eindigt ogenblikkelijk met een puntkomma.

Als we deze interface nu koppelen aan een klasse, moeten we deze methodes implementeren.

Een interface is een beschrijving hoe een component een andere component kan gebruiken, zonder te zeggen hoe dit moet gebeuren. De interface is met andere woorden 100% scheiding tussen de methode/Property-signatuur en de eigenlijke implementatie ervan.

Regels voor interfaces

  • Je kan geen constructor declareren

  • Je kan geen access specificeren (public, protected, etc): alles is public

  • Een interface kan niet overerven van een klasse, wel van een andere interface. In dat geval moet een implementatie de velden en properties van de ouderinterface en de kindinterface voorzien.

  • Je hoeft geen override te schrijven wanneer je een methode of property implementeert.

Toepassing interfaces

Volgende code toont hoe we kunnen aangeven dat een klasse Student serialisatie van en naar CSV voorziet:

class Student : ICSVSerializable
{
    private string naam;
    private byte leeftijd;
    private string separator;
    
    public string Separator {
        get {
            return this.separator;
        }
        set {
            this.separator = value;
        }
    }
    
    public Student(string naam, byte leeftijd) {
        this.naam = naam;
        this.leeftijd = leeftijd;
        this.Separator = ";";
    }
    
    public string ToCsv() {
        return $"Student{Separator}{this.naam}{Separator}{this.leeftijd}";
    }
}

Een nuttige toepassing van deze interface zou een data dump kunnen zijn. Als we een lijst bijhouden van alle ICSVSerializable objecten, kunnen we deze in één beweging exporteren. De code die deze export uitvoert mag dezelfde zijn voor allerlei verschillende soorten data: studenten, huisdieren, voedingsproducten,... Maakt niet uit!

Meerdere interfaces

Het is toegelaten meerdere interfaces te implementeren. Volgende code staat toe een Student op te slaan op schijf door hem te serialiseren als CSV of XML, naargelang je voorkeur.

interface IXMLSerializable
{
    string ToXml();
}

class Student : ICSVSerializable, IXMLSerializable
{
    private string naam;
    private byte leeftijd;
    private string separator;
    public string Separator {
        get {
            return this.separator;
        }
        set {
            this.separator = value;
        }
    }
    
    public Student(string naam, byte leeftijd) {
        this.naam = naam;
        this.leeftijd = leeftijd;
    }
    
    public string ToCsv() {
        return $"Student{this.Separator}{this.naam}{this.Separator}{this.leeftijd}";
    }
    
    public string ToXml() {
        return $@"<Student>
                    <naam>{this.naam}</naam>
                    <leeftijd>{this.leeftijd}</leeftijd>
                  </Student>";
    }
}

Interfaces vs. overerving

Je kan je hier terecht afvragen of we interfaces wel nodig hebben, aangezien we abstractie en polymorfisme ook kunnen bereiken met behulp van (al dan niet abstracte) klassen. Maar er zijn goede redenen voor het bestaan van interfaces:

  • Om technische redenen kan een klasse maar één ouderklasse hebben. Een klasse kan wel om het even welk aantal interfaces implementeren. Er zijn weliswaar talen waarin je meerdere ouderklassen kan hebben, maar daarin is een object altijd "iets meer" ouderklasse 1 dan ouderklasse 2 en dat kan heel onoverzichtelijk worden.

  • Er is een betekenisverschil: een kindklasse is een specifieker type van de ouderklasse. Een klasse die een interface implementeert kan gewoon bepaalde zaken. Dit is een beetje een kwestie van interpretatie, maar als vuistregel leidt dit tot betere ontwerpen dan lukraak gebruik van overerving.

  • Er is een praktisch verschil: bij overerving wil je veel overnemen van de ouderklasse, want zo bespaar je code. Interfaces wil je juist beperkt houden: je moet elk van je interfaces volledig implementeren.

Deze puntjes samen leiden ook tot een tweede vuistregel voor het gebruik van interfaces: kan je wel (veel) code besparen met overerving? Bijvoorbeeld bij ToCsv zal de methode voor elk object verschillen en win je dus niets met een ouderklasse tegenover een interface, terwijl je wel zorgt dat je geen andere ouderklasse meer kan hebben.

Dit lijkt wel heel erg op een afgewaterde abstracte klasse? Ja, maar er zijn goede redenen om interfaces te gebruiken. De simpelste: je mag maar van één klasse erven, maar je mag zo veel interfaces implementeren als je wil. Als je wil weten waarom, zie . De uitleg gaat over Java maar kan rechtstreeks toegepast worden op C#.

Kennisclip
hier