arrow-left

All pages
gitbookPowered by GitBook
1 of 8

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

OOP Intro

hashtag
OOP

Object Oriented Programming of korter OOP is een techniek afkomstig van higher level programmeertalen zoals Java, C#, VB.NET, ... en vindt zijn oorsprong bij Smalltalk die het eerst de term Object Oriented Programming introduceerde.

In recentere jaren heeft deze techniek echter ook zijn weg gevonden naar webscripting talen zoals Python, Ruby, Perl en zelfs PHP.

OOP streeft ernaar om een project zo structureel mogelijk op te bouwen in objecten. Dit heeft voor de programmeur het grote voordeel dat code vanaf nu in logische componenten wordt opgedeeld en veel makkelijker te hergebruiken is.

Om het concept van objecten te illustreren wordt meestal een voorwerp uit het dagelijks leven als voorbeeld gebruikt. Neem bijvoorbeeld een auto. De auto is het object en dit object heeft bepaalde properties of eigenschappen. Een eigenschap van de auto kan een band, een deur, een spiegel, de uitlaat of eender welk ander onderdeel van de auto zijn. Maar een auto heeft ook methoden. Een methode kan starten of remmen zijn.

Dus hebben we nu eigenlijk een object met properties en methoden. Zo zit een object in programmeertalen er ook uit. Een mail object heeft bijvoorbeeld als property de ontvanger, de verzender en het bericht en als methode versturen. Dit zijn natuurlijk erg vereenvoudigde voorbeelden en in de praktijk zal het er een stuk ingewikkelder aan toe gaan maar de basisprincipes zijn steeds hetzelfde. .

hashtag
Black-box principe

Een belangrijk concept bij OOP is het Black-box principe waarbij we de afzonderlijke objecten en hun werking als kleine zwarte dozen gaan beschouwen. Neem het voorbeeld van de auto: deze is in de echte wereld ontwikkeld volgens het blackbox-principe. De werking van de auto kennen tot in het kleinste detail is niet nodig om met een auto te kunnen rijden. De auto biedt een aantal zaken aan de buitenwereld aan (het stuur, pedalen, het dashboard), wat we de interface noemen, die je kan gebruiken om de interne staat van de auto uit te lezen of te manipuleren. Stel je voor dat je moest weten hoe een auto volledig werkte voor je ermee op de baan kon.

Binnen OOP wordt dit blackbox-concept encapsulatie genoemd. Het doel van OOP is andere programmeurs (en jezelf) zoveel mogelijk af te schermen van de interne werking van je code. Vergelijk het met de methoden uit vorig semester: "if it works, it works" en dan hoef je niet in de code van de methode te gaan zien wat er juist gebeurt.

hashtag
Klassen en objecten

Een elementair aspect binnen OOP is het verschil beheersen tussen een klasse en een object.

Wanneer we meerdere objecten gebruiken van dezelfde soort dan kunnen we zeggen dat deze objecten allemaal deel uitmaken van een zelfde klasse.

