Voortborduren op eerder gedaan werk Derde poging: “subklassen” class Twee { int x, y; int oud ( ) { return x+y; } class Twee : Twee { Drie int z; } int nieuw ( ) { return x+y+z; } }
Voortborduren op eerder gedaan werk Eerste poging: “knip&plak” class Twee { int x, y; int oud ( ) { return x+y; } class Twee { int x, y; int oud ( ) { return x+y; } Drie int z; +1; } int nieuw ( ) { return x+y+z; } versie-management problematiek }
Klasse-hiërarchie in Forms Common Dialog Component FileDialog ColorDialog Control Label TrackBar ButtonBase Button CheckBox RadioButton TextBoxBase TextBox RichTextBox Scrollable Control Container Control Form UserControl Panel ListView TreeView
Klasse-hiërarchie in Forms Object String Bitmap Graphics moeder van alle klassen EventArgs PaintEventArgs MouseEventArgs KeyPressEventArgs Component CommonDialog Control Label TrackBar ButtonBase
ondergrond gaat voor motorisatie Hiërarchie-ontwerp Vervoer middel Voertuig Boot Motor Voertuig Fiets Boot Zeil Vracht Wagen Stoom Boot Auto Motor Fiets ontwerpkeuze: motorfiets is meer motor dan fiets Vliegtuig ontwerpkeuze: ondergrond gaat voor motorisatie
Hiërarchie-ontwerp “is een” Voertuig Vervoer middel Boot class Voertuig : Vervoermiddel class Boot : Vervoermiddel “is een”
class Snelweg : Form { class MVoertuig { MVoertuig [ ] rijbaan void Teken(Graphics g) { } = new MVoertuig [15]; Snelweg( ) { Paint += teken; } } class Auto : MVoertuig { void Teken(Graphics g) { g.Fill ( ); } void teken(O o, PEA pea) { for (...t...) rijbaan[t].Teken( pea.Graphics, t*120, 60) } } }
class Snelweg { MVoertuig [ ] rijbaan = new MVoertuig [15]; Snelweg( ) { Paint += teken; for (int t=0; t<rijbaan.Length; t++) if ( t%3 != 0 ) rijbaan[t] = new Auto(); else if ( t%6 == 0 ) rijbaan[t] = new VrachtW(); else rijbaan[t] = new Combinat(); } }
class Snelweg { class MVoertuig { virtual MVoertuig [ ] rijbaan void Teken(Graphics g) { } = new MVoertuig [15]; Snelweg( ) { Paint += teken; } } class Auto : MVoertuig { override rijbaan[2] = new Auto(); void Teken(Graphics g) { g.Fill ( ); } void teken(O o, PEA pea) { for (...t...) rijbaan[t].Teken( pea.Graphics, t*120, 60) } } class VrachtW : MVoertuig { override void Teken(Graphics g) { g.Fill ( ); } } }
versie-management problematiek class VrachtW : MVoertuig { class Combinat : VrachtW { void Teken(Graphics g) { void Teken(Graphics g) { g.FillRect(...); g.FillEllipse(...); base. Teken(g); g.FillRect(...); g.FillEllipse(...); versie-management problematiek g.DrawLine(...); g.FillRect(...); g.FillEllipse(...); } } } }
class VrachtW : MVoertuig { class Combinat : VrachtW { Aanhanger aanhang; void Teken(Graphics g) { void Teken(Graphics g) { g.FillRect(...); g.FillEllipse(...); base. Teken(g); g.FillRect(...); g.FillEllipse(...); aanhang. Teken(g); g.DrawLine(...); g.FillRect(...); g.FillEllipse(...); } } } }
class Combinat : VrachtW { Aanhanger aanhang; class Aanhanger { class Combinat : VrachtW { Aanhanger aanhang; void Teken(Graphics g) { void Teken(Graphics g) { base. Teken(g); g.FillRect(...); g.FillEllipse(...); g. DrawLine(...); g.FillRect(...); g.FillEllipse(...); aanhang. Teken(g); g.DrawLine(...); g.FillRect(...); g.FillEllipse(...); } } } }
“is een” “heeft een” class Wiel class DingOpWielen Aanhanger MotorVoertuig PersonenAuto Vrachtwagen Combinatie class Wiel “is een” class DingOpWielen { Wiel [ ] wielen; } class Aanhanger : DingOpWielen class Motorvoertuig : DingOpWielen class PersonenAuto : MotorVoertuig class VrachtWagen : MotorVoertuig class Combinatie : Vrachtwagen “heeft een” { Aanhanger aanh; }
deze methode komt uit klasse: Virtual - Override A a = new B (); a . m( ); dit mag, als class B : A deze methode komt uit klasse: B als m virtual in A en override in B A anders
Gelijkheid van Strings static bool Gelijk( string s, string t) { int m = s.Length; int n = t.Length; for (i=0; i<m && i<n; i++) { char c = s[i]; char d= t[i]; if (c!=d) return false; } return m==n; }
Gelijkheid van Strings class String { static bool Equals( string s, string t) { int m = s.Length; this.Length; int n = t.Length; for (i=0; i<m && i<n; i++) { char c = s[i]; this[i]; char d= t[i]; if (c!=d) return false; } return m==n; } }
Werkcollege: Ordenen van Strings class String { bool Equals( string t ) { // true als alle letters hetzelfde zijn } int Compare( string t ) { // 0 als this en t hetzelfde zijn // positief als this alfabetisch voor t komt // negatief als this alfabetisch na t komt } }
Gelijkheid van Strings class String { bool Equals ( string t) { int m = this.Length; int n = t.Length; for (i=0; i<m && i<n; i++) { char c = this[i]; char d= t[i]; if (c!=d) return false; } return m==n; } }
Ordenen van Strings class String { int bool Equals ( string t) Compare int m = this.Length; int n = t.Length; for (i=0; i<m && i<n; i++) { char c = this[i]; char d= t[i]; if (c!=d) return false; c - d ; } return m==n; m - n ; } }
Hoofdstuk 10.2 Rekenmachine-casus
Voorbeeld: Rekenmachine
Voorbeeld: Rekenmachine Twee aspecten: User-interface Werking class Calculator : Form class Processor
Rekenmachine: User-interface Label TableLayoutPanel Button Calculator ( ) { paneel = new TableLayoutPanel( ); for (int t=0; t<16; t++) { } Button knop = new Button(); paneel.Controls.Add( knop ); Buttons zijn ondergeschikt aan het paneel this.Controls.Add( paneel ); }
ondergeschikt aan het paneel User-interface Calculator ( ) { paneel = new TableLayoutPanel( ); paneel.Columncount = 4; for (int t=0; t<4; t++) paneel.ColumnStyles.Add( ...25%... ); for (int t=0; t<16; t++) { Button knop = new Button(); knop.Text = "789/456*123+0C=-"[t].ToString(); knop.Dock = DockStyle.Fill; knop.Click += this.klik; knop.KeyPress += this.toets; knop.Resize += this.groei; paneel.Controls.Add( knop ); Buttons zijn ondergeschikt aan het paneel } this.Controls.Add( paneel ); }
Opbouw klasse Calculator class Calculator : Form { Label result; TableLayoutPanel paneel; Processor proc; membervariabelen ook nodig in EventHandlers Calculator ( ) { result = new Label( ); result.TextAlign = ContentAlignment.MiddleRight; // en de rest van de Userinterface-opbouw proc = new Processor ( ); }
Calculator Event-handlers class Calculator : Form { Label result; Processor proc; void klik (object obj, EA ea) { } verwerk( ((Button) obj) . Text[0] ); void toets(object obj, KPEA kpea ) { } verwerk( kpea.KeyChar ); void groei(object obj, EA ea ) { } Control c = (Control) obj; int h = c.Height / 2; if (c==result) h = c.Height/3; c.Font = new Font("Tahoma", h);
Calculator Event-handlers class Calculator : Form { Label result; Processor proc; void verwerk (char c) { if (c=='C') proc.Schoon(); else if (c=='=') proc.Reken(); else if (c>='0'&&c<='9') proc.Cijfer(c–'0'); else proc.Operatie(c); result . Text = ; proc . Scherm }
Opbouw klasse Proc class Processor { long Scherm; wat is een Processor? Processor ( ) { this . Schoon(); } void Schoon ( ) { ... } void Reken ( ) { ... } void Cijfer (int n) { ... } void Operatie (char c) { ... } wat kan een Processor?
Wat is een Processor? waarde op het scherm huidige waarde 9 3348 372 37 vorige waarde laatst gebruikte operator er lijkt niets te gebeuren... schermwaarde wordt tienmaal zo groot plus cijfer
Opbouw klasse Processor class Processor { long Scherm; wat is een Processor? long waarde, vorige; char op; Processor ( ) { this . Schoon(); } void Schoon ( ) { ... } void Reken ( ) { ... } void Cijfer (int n) { ... } void Operatie (char c) { ... } wat kan een Processor?
Processor methode cijfer class Processor { long scherm, waarde, vorige; char op; void Cijfer (int n) { } waarde = 10*waarde + n; scherm = waarde;
Processor methode reken class Processor { long scherm, waarde, vorige; char op; void Reken ( ) { } if (op=='+') if (op=='–') if (op=='*') if (op=='/') vorige += waarde; vorige –= waarde; vorige *= waarde; vorige /= waarde; scherm = vorige; waarde = 0;
Proc’s methode operatie class Processor { long scherm, waarde, vorige; char op; void Operatie (char c) { } this . reken ( ); op = c; void Schoon ( ) { waarde = 0; vorige = 0; scherm = 0; op = } '+';
Testen van een reeks mogelijke waarden switch (x) { } case 1: case 2: case 3: case 4: case 5: case 6: case 7: default: if (x==1) else if (x==2) else if (x==3) else if (x==4) else if (x==5) else if (x==6) else if (x==7) else this.een(); this.twee(); this.drie(); this.vier(); this.vijf(); this.zes(); this.zeven(); this.meer(); break;
Tekst-editor: MDI-interface Dialogen Files lezen Abstracte klassen Hoofdstuk 10.3 Tekst-editor: MDI-interface Dialogen Files lezen Abstracte klassen
Voorbeeld: Tekst-Editor Open/Save: standaard- dialoog Zoek/Vervang: eigen dialoog files lezen en schrijven Multiple Document Interface
Multiple Document Interface MDI- container MDI- children MDI- child
MDI-container en -children class Hoofdscherm : Form class Tekst : Form { { TextBox invoer; Label status; Hoofdscherm ( ) { this.IsMdiContainer = true; Tekst ( ) menu = new ToolStripMenuItem("File"); { invoer = new TextBox(); status = new Label(); menu.DropDownItems.Add ("Nieuw", null, this.nieuw ); invoer.TextChanged += anders; } } void nieuw (object o, EA ea ) void anders (object o, EA ea ) { { Tekst t = new Tekst(); status.Text = t.MdiParent = this; invoer.Text.Length.ToString(); t.Show ( ); } } } }
Multiple Document Interface menu-regel bevat items van de parent èn children
MDI-container en -children class Hoofdscherm : Form class Tekst : Form { { Hoofdscherm ( ) Tekst ( ) { this.IsMdiContainer = true; { MenuStrip strip = new MenuStrip ( ); MenuStrip strip = new MenuStrip ( ); menu = new ToolStripMenuItem("File"); menu = new ToolStripMenuItem("File"); menu.DropDownItems.Add ("Nieuw", null, this.nieuw ); menu.DropDownItems.Add ("Open", null, this.openen ); strip.Items.Add(menu); strip.Items.Add(menu); this.MainMenuStrip = strip; strip.Visible = false; } } } }
Dialogen voeren
Dialogen voeren
Dialogen voeren class Hoofdscherm : Form class Tekst : Form { { TextBox invoer; void openen (obj o, EA ea ) void zoeken (obj o, EA ea ) { OpenFileDialog d = new OpenFileDialog(); { ZoekDialoog d = new ZoekDialoog(); d.Filter = "Teksten|*.txt"; if ( d.ShowDialog() if ( d.ShowDialog() ==DialogResult.OK ) ==DialogResult.OK ) { Tekst t = new Tekst(); { string alles = invoer.Text; t.MdiParent = this; string zk = d.Zoek.Text; t.lees( d.FileName ); int pos = alles.IndexOf(zk); t.Show(); invoer.Select(pos, zk.Length); } } } } } }
ZoekDialoog class ZoekDialoog : Form { public TextBox Zoek; private Button ok, cc; ZoekDialoog ( ) { Zoek = new TextBox(); Zoek.Location=...; ...Add(Zoek); ok = new Button(); ok.Text="OK"; ok.Location=...; ...Add(ok); cc = new Button(); cc.Text="Cancel"; cc.Location=...; ...Add(cc); ok.Click += this.positief; sluit automatisch this.CancelButton = cc; reageert ook op ESC this.AcceptButton = ok; } reageert ook op Enter void positief (obj o, EA ea ) { this.DialogResult = DialogResult.OK; this.Close ( ); } }
Openen en Opslaan class Hoofdscherm : Form class Tekst : Form { { TextBox invoer; void openen (obj o, EA ea ) void opslaanAls (obj o, EA ea ) { OpenFileDialog d = new OpenFileDialog(); { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Teksten|*.txt"; d.Filter = "Teksten|*.txt"; if ( d.ShowDialog() if ( d.ShowDialog() ==DialogResult.OK ) ==DialogResult.OK ) { { } } } } } }
Openen en Opslaan class Hoofdscherm : Form class Tekst : Form { { TextBox invoer; void openen (obj o, EA ea ) void opslaanAls (obj o, EA ea ) { OpenFileDialog d = new OpenFileDialog(); { SaveFileDialog d = new SaveFileDialog(); d.Filter = "Teksten|*.txt"; d.Filter = "Teksten|*.txt"; if ( d.ShowDialog() if ( d.ShowDialog() ==DialogResult.OK ) ==DialogResult.OK ) { Tekst t = new Tekst(); { this.schrijf( d.FileName ); t.MdiParent = this; } t.lees( d.FileName ); } void lees (string naam) { ...... } void schrijf (string naam) t.Show(); } } } }
Openen en Opslaan class Tekst : Form { TextBox invoer; void lees (string naam) { StreamReader sr = new StreamReader (naam); this.invoer.Text = sr . ReadToEnd ( ) ; sr . Close ( ) ; this.Text = naam; } void schrijf (string naam) { StreamWriter sw = new StreamWriter (naam); sw . Write ( this.invoer.Text ) ; sw . Close ( ) ; this.Text = naam; } }
Klassen om files te lezen en te schrijven Object Stream TextReader TextWriter FileStream StreamReader StreamWriter store MemoryStream StringReader StringWriter NetworkStream BinaryReader BinaryWriter XmlReader XmlWriter BufferedStream decorator GZipStream CryptoStream
Klassen om files te lezen en te schrijven leest en schrijft bytes leest string en char schrijft string en char Stream FileStream StreamReader StreamWriter MemoryStream leest/schrijft een file NetworkStream leest/schrijft het geheugen leest/schrijft het netwerk
levert getal tussen 0...255 of –1 als er niets meer is Methoden van Stream class FileStream { int Read (byte[] doel, int max) { for (int t=0; t<max; t++) { int b = this.ReadByte(); Stream if (b==–1) return t; FileStream doel[t] = (byte) b ; } MemoryStream return max; } NetworkStream } FileMode.Append FileStream fs; FileMode.Create fs = new FileStream ("test", FileMode.Open ); levert getal tussen 0...255 of –1 als er niets meer is int b = fs.ReadByte( ) ; byte [ ] ruimte = new byte[100]; int n = fs.Read ( ruimte, 100 ) ;
Methoden van Stream class FileStream Stream { int Read (byte[] doel, int max) { for (int t=0; t<max; t++) { int b = this.ReadByte(); Stream if (b==–1) return t; FileStream doel[t] = (byte) b ; } MemoryStream return max; } NetworkStream virtual int ReadByte ( ) { /* leeg */ } } class FileStream : Stream { override int ReadByte ( ) { return ............... } }
Methoden van Stream abstract class FileStream Stream { int Read (byte[] doel, int max) { for (int t=0; t<max; t++) { int b = this.ReadByte(); Stream if (b==–1) return t; FileStream doel[t] = (byte) b ; } MemoryStream return max; } NetworkStream abstract virtual int ReadByte ( ) ; { /* leeg */ } } class FileStream : Stream { override int ReadByte ( ) { return ............... } }
Abstracte methode/klasse Abstracte methode: methode zonder body Abstracte klasse: bevat abstracte methode kun je geen new object van maken alleen bedoeld als superklasse Stream FileStream MemoryStream NetworkStream Brush SolidBrush HatchBrush
Abstracte methode/klasse Abstracte methode: methode zonder body Abstracte klasse: bevat abstracte methode kun je geen new object van maken alleen bedoeld als superklasse Stream FileStream MemoryStream NetworkStream MotorVoertuig PersonenAuto VrachtWagen
Methoden van Stream abstract class FileStream Stream { int Read (byte[] doel, int max) { for (int t=0; t<max; t++) { int b = this.ReadByte(); Stream if (b==–1) return t; FileStream doel[t] = (byte) b ; } MemoryStream return max; } NetworkStream abstract virtual int ReadByte ( ) ; } class FileStream : Stream { override int ReadByte ( ) { return ............... } }
Decorator Streams Stream str; str = new FileStream ( "test", FileMode.Create ); Stream GZipStream klein; FileStream klein = new GZipStream ( str ) ; store MemoryStream klein.Write( mijnByteArray ); NetworkStream geef het onderliggende store-medium "in beheer" je kunt decorators combineren BufferedStream decorator GZipStream CryptoStream geheim; CryptoStream geheim = new CryptoStream ( klein ) ;
Reader en Writer leest en schrijft bytes leest string en char schrijft string en char Object Stream TextReader TextWriter FileStream StreamReader StreamWriter store MemoryStream StringReader StringWriter NetworkStream vanuit een Stream vanuit een String BufferedStream decorator GZipStream CryptoStream
Reader en Writer leest en schrijft bytes leest string en char schrijft string en char Object Stream TextReader TextWriter FileStream StreamReader StreamWriter store MemoryStream StringReader StringWriter NetworkStream Stream str; str = new FileStream ( "test.txt", FileMode.Open ); BufferedStream TextReader lezer; decorator GZipStream lezer = new StreamReader ( str ); CryptoStream string s; s = lezer . ReadToEnd ( );
Reader en Writer leest en schrijft bytes leest string en char schrijft string en char Object Stream TextReader TextWriter FileStream StreamReader StreamWriter store MemoryStream StringReader StringWriter NetworkStream Stream str; str = new FileStream ( "test.txt", FileMode.Open ); BufferedStream TextReader lezer; decorator GZipStream lezer = new StreamReader ( str ); lezer = new StreamReader ( "test.txt" ); CryptoStream convenience-methode string s; s = lezer . ReadToEnd ( );
Reader en Writer leest en schrijft bytes leest string en char schrijft string en char Object Stream TextReader TextWriter FileStream StreamReader StreamWriter store MemoryStream StringReader StringWriter NetworkStream BinaryReader BinaryWriter XmlReader XmlWriter BufferedStream leest XML-teksten leest int en double decorator GZipStream CryptoStream
Encoding: char naar byte header A a ä α ASCII 1 byte per char, <128 41 61 3F 3F Unicode 2 bytes per char FE FF 41 00 61 00 E4 00 B1 03 BigEndianUnicode 2 bytes, grote eerst FF FE 00 41 00 61 00 E4 03 B1 Latin-1 (iso-8859-1) 1 byte per char, <256 41 61 E4 3F UTF8 1/2/3 bytes per char EF BB BF 41 61 C3 A4 CE B1
Encoding