In deze cursus zullen cruciale leerstofonderdelen van vorig jaar hernomen en aangevuld worden. We starten deze cursus met een heropfrissing van de principes van het objectgeoriënteerd programmeren. Daarna gaan we verder met overerving en polymorfisme, twee essentiële onderdelen voor c#-toepassingen.
Jullie hebben in het eerste jaar een voldoende basiskennis verworven om een aantal technieken en principes uit te diepen. Uitermate belangrijk hierbij zijn een voldoende kennis van controlestructuren (if, switch, lussen zoals while en for), operatoren en arrays. Een basiskennis over de begrippen klasse, methode, constructor, eigenschap is ook onontbeerlijk. Eventueel zal je met de cursus van vorig jaar deze kennis moeten opfrissen.
using System;
namespace Tijd
{
public class Tijd
{
private int uur; // 0-23
private int minuut; // 0-59
private int seconde; // 0-59
public Tijd() // constructor
{
SetTime(0,0,0);
}
// bewaart de tijd in 24-uur formaat, ongeldige waarden worden nullen
public void SetTime(int uurwaarde, int minuutwaarde, int secondewaarde)
{
uur = (uurwaarde >=0 && uurwaarde < 24) ? uurwaarde : 0;
minuut = (minuutwaarde >=0 && minuutwaarde < 60) ? minuutwaarde : 0;
seconde = (secondewaarde >=0 && secondewaarde < 60) ? secondewaarde : 0;
}
public string ToUniversalString() //24 uur weergave
{
return String.Format("{0:D2}:{1:D2}:{2:D2}",uur,minuut,seconde);
}
public string ToStandardString() //12 uur weergave
{
return String.Format("{0}:{1:D2}:{2:D2} {3}",
((uur==12 || uur == 0) ? 12 : uur % 12),
minuut,seconde,(uur<12?"AM":"PM"));
}
}
}
using System;
using System.Windows.Forms;
namespace Tijd
{
class TijdTest1
{
static void Main(string[] args)
{
Tijd tijd = new Tijd(); // roept de constructor van de klasse Tijd aan
string uit;
//huidige tijd als string in de variabele uit plaatsen
uit = "Initėle universele tijd is: " +
tijd.ToUniversalString() +
"\nInitiėle Standaard tijd is: " +
tijd.ToStandardString();
//tijd instellen op een geldige waarde
tijd.SetTime(13,27,44);
//ingestelde tijd toevoegen aan de variabele uit
uit += "\n\nUniversele tijd na SetTime is: " +
tijd.ToUniversalString() +
"\nStandaard tijd na SetTime is: " +
tijd.ToStandardString();
//ongeldige waarden instellen voor de tijd
tijd.SetTime(99,99,99);
//ingestelde tijd toevoegen aan de variabele uit
uit += "\n\nUniversele tijd met ongeldige waarde: " +
tijd.ToUniversalString() +
"\nStandaard tijd met ongeldige waarde: " +
tijd.ToStandardString();
MessageBox.Show(uit,"Klasse Tijd testen");
}
}
}
We declareren een object tijd afgeleid van de klasse Tijd en vullen een variabele uit met een tekstbericht naarmate we de variabele tijd aanpassen.
Uiteindelijk brengen we de inhoud van de variabele uit op het scherm met een MessageBox.
Om de tijd in te stellen moeten we gebruik maken van de methode SetTime. De variabele uur, minuut en seconde uit de klasse Tijd zijn niet rechtstreeks te benaderen vanuit de klasse TijdTest doordat ze privaat gedeclareerd zijn.
Pas de klasse Tijd aan:
Toon volledige code...
Toon nieuwe code...
public Tijd() // constructor1
{
SetTime(0,0,0);
}
public Tijd(int uur) // constructor2
{
SetTime(uur,0,0);
}
public Tijd(int uur, int minuut) // constructor3
{
SetTime(uur,minuut,0);
}
public Tijd(int uur, int minuut, int seconde) // constructor4
{
SetTime(uur, minuut, seconde);
}
public Tijd(Tijd tijd) // constructor5
{
SetTime(tijd.uur, tijd.minuut, tijd.seconde);
}
We passen ook de klasse TijdTest aan:
using System;
using System.Windows.Forms;
namespace Tijd
{
class TijdTest1
{
static void Main(string[] args)
{
Tijd tijd1 = new Tijd();
Tijd tijd2 = new Tijd(10);
Tijd tijd3 = new Tijd(15,30);
Tijd tijd4 = new Tijd(7,55,40);
Tijd tijd5 = new Tijd(tijd2);
string uit;
uit = "tijd1: " +
tijd1.ToUniversalString() +
" - " +
tijd1.ToStandardString();
uit += "\n\ntijd2: " +
tijd2.ToUniversalString() +
" - " +
tijd2.ToStandardString();
uit += "\n\ntijd3: " +
tijd3.ToUniversalString() +
" - " +
tijd3.ToStandardString();
uit += "\n\ntijd4: " +
tijd4.ToUniversalString() +
" - " +
tijd4.ToStandardString();
uit += "\n\ntijd5: " +
tijd5.ToUniversalString() +
" - " +
tijd5.ToStandardString();
MessageBox.Show(uit,"Klasse Tijd testen");
}
}
}
We passen de klasse Tijd aan voor het gebruik van eigenschappen Uur, Minuut en Seconde.
Deze keer kunnen we de controle voor geldige waarde uitvoeren op eigenschapniveau en hoeven we dit niet in de methode SetTime te doen.
Toon volledige code...
Toon nieuwe code...
public Tijd(Tijd tijd) // constructor5
{
SetTime(tijd.Uur, tijd.Minuut, tijd.Seconde);
}
//stel de tijd in, controle via de eigenschappen
public void SetTime(int uurwaarde, int minuutwaarde, int secondewaarde)
{
Uur = uurwaarde;
Minuut = minuutwaarde;
Seconde = secondewaarde;
}
//eigenschap Uur
public int Uur
{
get
{
return uur;
}
set
{
uur = ((value >= 0 && value < 24) ? value : 0);
}
}
//eigenschap Minuut
public int Minuut
{
get
{
return minuut;
}
set
{
minuut = ((value >= 0 && value < 60) ? value : 0);
}
}
//eigenschap Seconde
public int Seconde
{
get
{
return seconde;
}
set
{
seconde = ((value >= 0 && value < 60) ? value : 0);
}
}
public string ToUniversalString() //24 uur weergave
{
return String.Format("{0:D2}:{1:D2}:{2:D2}",Uur,Minuut,Seconde);
}
public string ToStandardString() //12 uur weergave
{
return String.Format("{0}:{1:D2}:{2:D2} {3}",
((Uur==12 || Uur == 0) ? 12 : Uur % 12),Minuut,Seconde,(Uur<12?"AM":"PM"));
}
}
}
In dit project maak je een eerste klasse Datum: Project > add class...
using System;
using System.Collections.Generic;
using System.Text;
namespace Werknemers
{
public class Datum
{
private int dag;
private int maand;
private int jaar;
public Datum(int dag, int maand, int jaar)
{
if(maand > 0 && maand < 12)
this.maand = maand;
else
{
this.maand = 1;
Console.WriteLine(
"Maand is ongeldig, ingesteld op 1");
}
this.jaar = jaar; //geen controle op jaar
this.dag = ControleerDag(dag); //controle op de dag
}
private int ControleerDag(int testDag)
{
int[] dagenPerMaand =
{ 0,31,28,31,30,31,30,31,31,30,31,30,31};
//controleer of de dag binnen het bereik van de maand valt
if(testDag > 0 && testDag <= dagenPerMaand[maand])
return testDag;
//controle schrikkeljaar
if(maand == 2 && testDag == 29 &&
(jaar % 400 == 0 ||
(jaar % 4 == 0 && jaar % 100 != 0) ) )
return testDag;
Console.WriteLine(
"Dag ongeldig, ingesteld op 1");
return 1;
}
public string maakDatumString()
{
return dag + "/" +maand +"/" +jaar;
}
}
}
Maak een klasse Werknemer: Project > add class...
using System;
using System.Collections.Generic;
using System.Text;
namespace Werknemers
{
public class Werknemer
{
private string voornaam;
private string familienaam;
private Datum geboorteDatum;
private Datum inDienstDatum;
public Werknemer(string voor, string achter,
int gdag, int gmaand, int gjaar,
int idag, int imaand, int ijaar)
{
voornaam = voor;
familienaam = achter;
geboorteDatum = new Datum(gdag,gmaand,gjaar);
inDienstDatum = new Datum(idag,imaand,ijaar);
}
public string maakWerknemerString()
{
return familienaam +"," +voornaam +
" In Dienst: " +inDienstDatum.maakDatumString() +
" Geboortedatum: " +geboorteDatum.maakDatumString();
}
}
}
We zien dat de instantievariabelen geboorteDatum en inDienstDatum referenties zijn naar objecten van een andere klasse: de klasse Datum. Dit principe heet compositie.
Maak nog een klasse TestWerknemer: Project > add class...
Leg een referentie naar System.Windows.Forms
Zet via Project > Werknemers Properties het Output type op Windows Application
using System;
using System.Windows.Forms;
namespace Werknemers
{
public class TestWerknemer
{
static void Main(string[] args)
{
Werknemer w = new Werknemer("Pietje","Pek",7,4,1970,1,1,2000);
MessageBox.Show(w.maakWerknemerString(),"Test klasse Werknemer");
}
}
}
Het gevaar schuilt erin dat je als programmeur de andere systeembronnen zoals netwerkconnecties, databases en bestanden handmatig moet vrijgeven.
Een techniek om dat te doen is te werken met een destructor: een routine die je schrijft die wordt uitgevoerd wanneer de Garbage Collector het object vernietigd.
Een klasse kan slechts één destructor bevatten. De naam van de destructor is de klassenaam met als prefix een tilde (˜).
Doe volgende aanpassing aan de klasse Werknemer:
Toon volledige code...
Toon nieuwe code...
~Werknemer()
{
MessageBox.Show("Werknemer vernietigd: " +
voornaam + ", " + familienaam, "Destructor");
}
Pas nu ook de klasse TestWerknemer aan:
using System;
using System.Windows.Forms;
namespace Werknemers
{
public class TestWerknemer
{
static void Main(string[] args)
{
Werknemer w = new Werknemer("Pietje","Pek",7,4,1800,1,1,2000);
MessageBox.Show(w.maakWerknemerString(),"Test klasse Werknemer");
w = null;
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
Werknemer a = new Werknemer("Guy","Taar",2,5,1950,3,5,1990);
MessageBox.Show(a.maakWerknemerString(),"Test klasse Werknemer");
}
}
}
Normaal weet je in een programma niet wanneer de Garbage Collector in actie zal schieten. Je kan dit proces echter forceren met de methode Collect van de Garbage Collector (GC).
De methode WaitForPendingFinalizers zorgt ervoor dat ook alle ongebruikte objecten vernietigd worden die in een parallelle thread met de Garbage Collector draaien.
Aanpassingen aan Werknemer:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Werknemers
{
public class Werknemer
{
private string voornaam;
private string familienaam;
private Datum geboorteDatum;
private Datum inDienstDatum;
private static int aantal;
public Werknemer(string voor, string achter,
int gdag, int gmaand, int gjaar,
int idag, int imaand, int ijaar)
{
voornaam = voor;
familienaam = achter;
geboorteDatum = new Datum(gdag, gmaand, gjaar);
inDienstDatum = new Datum(idag, imaand, ijaar);
++aantal;
MessageBox.Show("Werknemer constructor: " +
this.maakWerknemerString());
MessageBox.Show("Aantal = " + Aantal);
}
public string maakWerknemerString()
{
return familienaam + "," + voornaam +
" In Dienst: " + inDienstDatum.maakDatumString() +
" Geboortedatum: " + geboorteDatum.maakDatumString();
}
~Werknemer()
{
--aantal;
MessageBox.Show("Werknemer destructor: " +
this.maakWerknemerString());
MessageBox.Show("Aantal = " + Aantal);
}
public static int Aantal
{
get
{
return aantal;
}
}
}
}
Aanpassingen aan TestWerknemer:
using System;
using System.Windows.Forms;
namespace Werknemers
{
public class TestWerknemer
{
static void Main(string[] args)
{
Console.WriteLine("Aantal werknemers: " +Werknemer.Aantal);
Werknemer w = new Werknemer("Pietje","Pek",7,4,1800,1,1,2000);
Werknemer a = new Werknemer("Guy","Taar",2,5,1950,3,5,1990);
a = null;
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
w = null;
}
}
}
We maken een herbruikbare assembly van de klasse Tijd uit de vorige toepassing.
using System;
namespace TijdBib
{
public class Tijd
{
private int uur; // 0-23
private int minuut; // 0-59
private int seconde; // 0-59
public Tijd() // constructor1
{
SetTime(0,0,0);
}
public Tijd(int uur) // constructor2
{
SetTime(uur,0,0);
}
public Tijd(int uur, int minuut) // constructor3
{
SetTime(uur,minuut,0);
}
public Tijd(int uur, int minuut, int seconde) // constructor4
{
SetTime(uur, minuut, seconde);
}
public Tijd(Tijd tijd) // constructor5
{
SetTime(tijd.Uur, tijd.Minuut, tijd.Seconde);
}
//stel de tijd in, controle via de eigenschappen
public void SetTime(int uurwaarde, int minuutwaarde, int secondewaarde)
{
Uur = uurwaarde;
Minuut = minuutwaarde;
Seconde = secondewaarde;
}
//eigenschap Uur
public int Uur
{
get
{
return uur;
}
set
{
uur = ((value >= 0 && value < 24) ? value : 0);
}
}
//eigenschap Minuut
public int Minuut
{
get
{
return minuut;
}
set
{
minuut = ((value >= 0 && value < 60) ? value : 0);
}
}
//eigenschap Seconde
public int Seconde
{
get
{
return seconde;
}
set
{
seconde = ((value >= 0 && value < 60) ? value : 0);
}
}
public string ToUniversalString() //24 uur weergave
{
return String.Format("{0:D2}:{1:D2}:{2:D2}",Uur,Minuut,Seconde);
}
public string ToStandardString() //12 uur weergave
{
return String.Format("{0}:{1:D2}:{2:D2} {3}",
((Uur==12 || Uur == 0) ? 12 : Uur % 12),Minuut,Seconde,(Uur<12?"AM":"PM"));
}
}
}
using System;
using TijdBib;
namespace TijdBibTest
{
class TijdBibTest
{
static void Main(string[] args)
{
Tijd tijd = new Tijd(13,12,6);
Console.WriteLine("Standaard tijd: {0}\nUniversele tijd: {1}" ,
tijd.ToStandardString(), tijd.ToUniversalString());
}
}
}
Voer uit met CTRL-F5 (Build without debuging) dan heb je tijd om naar de console te kijken.
| Meer tutorials: |
| leer ook: | html | | xhtml | | css | | asp | | asp.net | | c# | | ado.net | | linq | | ajax | | java | | javascript |