Zo hebben we bijvoorbeeld de klasse van de auto's. De verschillende auto's die je op de straat ziet rijden zijn allemaal objecten van die klasse. De klasse zelf is een soort algemene beschrijving waaraan alle objecten van dat type moeten voldoen (bv: alle auto's hebben 4 banden, 1 motor en kunnen sneller en trager rijden).

hashtag
Definitie klasse en object

  • Een klasse is een beschrijving en verzameling van dingen (objecten) met soortgelijke eigenschappen

  • Een individueel object is een instantie van een klasse

Je zou dit kunnen vergelijken met het grondplan voor een huis dat tien keer in een straat zal gebouwd worden. Het plan met alle soortgelijke eigenschappen van ieder huis is de klasse. De effectieve huizen die we, gebaseerd op dat grondplan, bouwen zijn de instanties of objecten van deze klasse.

Nog een andere invalshoek:

Een andere invalshoek is de zogenaamde "dungeons" in veel online games. De makers van het spel hebben iedere dungeon in een klasse beschreven. Wanneer een groep avonturiers nu in zo'n grot gaat dan wordt voor die groep een aparte instantie (instance) van die grot gemaakt, gebasseerd op de klasse. Ze doen dit zodat iedere groep spelers mekaar niet voor de voeten loopt in 1 grot.

Bron van deze introductiearrow-up-right

Properties

hashtag
Properties

In dit hoofdstuk bespreken we eerst waarom properties nodig zijn. Vervolgens bespreken we de 2 soorten properties die er bestaan:

  1. Full properties

  2. Auto properties

hashtag
In een wereld zonder properties

Properties (eigenschappen) zijn de C# manier om objecten hun interne staat in en uit te lezen. Ze zorgen voor een gecontroleerde toegang tot de interne structuur van je objecten.

Stel dat we volgende klasse hebben:

Een SithLord heeft steeds een verborgen Sith Name en ook een hoeveelheid energie die hij nodig heeft om te strijden. Het is uit den boze dat we eenvoudige data fields (energy en name) public maken. Zouden we dat wel doen dan kunnen externe objecten deze geheime informatie uitlezen!

We willen echter wel van buiten uit het energy-level van een SithLord kunnen instellen. Maar ook hier hetzelfde probleem: wat als we de energy-level op -1000 instellen? Terwijl energy nooit onder 0 mag gaan.

Properties lossen dit probleem op

hashtag
Oldschool oplossing

Vroeger loste men voorgaande probleem op door Get-methoden te schrijven:

Je zal deze manier nog in veel andere talen tegenkomen. Wij prefereren properties zoals we nu zullen uitleggen.

Je zou dan kunnen doen:

hashtag
Full properties

Een full property ziet er als volgt uit:

Dankzij deze code kunnen we nu elders dit doen:

Vergelijk dit met de vorige alinea waar we dit met Get en Set methoden moesten doen. Deze property syntax is veel eenvoudiger in het gebruik.

We zullen de property nu stuk per stuk analyseren:

  • public int Energy: een property is normaal public. Vervolgens zeggen we wat voor type de property moet zijn en geven we het een naam. Indien je de property gaat gebruiken om een intern dataveld naar buiten beschikbaar te stellen, dan is het een goede gewoonte om dezelfde naam als dat veld te nemen maar nu met een hoofdletter. (dus Energy i.p.v. energy).

  • { }: Vervolgens volgen 2 accolades waarbinnen we de werking van de property beschrijven.

hashtag
Snel property schrijven

Visual Studio heeft een ingebouwde shortcut om snel een full property, inclusief een bijhorende private dataveld, te schrijven. Typ propfull gevolgd door twee tabs!

hashtag
Full property met toegangscontrole

De full property Energy heeft nog steeds het probleem dat we negatieve waarden kunnen toewijzen (via de set) die dan vervolgens zal toegewezen worden aan energy.

Properties hebben echter de mogelijkheid om op te treden als wachters van en naar de interne staat van objecten.

We kunnen in de setcode extra controles inbouwen. Asl volgt:

Enkel indien de toegewezen waarde groter of gelijk is aan 0 zal deze ook effectief aan energy toegewezen worden. Volgende lijn zal dus geen effect hebben: palpatine.Energy=-1;

We kunnen de code binnen set (en get) zo complex als we willen maken.

hashtag
Property variaties

We zijn niet verplicht om zowel de get en de set code van een property te schrijven.

hashtag
Write-only property

We kunnen dus enkel energy een waarde geven, maar niet van buitenuit uitlezen.

hashtag
Read-only property

We kunnen dus enkel energy van buitenuit uitlezen, maar niet aanpassen.

hashtag
Read-only property met private set

Soms gebeurt het dat we van buitenuit enkel de gebruiker de property read-only willen maken. We willen echter intern (in de klasse zelf) nog steeds controleren dat er geen illegale waarden aan private datafields worden gegeven. Op dat moment definieren we een read-only property met een private setter:

Van buitenuit zal enkel code werken die deget-van deze property aanroept: Console.WriteLine(palpatine.Energy);. Code die de set van buitenuit nodig heeft zal een fout geven zoals: palpatine.Energy=65; ongeacht of deze geldig is of niet.

Nu goed opletten: indien we in het object de property willen gebruiken dan moeten we deze dus ook effectief aanroepen, anders omzeilen we hem als we rechtstreeks energy instellen.

Kijk zelf naar volgende slechte code:

De nieuw toegevoegde methode ResetLord willen we gebruiken om de lord z'n energy terug te verlagen. Door echter energy=-1 te schrijven geven we dus -1 rechtstreeks aan energy. Nochtans is dit een illegale waarde. We moeten dus in de methode ook expliciet via de property gaan en dus schrijven:

Het is een goede gewoonte om zo vaak mogelijk via de properties je interne variabele aan te passen en niet rechtstreeks het dataveld zelf.

hashtag
Read-only Get-omvormers

Je bent uiteraard niet verplicht om voor iedere interne variabele een bijhorende property te schrijven. Omgekeerd ook: mogelijk wil je extra properties hebben voor data die je 'on-the-fly' kan genereren.

Stel dat we volgende klasse hebben

We willen echter ook soms de volledige naam op het scherm tonen ("Voornaam + Achternaam"). Via een read-only property kan dit supereenvoudig:

Of nog eentje:

Nog een voorbeeldje:

Vaak gebruiken we dit soort read-only properties om data te transformeren. Stel bijvoorbeeld dat we volgende klasse hebben:

hashtag
Auto properties

Automatische eigenschappen (autoproperties) in C# staan toe om eigenschappen (properties) die enkel een waarde uit een private variabele lezen en schrijven verkort voor te stellen.

Zo kan je eenvoudige de klasse Person herschrijven met behulp van autoproperties. De originele klasse:

De herschreven klasse met autoproperties (autoprops):

Beide klassen hebben exact dezelfde functionaliteit, echter de klasse aan de rechterzijde is aanzienlijk eenvoudig om te lezen en te typen.

hashtag
Beginwaarde van autoprops

Je mag autoproperties beginwaarden geven door de waarde achter de property te geven, als volgt:

hashtag
Altijd auto-properties?

Merk op dat je dit enkel kan doen indien er geen extra logica in de property aanwezig is. Stel dat je bij de setter van age wil controleren op een negatieve waarde, dan zal je dit zoals voorheen moeten schrijven en kan dit niet met een automatic property:

Voorgaande property kan dus NIET herschreven worden met een automatic property.

hashtag
Alleen-lezen eigenschap

Je kan automatic properties ook gebruiken om bijvoorbeeld een read-only property te definiëren . Als volgt:

Originele klasse:

Met autoprops:

En andere manier die ook kan is als volgt:

De enige manier om FirstName een waarde te geven is via de constructor van de klasse. Alle andere manieren zal een error genereren.

hashtag
Snel autoproperties typen in Visual Studio:

Als je in Visual Studio in je code prop typt en vervolgens twee keer de tabtoets indrukt dan verschijnt al de nodige code voor een automatic property. Je hoeft dan enkel nog volgende zaken in orde te brengen:

  • Het type van de property

  • De naam van de property (identifier)

  • De toegankelijkheid van get/set (public, private, protected)

Via propg krijg je aan autoproperty met private setter.

hashtag
Methode of property

Een veel gestelde vraag bij beginnende OO-ontwikkelaars is: "Moet dit in een property of in een methode gestoken worden?"

De regel is eenvoudig:

  • Betreft het een actie, iets dat het object moet doen (tekst tonen, iets berekenen, etc) dan plaats je het in een methode

  • Betreft het een eigenschap die een bepaalde waarde heeft, dan gebruik je een property

H8: Klassen en objecten

get {}: indien je wenst dat de property data naar buiten moet sturen, dan schrijven we de get-code. Binnen de accolades van de get schrijven we wat er naar buiten moet gestuurd worden. In dit geval return energy maar dit mag even goed bijvoorbeeld return 4 of een hele reeks berekeningen zijn. Het element dat je returnt in de get code moet uiteraard van hetzelfde type zijn als waarmee je de property hebt gedefinieerd (int in dit geval).

  • We kunnen nu van buitenaf toch de waarde van energy uitlezen via de property en het get-gedeelte: Console.WriteLine(palpatine.Energy);

  • set{}: in het set-gedeelte schrijven we de code die we moeten hanteren indien men van buitenuit een waarde aan de property wenst te geven om zo een interne variabele aan te passen. De waarde die we van buitenuit krijgen (als een parameter zeg maar) zal altijd in een lokale variabele value worden bewaard. Deze zal van het type van de property zijn. Vervolgens kunnen we value toewijzen aan de interne variabele indien gewenst: energy=value

    • We kunnen vanaf nu van buitenaf waarden toewijzen aan de property en zo energyvtoch bereiken: palpatine.Energy=50.

  • Meer info.arrow-up-right
    Hier een iets meer uitgebreid PRO antwoordarrow-up-right
    public class SithLord
    {
        private int energy;
        private string sithName;
    }
    SithLord palpatine = new SithLord();
    Console.WriteLine(palpatine.sithName); //DIT ZAL DUS NIET WERKEN, daar sithName private is.
    public class SithLord
    {
        private int energy;
        private string sithName;
    
        public void SetSithName(string newname)
        {
            sithName = newname;
        }
    
        public string GetSithName()
        {
            return "YOU WISH!";
        }
    
        public void SetEnergy(int value)
        {
            if(value > 0 && value < 9999)
                energy = value;
        }
    
        public int GetEnergy()
        {
            return energy;
        }
    }
    SithLord vader = new SithLord();
    vader.SetEnergy(20); 
    Console.WriteLine($"Vaders energy is {vader.GetEnergy()}"); //get
    class SithLord
    {
        private int energy;
        private string sithName;
    
        public int Energy
        {
            get
            {
                return energy;
            }
            set
            {
                energy = value;
            }
        }
    }
    SithLord vader = new SithLord();
    vader.Energy = 20; //set
    Console.WriteLine($"Vaders energy is {Vader.Energy}"); //get
       public int Energy
        {
            get
            {
                return energy;
            }
            set
            {
                if(value >= 0)
                    energy = value;
            }
        }
       public int Energy
        {
            set
            {
                if(value >= 0)
                    energy = value;
            }
        }
       public int Energy
        {
            get
            {
                return energy;
            }
        }
       public int Energy
        {
            get
            {
                return energy;
            }
            private set
            {
                if(value >= 0)
                    energy = value;
            }
        }
    class SithLord
    {
        private int energy;
        private string sithName;
    
        public void ResetLord()
        {
            energy = -1;
        }
    
        public int Energy
        {
            get
            {
                return energy;
            }
            private set
            {
                if(value >= 0)
                    energy = value;
            }
        }
    }
    public void ResetLord()
    {
        Energy = -1; // Energy i.p.v. energy
    }
    public class Person
    {
        private string firstName;
        private string lastName;
    }
    public class Person
    {
        private string firstName;
        private string lastName;
        public string FullName
        {
            get{ return $"{firstName} {lastName}";}
        }
        public string Email
        {
            get
            {
                return $"{firstName}.{lastName}@ap.be";
            }
        }
    }
    public class Earth
    {
        public double GravityConstant
        {
            get
            {
                return 9.81;
            }
        }
    }
    public class Person
    {
        private int age;
    
        public bool IsProbablyAlive
        {
            get
            {
                if(age > 120) return false;
                return true;
            }
        }
    }
    public class Person
    {
        private int age; //in jaren
    
        public int AgeInMonths
        {
            get
            {
                return age * 12;
            }
        }
    }
    public class Person
        {
    
            private string firstName;
            private string lastName;
            private int age;
    
            public string FirstName
            {
                get
                {
                    return firstName;
                }
                set
                {
                    firstName = value;
                }
            }
    
            public string LastName
            {
                get
                {
                    return lastName;
                }
                set
                {
                    lastName = value;
                }
            }
    
            public int Age
            {
                get
                {
                    return age;
                }
                set
                {
                    age = value;
                }
            }
        }
    public class Person
        {
    
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int Age { get; set; }
    
        }
    public int Age {get;set;} = 45;
    set
    {
        if( value > 0)
            age = value;
    }
    public string FirstName
    {
    
        get
        {
            return firstName;
        }
    }
    public string FirstName { get; private set;}
    public string FirstName { get; }

    Klassen en objecten in C#

    In C# kunnen we geen objecten aanmaken voor we een klasse hebben gedefinieerd dat de algemene eigenschappen (properties) en werking (methoden) beschrijft.

    hashtag
    Klasse maken

    Een klasse heeft de volgende vorm:

    Volgende code beschrijft de klasse auto in C#

    Binnen het codeblock dat bij deze klasse hoort zullen we verderop dan de werking via properties en methoden beschrijven.

    De optionele access modifier komen we later op terug.

    hashtag
    Klassen in Visual Studio

    Je kan "eender waar" een klasse aanmaken, maar het is een goede gewoonte om per klasse een apart bestand te gebruiken:

    • In de solution explorer, rechterklik op je project

    • Kies Add

    • Kies Class..

    De naam van je klasse moet voldoen aan de identifier regels die ook gelden voor het aanmaken van variabelen!

    hashtag
    Objecten aanmaken

    Je kan nu objecten aanmaken van de klasse die je hebt gedefinieerd. Je doet dit door eerst een variabele te definiëren en vervolgens een object te instantiëren met behulp van het new keyword:

    We hebben nu twee objecten aangemaakt van het type Auto.

    Let goed op dat je dus op de juiste plekken dit alles doet (bekijk de onderstaande screenshot):

    • Klassen maak je aan als aparte files in je project

    • Objecten creëer je in je code op de plekken dat je deze nodig hebt, bijvoorbeeld in je Main methode bij een Console-applicatie

    Je hebt dus in het verleden ook al objecten aangemaakt. Telkens je met Random werkt deed je dit al. Dit wil zeggen dat er dus in .NET ergens reeds een voorgeprogrammeerde klasse Random bestaat met de interne werking.

    (Klassikale!) smaakmaker OOP

    hashtag
    1. Keuzemenuutje voor latere programma's

    hashtag
    Leerdoelen

    • Code makkelijk toegankelijk maken

    • Vermijden heleboel piepkleine projectjes aan te maken

    hashtag
    Functionele analyse

    We gaan leren werken met grotere hoeveelheden code. We zullen voortaan niet meer al onze programma's in een apart project plaatsen, maar een keuzemenu gebruiken om daaruit alle andere programma's op te starten.

    hashtag
    Technische analyse

    Wanneer de gebruiker de Main van de klasse Program opstart, krijg je een keuzemenuutje. Hierop worden omschrijvingen getoond voor alle oefeningen die je al hebt, gevolgd door de unieke titel van de oefening in kwestie. Wanneer de gebruiker het getal intypt dat overeenstemt met een oefening, wordt de oefening opgestart.

    Voorbeeldoutput:

    Wat wil je doen? 1. Vormen tekenen (h8-vormen) 2. Auto's laten rijden (h8-autos) 3. Patiënten tonen (h8-patienten) 4. Honden laten blaffen (h8-blaffende-honden)

    Wanneer de gebruiker een van deze opties kiest door het juiste getal in te typen, wordt dat programma opgestart. Als hij iets intypt dat niet kan worden uitgevoerd, komt er een boodschap ongeldig getal!. Wanneer je dit programma voor het eerst schrijft, kan je alleen nog maar ongeldige keuzes maken.

    hashtag
    2. Kennismaking OOP (h8-vormen)

    Doorloop de instructies en uitleg op , maar let op volgende zaken:

    • We werken niet in een map voor het vak "Programmeren 3", maar in een map "OOP" (zoals de namespace die we hanteren, maar dat is geen regel die C# oplegt).

    • Indien je reeds een project met de naam OOP hebt, hoef je géén nieuw project aan te maken.

    • Je gebruikt ShapesBuilder.cs in plaats van Vormen.cs

    hashtag
    3. Voorbeeld met auto's (h8-autos)

    hashtag
    Doelstelling

    • Kennismaking met OOP

    hashtag
    Functionele analyse

    We bouwen een simulatie van rijdende auto's. We voorzien deze van een kilometerteller, een huidige snelheid, een methode om de gaspedaal te simuleren en om de rem te simuleren.

    hashtag
    Technische analyse

    • We starten vanaf de klasse Auto uit de cursus (maar noemen deze Car).

    • We voegen eigenschappen Odometer en Speed toe, beide doubles.

    hashtag
    4. Refactoren van deze code (met allerlei arrays voor eigenschappen) die een verslag produceert met info (h8patienten)

    hashtag
    Doelstelling

    • Kennismaking met OOP

    • Kennismaking met refactoring

    • Toepassing van encapsulatie

    hashtag
    Functionele analyse

    We hebben al wat code, maar we vinden deze moeilijk te onderhouden omdat we allerlei variabelen moeten onderhouden. We refactoren deze om zo een meer objectgericht en beter onderhoudbaar programma te bekomen.

    hashtag
    Technische analyse

    • Introduceer een klasse Patient

    • Vervang alle arrays door één array van objecten van de klasse Patient

    • Zorg dat het afgeprinte verslag er identiek uitziet aan het oorspronkelijke verslag

    Code om van te starten:

    hashtag
    5. Voorbeeld abstractie (h8-honden)

    hashtag
    Doelstelling

    • Kennismaking met OOP Kennismaking met refactoring

    • Toepassing van abstractie

    hashtag
    Functionele analyse

    We krijgen een programma dat al objecten bevat, maar dit programma moet zelf nog veel rekening houden met hoe deze objecten in elkaar zitten. We refactoren het om zo een meer objectgericht en beter onderhoudbaar programma te bekomen.

    hashtag
    Technische analyse

    Je krijgt volgende twee files. De bestandsnamen volgen de afspraak:

    en

    Volg hierbij volgende stappen:

    • Maak de random generator statisch onderdeel van de klasse BarkingDog.

    • Voeg volgende code toe binnen de klasse BarkingDog:

    hashtag
    6. Controleren dat alles kan worden opgestart via keuzemenu.

    hashtag
    7. Alles in Git plaatsen en delen met de lector. Eerst controleren dat juiste files genegeerd worden met git status -u!

    [optionele access modifier] class className
    {
    
    }
    class Auto
    {
    
    }
    en schrijft in het algemeen je code in het Engels.
  • Je gebruikt de namespace OOP.Geometry in plaats van Wiskunde.Meetkunde.

  • Als je van stap 6 naar stap 7 gaat, laat je de code voor de eigenschap Color staan.

  • Later zullen we deze code refactoren om nog meer gebruik te maken van objecten.

  • We zorgen dat de snelheid nooit onder de 0km/u kan gaan en nooit boven de 120km/u door de eigenschap aan te passen.

  • We schrijven klassikaal een methode Gas() die de snelheid met 10km/u verhoogt en de auto verplaatst met zijn gemiddelde snelheid / 60 (om één minuut rijden te simuleren). De gemiddelde snelheid is het gemiddelde van de snelheid voor en na het verhogen.

  • We schrijven individueel een methode Brake die gelijkaardig werkt, maar die de snelheid met 10 km/u verlaagt.

  • We schrijven een methode Main

    • die twee auto's aanmaakt

    • de eerste vijf keer laat versnellen, drie keer laat remmen

    • de tweede tien keer laat versnellen en een keer laat remmen

    • in onderstaand formaat de snelheid en afgelegde weg afprint: auto 1: km/u, afgelegde weg km auto 2: km/u, afgelegde weg km

  • ModernWaysarrow-up-right
    using System; 
    
    namespace OOP {     
       class PatientProgram {         
          public static void Main() {             
             Console.WriteLine("Hoe veel patiënten zijn er?"); // aanmaken van de nodige variabelen
             int numberOfPatients = int.Parse(Console.ReadLine());
             string[] patientNames = new string[numberOfPatients];
             string[] patientGenders = new string[numberOfPatients];
             string[] patientLifestyles = new string[numberOfPatients];
             int[] patientDays = new int[numberOfPatients];
             int[] patientMonths = new int[numberOfPatients];
             int[] patientYears = new int[numberOfPatients];
    
             // invullen van de rijen
             for(int i = 0; i < numberOfPatients; i++) {
                patientNames[i] = Console.ReadLine();
                patientGenders[i] = Console.ReadLine();
                patientLifestyles[i] = Console.ReadLine();
                patientDays[i] = int.Parse(Console.ReadLine());
                patientMonths[i] = int.Parse(Console.ReadLine());
                patientYears[i] = int.Parse(Console.ReadLine());
             }
    
             // afprinten van het verslag
             // variabele in twee keer toegekend om code niet te breed te maken
             for(int i = 0; i < numberOfPatients; i++) {
                string info = $"{patientNames[i]} ({patientGenders[i]}, {patientLifestyles[i]})";
                info += $", geboren {patientDays[i]}-{patientMonths[i]}{patientYears[i]}";
                Console.WriteLine(info);
             }
          }
       }
    }
    using System; 
    
    namespace OOP {
       class BarkingProgram {
          // nu maken we onze randomgenerator *buiten* Main
          public static Random rng = new Random();
          public static void Main() {
             BarkingDog dog1 = new BarkingDog();
             BarkingDog dog2 = new BarkingDog();
             dog1.Name = "Swieber";
             dog2.Name = "Misty";
             dog1BreedNumber = rng.Next(0,3);
             dog2BreedNumber = rng.Next(0,3);
             if(dog1BreedNumber == 0) {
                dog1.Breed = "German Shepherd";
             }             
             else if(dog1BreedNumber == 1) {
                dog1.Breed = "Wolfspitz";
             }
             else {
                dog1.Breed = "Chihuahua";
             }
             if(dog2BreedNumber == 0) {
                dog2.Breed = "German Shepherd";
             }
             else if(dog2BreedNumber == 1) {
                dog2.Breed = "Wolfspitz";
             }
             else {
                dog2.Breed = "Chihuahua";
             }
             while(true) {
                Console.WriteLine(dog1.Bark());
                Console.WriteLine(dog2.Bark());
             }
          }
       }
    }
    namespace OOP {
        class BarkingDog {
            public string Name;
            public string Breed;
    
            public string Bark() {
                if(Breed == "German Shepherd") {
                    return "RUFF!";
                }
                else if(Breed == "Wolfspitz") {
                    return "AwawaWAF!";
                }
                else if(Breed == "Chihuahua") {
                    return "ARF ARF ARF!";
                }
                // dit zou nooit mogen gebeuren
                // maar als de programmeur van Main iets fout doet, kan het wel
                else {
                    return "Euhhh... Miauw?";
                }
            }
        }
    }
    public BarkingDog() {
        // bepaal hier met de randomgenerator het ras van de hond
        // stel hier `Breed` in
        // maak van `Breed` een eigenschap zoals we dat bij de geometrische vormen hebben gedaan
    }
    Geef een goede naam voor je klasse
    Klasse toevoegen in VS
    basics oop same in vv

    Oefeningen

    hashtag
    Richtlijnen

    hashtag
    Structuur oefeningen

    Vanaf hier veronderstellen we dat je in één groot project werkt dat één klasse Program heeft. De oefeningen worden los van elkaar omschreven, maar je zorgt ervoor dat ze getest kunnen worden via het keuzemenu in je klasse Program.

    hashtag
    meerdere Main methodes

    Indien je meerdere klassen hebt met een methode Main, moet je aangeven welke normaal gebruikt wordt voor de uitvoering van je programma. Dat doe je door aan je .csproj-bestand het volgende toe te voegen: <StartupObject>Namespace-van-de-opstartklasse.Naam-van-de-opstartklasse</StartupObject>

    triangle-exclamation

    Dit staat hier niet zomaar! Als je dit niet doet, zullen je oefeningen niet uitgevoerd kunnen worden. Je .csproj file staat in dezelfde map als je .cs-bestanden en indien het niet opent in Visual Studio, kan je het openen in Kladblok.

    Bijvoorbeeld:

    (Je file zou er al gelijkaardig moeten uitzien, maar je moet zelf het StartupObject toevoegen.)

    hashtag
    Oefening: H8-dag-van-de-week

    hashtag
    Leerdoelen

    • aanmaken van DateTime objecten

    • formatteren van DateTime objecten

    hashtag
    Functionele analyse

    We willen voor een willekeurige datum kunnen bepalen welke dag van de week het is.

    hashtag
    Technische analyse

    • je moet eerst de dag, maand en jaar opvragen en een DateTime aanmaken

    • daarna moet je laten zien over welke dag van de week het gaat

      • gebruik hiervoor formattering van een DateTime

    hashtag
    Voorbeeldinteractie

    hashtag
    Oefening: H8-ticks-sinds-2000

    hashtag
    Leerdoelen

    • aanmaken van DateTime objecten

    hashtag
    Functionele analyse

    We willen weten hoe veel fracties van een seconde al verlopen zijn sinds het begin van de jaren 2000.

    hashtag
    Technische analyse

    • .NET stelt deze fracties (1 / 10000 milliseconden) voor als "ticks"

    • We willen weten hoe veel ticks er voorbijgegaan zijn sinds het absolute begin van het jaar 2000

    • Noem de klasse waarin je dit schrijft Ticks2000Program

    hashtag
    Voorbeeldinteractie

    hashtag
    Oefening: H8-schrikkelteller

    hashtag
    Leerdoelen

    • gebruik van een statische property

    hashtag
    Functionele analyse

    We willen bepalen hoe veel schrikkeljaren er zijn tussen 1800 en 2020.

    hashtag
    Technische analyse

    • implementeer zelf een logica voor schrikkeljaren, maar laat dit over aan de klassen DateTime

    • maak gebruik van een statische methode van deze klasse

    • noem je klasse LeapYearProgram en voorzie ze van een Main

    hashtag
    Voorbeeldinteractie

    hashtag
    Oefening: H8-simpele-timing

    hashtag
    Leerdoelen

    • eenvoudig code leren timen

    • gebruiken van DateTime

    • herhaling arrays

    hashtag
    Functionele analyse

    We zijn benieuwd hoe lang het duurt een array van 1 miljoen ints te maken en op te vullen met de waarden 1,2,...

    hashtag
    Technische analyse

    • Bepaal het tijdstp voor en na aanmaken van de array.

    • Vul de array in met een for-lus.

    • Noem de klasse waarin je dit schrijft ArrayTimerProgram

    hashtag
    Voorbeeldinteractie

    hashtag
    Oefening: H8-RapportModule-V1

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van simpele properties en methodes

    hashtag
    Functionele analyse

    Dit programma geeft op basis van de input van een percentage de graad weer die je met dit gegeven zou behaald hebben.

    hashtag
    Technische analyse

    Ontwerp een klasse ResultV1 die je zal tonen wat je graad is gegeven een bepaald behaald percentage. Het enige dat je aan een ResultV1-object moet kunnen geven is het behaalde percentage. Enkel het totaal behaalde percentage wordt bijgehouden. Via een methode PrintHonors kan de behaalde graad worden weergegeven. Dit zijn de mogelijkheden:

    • < 50: niet geslaagd;

    • tussen 50 en 68: voldoende;

    • tussen 68 en 75: onderscheiding;

    Je hoeft voorlopig geen rekening te houden met ongeldige waarden. Test je klasse door ResultV1 ook van een statische methode Main te voorzien, waarin je enkele objecten van deze klasse aanmaakt en de verschillende properties waarden te geeft en vervolgens PrintHonors oproept.

    hashtag
    Oefening: H8-RapportModule-V2

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van simpele properties en methodes

    hashtag
    Functionele analyse

    Dit programma geeft op basis van de input van een percentage de graad weer die je met dit gegeven zou behaald hebben.

    hashtag
    Technische analyse

    Ontwerp een klasse ResultV2 die je zal vertellen wat je graad is gegeven een bepaald behaald percentage. Het enige dat je aan een ResultV2-object moet kunnen geven is het behaalde percentage. Enkel het totaal behaalde percentage wordt bijgehouden. Via een methode ComputeHonors kan de behaalde graad worden teruggegeven. Dit werkt op dezelfde manier als in versie 1 van deze oefening, maar de verschillende graden worden voorgesteld met een Enum, Honors. De methode ComputeHonors toont het resultaat niet, maar geeft een waarde van deze Enum terug. Het is aan de Main om deze waarde af te printen, zodat je kan zien of je code werkt.

    Test je klasse op dezelfde manier als versie 1. De teruggegeven waarden van Honors mag je in de Main meegeven aan Console.WriteLine.

    hashtag
    Oefening: H8-Getallencombinatie

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van properties

    hashtag
    Functionele analyse

    Dit programma geeft op basis van de input van twee getallen de som van beide getallen, het verschil, het product en de deling. In het laatste geval en indien er een deling door nul zou worden uitgevoerd, wordt dit woordelijk weergegeven.

    hashtag
    Technische analyse

    Maak een eenvoudige klasse NumberCombination. Deze klasse bevat 2 getallen (type int). Er zijn 4 methoden, die allemaal een double teruggeven:

    • Sum: geeft som van beide getallen weer

    • Difference: geeft verschil van beide getallen weer

    • Product

    Gebruik full properties voor Number1 en Number2 en toon in je Main aan dat je code werkt.

    Volgende code zou namelijk onderstaande output moeten geven:

    hashtag
    Voorbeeldinteractie(s)

    hashtag
    Oefening: H8-Figuren

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van properties om geldige waarden af te dwingen

    hashtag
    Functionele analyse

    Dit programma maakt enkele rechthoeken en driehoeken met gegeven afmetingen (in meter) aan, berekent hun oppervlakte en toont deze info aan de gebruiker. De rechthoeken en driehoeken die worden aangemaakt, zijn al gecodeerd in het programma. De gebruiker hoeft dus niets anders te doen dan het programma te starten.

    hashtag
    Technische analyse

    Er is een klasse Rectangle met properties Width en Height en een klasse Triangle met Base en Height. Je programma maakt de figuren die hierboven beschreven worden aan met waarde 1.0 voor elke afmeting en stelt daarna hun afmetingen in via de setters voor deze properties. De oppervlakte wordt bepaald in een read-only property, Surface van het type double.

    Indien om het even welk van deze properties wordt ingesteld op 0 (of minder) wordt er een foutboodschap afgeprint en wordt de afmeting niet aangepast.

    De wiskundige formule voor de oppervlakte van een driehoek is basis * hoogte / 2.

    Schrijf de voorbeelden uit in de Main van een extra klasse, FigureProgram.

    hashtag
    Voorbeeldinteractie(s)

    (Er worden twee rechthoeken en twee driehoeken aangemaakt. De afmetingen van de eerste rechthoek worden eerst op -1 en 0 ingesteld.

    hashtag
    Oefening: H8-Studentklasse

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van properties om geldige waarden af te dwingen

    hashtag
    Functionele analyse

    Dit programma vraagt om de naam en leeftijd van een student. Er moet ook worden meegeven in welke klasgroep de student is ingeschreven. De groepen zijn EA1, EA2 en EB1. Vervolgens worden de punten voor 3 vakken gevraagd, waarna het gemiddelde wordt teruggegeven.

    hashtag
    Technische analyse

    Maak een nieuwe klasse Student. Deze klasse heeft 6 properties. Leeftijd en de punten stel je voor met full properties. Een student kan nooit ouder zijn dan 120. Je kan ook nooit een cijfer boven 20 behalen. Over leeftijden en cijfers onder 0 hoef je je geen zorgen te maken, want de achterliggende variabelen zijn bytes en die zijn altijd minstens 0.

    • Name (string)

    • Age (byte)

    • ClassGroup (maak hiervoor een enum ClassGroups)

    Voeg aan de klasse een read-only property OverallMark toe. Deze berekent het gemiddelde van de 3 punten als double.

    Voeg aan de klasse ook de methode ShowOverview() toe. Deze methode zal een volledig rapport van de student tonen (inclusief het gemiddelde m.b.v. de OverallMark-property).

    Test je programma door enkele studenten aan te maken en in te stellen. Volgende statische methode Main zet je in de klasse Student.

    hashtag
    Voorbeeldinteractie(s)

    hashtag
    H8-uniform-soldiers

    hashtag
    Functionele analyse

    Je krijgt code die deel zou kunnen uitmaken van een videogame. Met deze code wordt bijgehouden hoe veel schade elke soldaat aanricht. De schade is niet constant. Als je een upgrade aankoopt, doen al je soldaten dubbel zo veel schade als eerder. We hebben al werkende code, maar ze maakt het moeilijk te verzekeren dat elke soldaat even veel schade aanricht. Pas aan zodat dit ingebakken is in de code.

    hashtag
    Technische analyse

    Je krijgt volgende klassen (SoldierGame en Soldier):

    Gebruik hiervoor een sleutelwoordje dat zorgt dat de hoeveelheid schade niet specifiek is voor één soldaat, maar dezelfde is voor alle soldaten. We hebben het ook gebruikt om te bepalen of een jaar een schrikkeljaar is, omdat die berekening niet specifiek is voor één datum. Pas ook de demonstratiemethode aan.

    hashtag
    H8-utility-methode

    hashtag
    Functionele analyse

    We hebben code voor een berekening. Deze werkt, maar vereist dat we een object aanmaken dat geen duidelijke functie heeft, namelijk een MyMath-object. Het is moeilijk te zeggen wat "één wiskunde" betekent, dus we zouden liefst niet met objecten werken.

    hashtag
    Technische analyse

    Je krijgt twee klassen, MathProgram en MyMath. Pas aan zodat je dezelfde berekening kan uitvoeren, zonder dat je objecten van de klasse MyMath hoeft aan te maken.

    en

    hashtag
    Oefening: H8-RapportModule-V3

    hashtag
    Leerdoelen

    • werken met klassen en objecten

    • gebruik maken van properties om geldige waarden af te dwingen

    hashtag
    Functionele analyse

    Deze is gelijkaardig aan de vorige versie van het programma, maar gebruikt iets geavanceerdere technieken.

    hashtag
    Technische analyse

    Maak een nieuwe versie van H8-RapportModule-V2, waarbij je een full property gebruikt voor het percentage. Zorg ervoor dat dit steeds tussen 0 en 100 ligt. Vervang ook ComputeHonors door een read-only property, Honors.

    hashtag
    H8-honden

    hashtag
    Doelstelling

    • Kennismaking met OOP

    • Kennismaking met refactoring

    • Toepassing van abstractie

    hashtag
    Functionele analyse

    We krijgen een programma dat al objecten bevat, maar dit programma moet zelf nog veel rekening houden met hoe deze objecten in elkaar zitten. We refactoren het om zo een meer objectgericht en beter onderhoudbaar programma te bekomen.

    hashtag
    Technische analyse

    Je krijgt volgende twee files. De bestandsnamen volgen de afspraak:

    en

    Volg hierbij volgende stappen:

    • Maak de random generator een geëncapsuleerd statisch attribuut van de klasse BarkingDog.

    • Vervang de instantievariabele Name door een autoproperty en vervang de instantievariabele Breed door een read-only full property.

    Test uiteindelijk via de Main van Program de Main van BarkingProgram.

    Methoden en access modifiers

    hashtag
    Een eenvoudige klasse

    We zullen nu enkele basisconcepten van klassen en objecten toelichten aan de hand van praktische voorbeelden.

    hashtag
    Object methoden

    Stel dat we een klasse willen maken die ons toelaat om objecten te maken die verschillende mensen voorstellen. We willen aan iedere mens kunnen vragen waar deze woont en die zal dat dan op het scherm tonen.

    We maken een nieuwe klasse Human en maken een methode Speak die iets op het scherm zet:

    We zien twee nieuwe aspecten:

    • Het keyword static komt bij een klasse niet aan te pas (of toch minder zoals we )

    • Voor de methode plaatsen we public : dit leggen we zo meteen uit

    Je kan nu elders objecten aanmaken en ieder object z'n methode Speak aanroepen:

    Er zal 2x Ik ben een mens! op het scherm verschijnen. Waarbij telkens ieder object (joske en alfons) zelf verantwoordelijk ervoor waren dat dit gebeurde.

    hashtag
    Public en private access modifiers

    De access modifier geeft aan hoe zichtbaar een bepaalde deel van de klasse is. Wanneer je niet wilt dat "van buitenuit" (bv objecten van je klasse in de Main) een bepaalde methode kan aangeroepen worden, dan dien je deze als private in te stellen. Wil je dit net wel dat moet je er expliciet public voor zetten.

    Test in de voorgaande klasse eens wat gebeurt wanneer je public vervangt door private voor de methode. Inderdaad, je zal de methode Speak niet meer op de objecten kunnen aanroepen.

    Test volgende klasse eens, kan je de methode TellSecret vanuit de Main op joske aanroepen?

    Je kan klassen, methodes,... ook noteren zonder public of private maar er is een betekenisverschil. Wij verwachten dat je altijd expliciet noteert wat je verwacht.

    hashtag
    Reden van private

    Waarom zou je bepaalde zaken private maken?

    Stel dat we in de klasse extra (hulp)methoden willen gebruiken die enkel intern nodig zijn, dan doen we dit. Volgende voorbeeld toont hoe we in de methode Speak de private methode TellSecret gebruiken:

    Als we nu elders een object laten praten als volgt:

    Dan zal de uitvoer worden:

    hashtag
    Instantie variabelen

    We maken onze klasse wat groter, we willen dat een object een leeftijd heeft die we kunnen verhogen via een methode CelebrateBirthday (we hebben de methode TellSecret even weggelaten):

    Hier zien we een pak details de onze aandacht vereisen:

    • Ook variabelen zoals int age mogen een access modifier krijgen in een klasse. Variabelen als deze zetten we altijd op private (tenzij we in de les iets aan het demonstreren zijn).

    • Ook al is age private , alle methoden in de klasse kunnen hier aan. Het is enkel langs buiten dat bijvoorbeeld volgende code niet zal werken rachid.age = 34;

    Die laatste opmerking is een kernconcept van OOP: ieder object heeft z'n eigen interne staat die kan aangepast worden individueel van de andere objecten van hetzelfde type.

    We zullen dit testen in volgende voorbeeld waarin we 2 objecten maken en enkel 1 ervan laten verjaren. Kijk wat er gebeurt:

    Als je deze code zou uitvoeren zal je zien dat de leeftijd van Elvis verhoogt en niet die van Bono wanneer we CelebrateBirthday aanroepen. Zoals het hoort!

    Auto mijnEerste = new Auto();
    Auto mijnAndereAuto = new Auto();

    We kunnen iedere variabele een beginwaarde geven.

  • Ieder object zal z'n eigen leeftijd hebben

  • later zullen zienarrow-up-right
  • laat ook de datum zelf zien in een formaat dat leesbaar is voor de gebruiker

  • als je computer niet volledig ingesteld is op Belgisch Nederlands, kan het resultaat er wat anders uitzien.

  • noem de klasse waarin je dit schrijft DayOfWeekProgram

    • schrijf je code in de statische methode Main

    • roep de statische Main van DayOfWeekProgram op in het keuzemenu van Program

  • tussen 75 en 85: grote onderscheiding;
  • > 85: grootste onderscheiding.

  • : geeft product van beide getallen weer
  • Quotient: geeft deling van beide getallen weer. Print "Error" naar de console indien je zou moeten delen door 0 en voer dan de deling uit. Wat er dan gebeurt, is niet belangrijk.

  • MarkCommunication (byte)

  • MarkProgrammingPrinciples (byte)

  • MarkWebTech (byte)

  • Voeg volgende code toe binnen de klasse BarkingDog:
    public class Human
    {
        public void Speak()
        {
            Console.WriteLine("Ik ben een mens!");
        }
    }
    Human joske = new Human();
    Human alfons = new Human();
    
    joske.Speak();
    alfons.Speak();
    public class Human
    {
        public void Speak()
        {
            Console.WriteLine("Ik ben een mens!");
        }
    
        private void TellSecret()
        {
            Console.WriteLine("Mijn geheim is dat ik leef!");
        }
    }
    public class Human
    {
        public void Speak()
        {
            Console.WriteLine("Ik ben een mens!");
            TellSecret();
        }
    
        private void TellSecret()
        {
            Console.WriteLine("Mijn geheim is dat ik leef!");
        }
    }
    Human rachid = new Human();
    rachid.Speak();
    Ik ben een mens!
    Mijn geheim is dat ik leef!
    public class Human
    {
        private int age = 1;
    
        public void CelebrateBirthday()
        {
            Console.WriteLine("Hiphip hoera voor mezelf!");
            age++;
            Speak();
        }
    
        public void Speak()
        {
            Console.WriteLine("Ik ben een mens! ");
            Console.WriteLine($"Ik ben {age} jaar oud");
        }
    }
    Human elvis = new Human();
    Human bono = new Human();
    
    elvis.CelebrateBirthday();
    elvis.CelebrateBirthday();
    elvis.CelebrateBirthday();
    bono.CelebrateBirthday();
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <StartupObject>OOP.Program</StartupObject>
      </PropertyGroup>
    </Project>
    Welke dag?
    > 14
    Welke maand?
    > 2
    Welk jaar?
    > 2020
    14 februari 2020 is een vrijdag.
    Sinds 1 januari 2000 zijn er (hier wordt het aantal getoond) ticks voorbijgegaan.
    Er zijn (hier wordt het aantal getoond) schrikkeljaren tussen 1800 en 2020.
    Het duurt (hier wordt het aantal getoond) milliseconden om een array van een miljoen elementen aan te maken en op te vullen met opeenvolgende waarden.
    NumberCombination pair1 = new NumberCombination();
    pair1.Number1 = 12;
    pair1.Number2 = 34;
    Console.WriteLine("Paar:" + pair1.Number1 + ", " + pair1.Number2);
    Console.WriteLine("Sum = " + pair1.Sum());
    Console.WriteLine("Verschil = " + pair1.Difference());
    Console.WriteLine("Product = " + pair1.Product());
    Console.WriteLine("Quotient = " + pair1.Quotient());
    Paar: 12, 34
    Som = 46
    Verschil = -22
    Product = 408
    Quotient = 0,352941176470588
    Het is verboden een breedte van -1 in te stellen!
    Het is verboden een breedte van 0 in te stellen!
    Een rechthoek met een breedte van 2,2m en een hoogte van 1,5m heeft een oppervlakte van 3,3m².
    Een rechthoek met een breedte van 3m en een hoogte van 1m heeft een oppervlakte van 3m².
    Een driehoek met een basis van 3m en een hoogte van 1m heeft een oppervlakte van 1,5m².
    Een driehoek met een basis van 2m en een hoogte van 2m heeft een oppervlakte van 2m².
    Student student1= new Student();
    student1.Class = ClassGroups.EA2;
    student1.Age = 21;
    student1.Name = "Joske Vermeulen";
    student1.MarkCommunication = 12;
    student1.MarkProgrammingPrinciples = 15;
    student1.MarkWebTech = 13;
    student1.ShowOverview();
    Joske Vermeulen, 21 jaar
    Klas: EA2
    
    Cijferrapport:
    **********
    Communicatie:             12
    Programming Principles:   15
    Web Technology:           13
    Gemiddelde:               13.3
    using System;
    
    namespace OOP {
        class SoldierGame {
            public static void Main() {
                Soldier soldier1 = new Soldier();
                soldier1.Health = 100;
                soldier1.Damage = 20;
                Soldier soldier2 = new Soldier();
                soldier2.Health = 99; // om maar te tonen dat dit mag verschillen per soldaat
                soldier2.Damage = 20;
                Soldier soldier3 = new Soldier();
                soldier3.Health = 98;
                soldier3.Damage = 20;
                // beeld je in dat de game wat verder loopt
            /* nadeel van deze werkwijze: we moeten veronderstellen dat 
               wat geldt voor soldaat1 ook geldt voor de rest */
            Console.WriteLine($"Schade per soldaat: {soldier1.Damage}");
                // nu volgt de upgrade
                soldier1.Damage *= 2;
                soldier2.Damage *= 2;
                soldier3.Damage *= 2;
            /* nadeel van deze werkwijze: we moeten veronderstellen dat 
               wat geldt voor soldaat1 ook geldt voor de rest */
            Console.WriteLine($"Schade per soldaat: {soldier1.Damage}");
            }
        }
    }
    namespace OOP {
        class Soldier {
            private int health;
            public int Health {
                get {
                    return health;
                }
                set {
                    if (value >= 0 && value <= 100) {
                        health = value;
                    }
                }
            }
            private int damage;
            public int Damage {
                get {
                    return damage;
                }
                set {
                    if (value >= 0 && value <= 100) {
                        damage = value;
                    }
                }
            }
        }
    }
    using System;
    
    namespace OOP {
        class MathProgram {
            public static void Main() {
                MyMath calculcator = new MyMath();
                Console.WriteLine(calculator.DoubleAddTwo(13));
            }
        }
    }
    namespace OOP {
        class MyMath {
            public int DoubleAddTwo(int n) {
                return 2*n+2;
            }
        }
    }
    using System;
    
    namespace OOP {
        class BarkingProgram {
    
            // nu maken we onze randomgenerator *buiten* Main
            public static Random rng = new Random();
            public static void Main() {
                BarkingDog dog1 = new BarkingDog();
                BarkingDog dog2 = new BarkingDog();
                dog1.Name = "Swieber";
                dog2.Name = "Misty";
                dog1BreedNumber = rng.Next(0,3);
                dog2BreedNumber = rng.Next(0,3);
                if(dog1BreedNumber == 0) {
                    dog1.Breed = "German Shepherd";
                }
                else if(dog1BreedNumber == 1) {
                    dog1.Breed = "Wolfspitz";
                }
                else {
                    dog1.Breed = "Chihuahua";
                }
                if(dog2BreedNumber == 0) {
                    dog2.Breed = "German Shepherd";
                }
                else if(dog2BreedNumber == 1) {
                    dog2.Breed = "Wolfspitz";
                }
                else {
                    dog2.Breed = "Chihuahua";
                }
                while(true) {
                    Console.WriteLine(dog1.Bark());
                    Console.WriteLine(dog2.Bark());
                }
            }
        }
    }
    namespace OOP {
        class BarkingDog {
            public string Name;
            public string Breed;
    
            public string Bark() {
                if(Breed == "German Shepherd") {
                    return "RUFF!";
                }
                else if(Breed == "Wolfspitz") {
                    return "AwawaWAF!";
                }
                else if(Breed == "Chihuahua") {
                    return "ARF ARF ARF!";
                }
                // dit zou nooit mogen gebeuren
                // maar als de programmeur van Main iets fout doet, kan het wel
                else {
                    return "Euhhh... Miauw?";
                }
            }
        }
    }
    public BarkingDog() {
      // deze code wordt uitgevoerd wanneer een nieuwe hond wordt aangemaakt
      // bepaal hier met de randomgenerator het ras van de hond
    }

    DateTime: leren werken met objecten

    hashtag
    DateTime

    De .NET klasse DateTime is de ideale manier om te leren werken met objecten. Het is een nuttige en toegankelijk klasse.

    Grote delen van deze tekst komen van zetoode.comarrow-up-right.

    hashtag
    DateTime objecten aanmaken

    Er zijn 2 manieren om DateTime objecten aan te maken:

    1. Door aan de klasse de huidige datum en tijd te vragen via DateTime.Now

    2. Door manueel de datum en tijd in te stellen via de constructor

    hashtag
    DateTime.Now

    Volgend voorbeeld toont hoe we een object kunnen maken dat de huidige datum tijd van het systeem bevat. Vervolgens printen we dit op het scherm:

    hashtag
    Met constructor

    Via de constructor kunnen we beginwaarden meegeven bij het maken van een nieuw object. Er zijn 11 manieren waarop dit kan zoals je .

    Enkele voorbeelden:

    hashtag
    DateTime methoden

    Ieder DateTime object dat je aanmaakt heeft en hoop nuttige methoden.

    hashtag
    Add Methods

    Deze methoden kan je gebruiken om een bepaalde aantal dagen, uren, minuten en zo voort aan je huidige object toe te voegen. Al deze methoden geven steeds een nieuw DateTime object terug dat je moet bewaren wil je er iets mee doen:

    • AddDays

    • AddHours

    • AddMilliseconds

    Een voorbeeld:

    (voorgaande kan ook in 1 lijn: DateTime nextWeek= DateTime.Now.AddDays(7))

    Uiteraard mag je ook een bestaand object overschrijven met het resultaat van deze methoden:

    hashtag
    DateTime properties

    Properties (eigenschappen) zijn een zeer uniek aspect van C#. We zullen deze nog tot in den treuren leren maken. Via properties kan je de interne staat van objecten uitlezen én aanpassen, dit op een gecontroleerde manier.

    Het fijne aan properties is dat :

    • je gebruikt ze alsof het gewone variabelen zijn

    • maar ze werken als methoden

    Meer hierover later.

    Enkele nuttige properties van DateTime zijn:

    • Date

    • Day

    • DayOfWeek

    hashtag
    Properties gebruiken

    Sommige properties zijn read-only, andere kan je zowel naar schrijven als uitlezen. Alle properties van DateTime zijn read-only*..

    Een voorbeeld:

    Uiteraard mag je ook deze properties gebruiken om direct naar het scherm te schrijven:

    hashtag
    Datum en tijd formateren

    Je hebt een invloed op hoe DateTime objecten naar string worden opgezet. Je kan dit door door extra formatter syntax mee te geven.

    Dit zie je in volgende voorbeeld:

    hashtag
    Custom format

    Wil je nog meer controle over de output dan kan je ook zelf je formaat specifieren.

    hashtag
    Localized time

    De manier waarop DateTime objecten worden getoond (via ToString) is afhankelijk van de landinstellingen van je systeem. Soms wil je echter op een andere manier dit tonen. Je doet dit door mee te geven volgens welke culture de tijd en datum getoond moet worden.

    Dit vereist dat je eerst een CultureInfo aanmaakt en dat je dan meegeeft:

    hashtag
    Culture names

    Een lijst van alle cultures in .NET kan je . Opgelet, enkel indien een specifieke culture op je computer staat geïnstalleerd zal je deze kunnen gebruiken.

    hashtag
    Static method

    Sommige methoden zijn static dat wil zeggen dat je ze enkel rechtstreeks op de klasse kunt aanroepen. Vaak zijn deze methoden hulpmethoden waar de individuele objecten niets aan hebben.

    hashtag
    Parsing time

    Parsen laat toe dat je strings omzet naar DateTime. Dit is handig als je bijvoorbeeld de gebruiker via ReadLine tijd en datum wilt laten invoeren:

    Zoals je ziet roepen we Parse aan op DateTime en dus niet op een specifiek object.

    hashtag
    IsLeapYear

    Deze nuttige methode geeft een bool terug om aan te geven het meegegeven object eens schrikkeljaar is of niet:

    hashtag
    TimeSpan (PRO)

    Je kan DateTime objecten ook bij mekaar optellen en aftrekken. Het resultaat van deze bewerking geeft echter NIET een DateTime object terug, maar een TimeSpan object. Dit is een object dat dus aangeeft hoe groot het verschil is tussen de 2 DateTime objecten:

    hashtag
    Oefening

    hashtag
    Klokje

    Maak een applicatie die bestaat uit een oneindige loop. De loop zal iedere seconde pauzeren: System.Threading.Thread.Sleep(1000);. Vervolgens wordt het scherm leeg gemaakt en wordt de huidige tijd getoond. Merk op dat ENKEL de tijd wordt getoond, niet de datum.

    hashtag
    Verjaardag

    Maak een applicatie die aan de gebruiker vraagt op welke dag hij jarig is. Toon vervolgens over hoeveel dagen z'n verjaardag dan zal zijn.

    AddMinutes
  • AddMonths

  • AddSeconds

  • AddTicks

  • AddYears

  • DayOfYear
  • Hour

  • Millisecond

  • Minute

  • Month

  • Second

  • Ticks

  • TimeOfDay

  • Today

  • UtcNow

  • Year

  • hier kan zienarrow-up-right
    Dit wordt hier volledig uit de doeken gedaan.arrow-up-right
    hier terugvindenarrow-up-right
            DateTime currentTime = DateTime.Now;
            Console.WriteLine(currentTime);
    DateTime birthday = new DateTime(1982, 3, 18); //year, month, day
    
    DateTime someMomentInTime = new DateTime(2017, 1, 18, 10, 16,34 ); //year, month, day, hour, min, sec
    DateTime timeNow= DateTime.Now;
    
    DateTime nextWeek= timeNow.AddDays(7);
    DateTime someTime= new DateTime(2019, 4, 1);
    
    //much later...
    someTime = someTime.AddYears(10);
    Console.WriteLine(someTime);
    DateTime moment = new DateTime(1999, 1, 13, 3, 57, 32, 11);
    
    // Year gets 1999.
    int year = moment.Year;
    
    // Month gets 1 (January).
    int month = moment.Month;
    
    // Day gets 13.
    int day = moment.Day;
    
    // Hour gets 3.
    int hour = moment.Hour;
    
    // Minute gets 57.
    int minute = moment.Minute;
    
    // Second gets 32.
    int second = moment.Second;
    
    // Millisecond gets 11.
    int millisecond = moment.Millisecond;
    DateTime now = DateTime.Now;
    
    Console.WriteLine($"The current day is {now.DayOfWeek}");
    DateTime now = DateTime.Now;
    
    WriteLine(now.ToString("d")); // short date 
    WriteLine(now.ToString("D")); // long date
    WriteLine(now.ToString("F")); // full date and time
    WriteLine(now.ToString("M")); // month and day
    WriteLine(now.ToString("o")); // date en time separated by T and time zone at the end
    WriteLine(now.ToString("R")); // RFC1123 date and time
    WriteLine(now.ToString("t")); // short time
    WriteLine(now.ToString("T")); // long time
    WriteLine(now.ToString("Y")); // year and month
    DateTime now = DateTime.Now;
    CultureInfo russianCI = new CultureInfo("ru-RU");
    
    Console.WriteLine($"Current time in Russian style is: {now.ToString("F", russianCI)}");
    string date_string = "8/11/2016"; //dit zou dus ook door gebruiker kunnen ingetypt zijn
    DateTime dt = DateTime.Parse(date_string);
    Console.WriteLine(dt);
    DateTime today= DateTime.Now;
    bool isLeap= DateTime.IsLeapYear(today.Year);
    if(isLeap==true)
        Console.WriteLine("This year is a leap year");
    DateTime today = DateTime.Today;
    DateTime borodino_battle = new DateTime(1812, 9, 7);
    
    TimeSpan diff = today - borodino_battle;
    
    WriteLine("{0} days have passed since the Battle of Borodino.", diff.TotalDays);