Άλλες τεχνικές αφαίρεσης Προσομοίωση παρακολούθησης πληθυσμών αλεπούδων και ρ μ η ρ η ης η μ κουνελιών
Άλλες τεχνικές αφαίρεσης public class Fox { private static final int BREEDING_AGE = 10; private static final int MAX_AGE = 150; private static final double BREEDING_PROBABILITY = 0.09; private static final int MAX_LITTER_SIZE = 3; private static final int RABBIT_FOOD_VALUE = 4; private static final Random rand = new Random(); private int age; private boolean alive; private Location location; private int foodlevel; public Fox(boolean randomage) { age = 0; alive = true; if(randomage) { age = rand.nextint(max_age); foodlevel = rand.nextint(rabbit_food_value); else { // leave age at 0 foodlevel = RABBIT_FOOD_VALUE;
Άλλες τεχνικές αφαίρεσης public class Rabbit { private static final int BREEDING_AGE = 5; private static final int MAX_AGE = 50; private static final double BREEDING_PROBABILITY = 0.15; private static final int MAX_LITTER_SIZE = 5; private static final Random rand = new Random(); private int age; private boolean alive; private Location location; public void run(field updatedfield, List<Rabbit> newrabbits) {.... private void incrementage() {.... public Rabbit(boolean randomage) { age = 0; alive = true; if(randomage) { age = rand.nextint(max_age); private int breed() {...... private boolean canbreed() {..... public boolean isalive() {...... public void seteaten() {....... public void setlocation(int row, int col) {.... public void setlocation(location location) {....
Άλλες τεχνικές αφαίρεσης Οι κλάσεις Fox και Rabbit ορίζουν και οι δύο τα χαρακτηριστικά age, alive και location τα οποία μπορούν να μεταφερθούν σε μία νέα υπερκλάση Animal μαζί με τις μεθόδους isalive και setlocation. Με τη μετακίνηση των τριών χαρακτηριστικών στην κλάση Animal προκύπτει ποια πρέπει να είναι η ορατότητα τους. Η κλάση Rabbit ορίζει μια μέθοδο μετάλλαξης seteaten που χρησιμοποιείται από τη μέθοδο findfood της κλάσης Fox. Ωστόσο, τόσο η κλάση Fox όσο και ηκλάση Rabit χρειάζεται να θέτουν την τιμή false στο χαρακτηριστικό alive σε άλλα σημεία (μεθόδους incrementage). Μια λογική αλλαγή είναι να δώσουμε στη μέθοδο seteaten το γενικότερο όνομα setdead και να την τοποθετήσουμε στην κλάση Animal, έτσι ώστε να μπορούν να τη χρησιμοποιούν οι μέθοδοι βηματικής αύξησης.
Άλλες τεχνικές αφαίρεσης
Στην κλάση Simulator χρησιμοποιήθηκαν η διαφορετικοί τύποι λίστας για τις αλεπούδες και τα κουνέλια καθώς και κώδικας διάσχισης της κάθε λίστας. Τώρα που έχουμε την κλάση Animal μπορούμε να βελτιώσουμε τον κώδικα. Να συγχωνεύσουμε τις δύο συλλογές σε μία. for(iterator<animal> it = animals.iterator(); iterator(); it.hasnext(); ) { Animal animal = it.next(); if(animal instanceof (Rabbit)) { Rabbit rabbit = (Rabbit) animal; rabbit.run(updatedfield, newanimals); else if(animal instanceof Fox) { Fox fox = (Fox) animal; fox.hunt(field, updatefield, newanimals); else { System.out.println( found unknown animal ); if(!animal.isalive()) { it.remove();
Παρότι γνωρίζουμε ότι κάθε στοιχείο στη λίστα είναι ένα αντικείμενο τύπου Animal, πρέπει να καθορίσουμε τι τύπου ζώα είναι, προκειμένου να καλέσουμε τη σωστή μέθοδο ενέργειας για τον τύπο του. Ο τελεστής instanceof ελέγχει αν ένα δεδομένο αντικείμενο είναι, άμεσα ή έμεσα, στιγμιότυπο μιας δεδομένης κλάσης. Ο έλεγχος obj instanceof MyClass επιστρέφει την τιμή true αν ο δυναμικός τύπος της obj είναι MyClass ή οποιαδήποτε υποκλάση της MyClass. Έτσι όμως δεν αξιοποιούνται πλήρως οι δυνατότητες που προσφέρει η κληρονομικότητα.
Αν εξασφαλίσουμε ότι η υπερκλάση Animal έχει μια μέθοδο που επιτρέπει σε ένα ζώο να ενεργεί και ότι η μέθοδος αυτή ορίζεται εκ νέου σε κάθε υποκλάση, τότε μπορούμε να χρησιμοποιήσουμε μια πολυμορφική κλήση μεθόδου. for(iterator<animal> it = animals.iterator(); it.hasnext(); ) { Animal animal = it.next(); animal.act(field, updatedfield, newanimals); // Remove dead animals from the simulation. if(! animal.isalive()) { it.remove();
ΠΑΡΑΤΗΡΗΣΕΙΣ Υποθέτουμε ότι οι συγκεκριμένες μέθοδοι δράσης των ζώων (η run της κλάσης Rabbit και η hunt της κλάσης Fox) έχουν μετονομαστεί σε act. Η μέθοδος run της κλάσης Rabbit είχε μόνο δύο παραμέτρους, ρ την updatefield και τη newanimals. Τώρα έχουμε προσθέσει μια τρίτη παράμετρο, τη field, για να υπάρχει συνέπεια με τη μέθοδο act της κλάσης Fox. Ε δή δ ό ύ βλ ή ί ό Επειδή ο δυναμικός τύπος της μευαβλητής είναι αυτός που καθορίζει ποια μέθοδος εκτελείται τελικά, η μέθοδος ενέργειας των αλεπούδων θα εκτελείται για τις αλεπούδες, ενώ η αντίστοιχη μέθοδος θα εκτελείται για τα κουνέλια.
Αφού ο έλεγχος τύπων πραγματοποιείται με τη ηβοήθεια του στατικού τύπου, ο κώδικας θα μεταγλωττιστεί μόνον αν η κλάση Animal διαθέτει μια μέθοδο act με τη σωστή υπογραφή. Παρόλο όμως που κάθε ζώο μπορεί να εκτελέσει συγκεκριμένο σύνολο ενεργειών, δε μπορούμε να περιγράψουμε τις ενέργειες για τα ζώα γενικά. Οι εκάστοτε ενέργειες εξαρτώνται από το συγκεκριμένο υποτύπο. Το πρόβλημα απορρέει από το γεγονός ότι δεν πρόκειται να Το πρόβλημα απορρέει από το γεγονός ότι δεν πρόκειται να υπάρξει ποτέ κανένα στιγμιότυπο της κλάσης Animal.
Κλάσεις οι οποίες δεν προορίζονται ρ για τη δημιουργία αντικειμένων αλλά χρησιμοποιούνται μόνο ως υπερκλάσεις, είναι γνωστές ως αφηρημένες κλάσεις (abstract classes). Για την κλάση Animal lθέλουμε να δηλώσουμε ότι για κάθε ζώο υπάρχει μια μέθοδος act, αλλά δεν μπορούμε να δώσουμε μια λογική υλοποίηση αυτής της μεθόδου στην κλάση Animal. abstract public void act(field currentfield, Field updatedfield, dfi List<Animal> i newanimals); Η μέθοδος έχει ως πρόθεμα τη λέξη κλειδί abstract. Η μέθοδος δεν έχει σώμα. Η επικεφαλίδα της τερματίζεται με ένα ελληνικό ερωτηματικό.