Modelleren en Programmeren Jeroen Bransen 11 december 2013 Terugblik Call-by-value I Een parameter is een losse variabele, die alleen bestaat binnen die methode Call-by-value I Een parameter is een losse variabele, die alleen bestaat binnen die methode I Bij aanroep wordt de waarde (value) in die variabele opgeslagen Call-by-value I Een parameter is een losse variabele, die alleen bestaat binnen die methode I Bij aanroep wordt de waarde (value) in die variabele opgeslagen I Wijzigen van de parameter heeft dus geen effect buiten de functie Call-by-value I Een parameter is een losse variabele, die alleen bestaat binnen die methode I Bij aanroep wordt de waarde (value) in die variabele opgeslagen I Wijzigen van de parameter heeft dus geen effect buiten de functie I Dit noemen we call-by-value en wordt in Java voor simpele typen gebruikt Call-by-reference I Een array of object wordt in een variabele opgeslagen als verwijzing Call-by-reference I Een array of object wordt in een variabele opgeslagen als verwijzing I Bij aanroep wordt de verwijzingen (reference) opgeslagen in de parameter Call-by-reference I Een array of object wordt in een variabele opgeslagen als verwijzing I Bij aanroep wordt de verwijzingen (reference) opgeslagen in de parameter I Wijzigen van object/array waar parameter naar verwijst heeft dus wel effect buiten de functie Call-by-reference I Een array of object wordt in een variabele opgeslagen als verwijzing I Bij aanroep wordt de verwijzingen (reference) opgeslagen in de parameter I Wijzigen van object/array waar parameter naar verwijst heeft dus wel effect buiten de functie I Dit noemen we call-by-reference en wordt in Java voor objecten en arrays gebruikt Call-by-reference I Een array of object wordt in een variabele opgeslagen als verwijzing I Bij aanroep wordt de verwijzingen (reference) opgeslagen in de parameter I Wijzigen van object/array waar parameter naar verwijst heeft dus wel effect buiten de functie I Dit noemen we call-by-reference en wordt in Java voor objecten en arrays gebruikt I Maar: de verwijzing zelf aanpassen heeft dan weer geen effect Variabelen in geheugen I Primitieve waarden: Variabelen in geheugen I Primitieve waarden: I Arrays: Variabelen in geheugen I Primitieve waarden: I Arrays: I Objecten: Call-by overzicht public class CallBy { public static void main(String[] args) { int i = 2; int[] j = { 2 }; int[] k = { 2 }; Persoon p = new Persoon("Sinterklaas", 417, 181); add1(i, j, k, p); System.out.println(i); // Print 2 System.out.println(j[0]); // Print 3 System.out.println(k[0]); // Print 2 System.out.println(p.leeftijd); // Print 418 } static void add1(int a, int[] b, int[] c, Persoon d) { a++; // heeft geen effect b[0]++; // heeft wel effect c = new int[1]; c[0] = 3; // heeft geen effect d.leeftijd++; // heeft wel effect } } Plaatje van whiteboard Foto: Rianne van Dijk Gelijkheid van objecten I Strings zijn ook objecten Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben I Maar bij objecten is de waarde de verwijzing Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben I Maar bij objecten is de waarde de verwijzing I Dus == controleert of de variabelen naar hetzelfde object verwijzen Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben I Maar bij objecten is de waarde de verwijzing I Dus == controleert of de variabelen naar hetzelfde object verwijzen I x en y zijn niet hetzelfde object! Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben I Maar bij objecten is de waarde de verwijzing I Dus == controleert of de variabelen naar hetzelfde object verwijzen I x en y zijn niet hetzelfde object! I Ze representeren alleen dezelfde string Gelijkheid van objecten I Strings zijn ook objecten I Met == controleren we of variabelen dezelfde waarde hebben I Maar bij objecten is de waarde de verwijzing I Dus == controleert of de variabelen naar hetzelfde object verwijzen I x en y zijn niet hetzelfde object! I Ze representeren alleen dezelfde string I Met equals kunnen we controleren of strings hetzelfde zijn Break en continue I Keyword break breekt een for of while meteen af Break en continue I Keyword break breekt een for of while meteen af I Keyword continue gaat naar de volgende iteratie van een for of while Recursie Recursie I “Om recursie te begrijpen, moet je eerst recursie begrijpen” Recursie I “Om recursie te begrijpen, moet je eerst recursie begrijpen” I Recursieve functie roept zichzelf aan Recursie I “Om recursie te begrijpen, moet je eerst recursie begrijpen” I Recursieve functie roept zichzelf aan I Minstens 1 parameter moet “kleiner” worden Recursie I “Om recursie te begrijpen, moet je eerst recursie begrijpen” I Recursieve functie roept zichzelf aan I Minstens 1 parameter moet “kleiner” worden I Herhalingsconstructies (for, while) kunnen ook recursief worden beschreven Factorial voorbeeld // A simple example of recursion. public class Factorial { // This is a recursive function. public static int factR(int n) { int result; if(n==1) return 1; result = factR(n-1) * n; return result; } // This is an iterative equivalent. public static int factI(int n) { int t, result; result = 1; for(t=1; t <= n; t++) result *= t; return result; } } Mutuele recursie I Twee (of meerdere) functies die elkaar aanroepen Mutuele recursie I Twee (of meerdere) functies die elkaar aanroepen I Functies roepen indirect zichzelf aan Mutuele recursie I Twee (of meerdere) functies die elkaar aanroepen I Functies roepen indirect zichzelf aan I Ook hier moet er een parameter kleiner worden om oneindige recursie tegen te gaan Fibonacci public class Fibonacci { public static void main(String[] args) { // Print het vijfde Fibonaccigetal System.out.println(fib(5)); } public static int fib(int n) { // Basisgeval if(n <= 1) return 1; // Reken getal uit op basis van andere waarden return fib(n-1) + fib(n-2); } } Fibonacci call tree fib(5) + fib(4) + fib(3) + fib(2) + fib(1) 1 fib(0) 1 fib(3) + fib(2) + fib(1) 1 fib(1) 1 fib(0) 1 fib(2) + fib(1) 1 fib(0) 1 fib(1) 1 Oefenopgave Schrijf een functie macht die geven een int a en een int b met behulp van recursie de waarde van ab (a tot-de-macht b) berekent. Je mag aannemen dat b ≥ 0. Oefenopgave Schrijf een functie macht die geven een int a en een int b met behulp van recursie de waarde van ab (a tot-de-macht b) berekent. Je mag aannemen dat b ≥ 0. public class Macht { public static int macht(int a, int b) { if(b == 0) return 1; return a * macht(a, b - 1); } } Overloading Overloading demo class Overload { void ovlDemo() { System.out.println("No parameters"); } // Overload ovlDemo for one integer parameter. void ovlDemo(int a) { System.out.println("One parameter: " + a); } // Overload ovlDemo for two integer parameters. int ovlDemo(int a, int b) { System.out.println("Two parameters: " + a + " " + b); return a + b; } // Overload ovlDemo for two double parameters. double ovlDemo(double a, double b) { System.out.println("Two double parameters: "+a+" "+b); return a + b; } } Overloading demo class OverloadDemo { public static void main(String[] args) { Overload ob = new Overload(); int resI; double resD; // call all versions of ovlDemo() ob.ovlDemo(); System.out.println(); ob.ovlDemo(2); System.out.println(); resI = ob.ovlDemo(4, 6); System.out.println("Result of ob.ovlDemo(4, 6): " + resI); System.out.println(); resD = ob.ovlDemo(1.1, 2.32); System.out.println("Result of ob.ovlDemo(1.1, 2.2): " + resD); } } Overloading I Bij een functieaanroep kijkt Java naar de naam van de functie en de types van de parameters Overloading I Bij een functieaanroep kijkt Java naar de naam van de functie en de types van de parameters I Er mogen dus meerdere functies met dezelfde naam zijn, zolang de types van de parameters verschillend zijn Overloading I Bij een functieaanroep kijkt Java naar de naam van de functie en de types van de parameters I Er mogen dus meerdere functies met dezelfde naam zijn, zolang de types van de parameters verschillend zijn I Ook resultaatwaarde mag anders zijn, maar die wordt niet gebruikt voor de keuze Overloading I Bij een functieaanroep kijkt Java naar de naam van de functie en de types van de parameters I Er mogen dus meerdere functies met dezelfde naam zijn, zolang de types van de parameters verschillend zijn I Ook resultaatwaarde mag anders zijn, maar die wordt niet gebruikt voor de keuze I Ook constructors mogen overloaded zijn Overloading I Bij een functieaanroep kijkt Java naar de naam van de functie en de types van de parameters I Er mogen dus meerdere functies met dezelfde naam zijn, zolang de types van de parameters verschillend zijn I Ook resultaatwaarde mag anders zijn, maar die wordt niet gebruikt voor de keuze I Ook constructors mogen overloaded zijn I Bijvoorbeeld veel functies in Math klasse zijn overloaded Overloaded constructor public class Persoon { String naam; int leeftijd; int lengte; public Persoon(String naam) { this.naam = naam; this.leeftijd = 0; this.lengte = 47; } public Persoon(String naam, int leeftijd, int lengte) { this.naam = naam; this.leeftijd = leeftijd; this.lengte = lengte; } } Interfaces Interface I Een interface specificeert wat een klasse moet doen, maar niet hoe Interface I Een interface specificeert wat een klasse moet doen, maar niet hoe I Interface heeft een naam en een aantal methode-declaraties Interface I Een interface specificeert wat een klasse moet doen, maar niet hoe I Interface heeft een naam en een aantal methode-declaraties I Een klasse kan een interface implementeren met: class KlasseNaam implements InterfaceNaam Interface I Een interface specificeert wat een klasse moet doen, maar niet hoe I Interface heeft een naam en een aantal methode-declaraties I Een klasse kan een interface implementeren met: class KlasseNaam implements InterfaceNaam I Klasse moet dan ook alle methoden van die interface implementeren Voorbeeldinterface // Interface voor objecten die kunnen groeien public interface Groeit { // Geef terug hoe groot het object is public int hoeGroot(); // Geef het object water public void geefWater(int liter); } Voorbeeldimplementatie // Een plant kan groeien public class Plant implements Groeit { int hoogte = 0; public int hoeGroot() { return hoogte; } public void geefWater(int liter) { // Een plant groeit wel 5cm per liter water hoogte += liter * 5; } } Voorbeeldimplementatie 2 // Ook een boom kan groeien public class Boom implements Groeit { int hoogte = 0; public int hoeGroot() { return hoogte; } public void geefWater(int liter) { // Een boom heeft meer dan 10 liter water // nodig om te groeien if(liter > 10) hoogte++; } } Interface I Meedere klassen kunnen dezelfde interface implementeren Interface I Meedere klassen kunnen dezelfde interface implementeren I Hiermee maken we verschillende objecten met dezelfde functies Interface I Meedere klassen kunnen dezelfde interface implementeren I Hiermee maken we verschillende objecten met dezelfde functies I Interface geeft ook een type Interface I Meedere klassen kunnen dezelfde interface implementeren I Hiermee maken we verschillende objecten met dezelfde functies I Interface geeft ook een type I Elk object van een klasse die de interface implementeert kan dat type hebben Groeit gebruik public class GroeitMain { public static void main(String[] args) { // Maak een boom en plant aan en geef water Boom boom = new Boom(); boom.geefWater(50); Plant plant = new Plant(); plant.geefWater(2); // Elke boom en plant is ook van type Groeit Groeit groeit1 = plant; Groeit groeit2 = boom; // Geef elk nog wat water groeit1.geefWater(5); groeit2.geefWater(5); System.out.println(groeit1.hoeGroot()); System.out.println(groeit2.hoeGroot()); } } Expressievoorbeeld Maak klassen aan voor het representeren van rekenkundige expressies bestaande uit ofwel een getal ofwel een optelling van twee expressies. Deze expressies moeten een methode toString hebben om ze als String te printen en een methode waarde om de waarde uit te rekenen. Voorbeeld: (1 + 3) + (5 + 9) SAT-solver Organisatorisch I Opdracht in tweetallen Organisatorisch I Opdracht in tweetallen I Begin op tijd! Organisatorisch I Opdracht in tweetallen I Begin op tijd! I Gezamenlijk cijfer betekent ook dat de bedoeling is dat jullie elk evenveel bijdragen SAT-solver I Gegeven een formule uit propositielogica, vindt een valuatie die de formule waar maakt SAT-solver I Gegeven een formule uit propositielogica, vindt een valuatie die de formule waar maakt I Bijvoorbeeld: p ∧ (¬p ∨ ¬q) SAT-solver I Gegeven een formule uit propositielogica, vindt een valuatie die de formule waar maakt I Bijvoorbeeld: p ∧ (¬p ∨ ¬q) I De formule is waar wanneer p waar is en q onwaar SAT-solver I Gegeven een formule uit propositielogica, vindt een valuatie die de formule waar maakt I Bijvoorbeeld: p ∧ (¬p ∨ ¬q) I De formule is waar wanneer p waar is en q onwaar I Basisidee: probeer alle mogelijkheden Toepassingen I Planningsproblemen (bv. treinschema) Toepassingen I Planningsproblemen (bv. treinschema) I Roostering (bv. roosters op middelbare school) Toepassingen I Planningsproblemen (bv. treinschema) I Roostering (bv. roosters op middelbare school) I Software-verificatie (voldoet programma aan bepaalde eigenschappen?) Toepassingen I Planningsproblemen (bv. treinschema) I Roostering (bv. roosters op middelbare school) I Software-verificatie (voldoet programma aan bepaalde eigenschappen?) I Logische problemen (bv. sudoku oplossen) Toepassingen I Planningsproblemen (bv. treinschema) I Roostering (bv. roosters op middelbare school) I Software-verificatie (voldoet programma aan bepaalde eigenschappen?) I Logische problemen (bv. sudoku oplossen) I Etc... SAT-solver p ∧ (¬p ∨ ¬q) SAT-solver p ∧ (¬p ∨ ¬q) vervulbaar? p = true p = false q = true q = false q = true q = false nee ja! nee nee SAT-solver (iets slimmer) p ∧ (¬p ∨ ¬q) vervulbaar? p = true p = false q = true q = false nee ja! nee