JAVA ΕΝΟΤΗΤΑ 16 – THEORY REVIEW (COMPLETE EXAMPLE)

 


ΕΙΣΑΓΩΓΗ

Στο σημερινό δωρεάν μάθημα Java θα δούμε ένα ολοκληρωμένο πρόγραμμα που συμπεριλαμβάνει όλη την θεωρία για την οποία έχουμε μιλήσει μέχρι αυτή τη στιγμή. 

Το πρόγραμμα είναι ένα simulation ενός ποδοσφαιρικού αγώνα. Όλες οι διαδικασίες του αγώνα, όπως π.χ σκορ, γίνονται μέσα από μεθόδους. Ας δούμε όμως με περισσότερες λεπτομέρειες το πρόβλημα και πως πρέπει να το προσεγγίσουμε για να δημιουργήσουμε την αντίστοιχη προγραμματιστική λύση.

PROBLEM STATEMENT

Μας έχει ζητηθεί λοιπόν να δημιουργήσουμε ένα πρόγραμμα το οποίο θα πρέπει να καλύπτει τα εξής κριτήρια:

  • Θα υπάρχει δυνατότητα δημιουργίας δύο ομάδων με τα εξής χαρακτηριστικά: όνομα της ομάδας και πόλη από την οποία προέρχεται η ομάδα
  • Θα πρέπει να μπορούμε να ορίσουμε ποιος είναι ο γηπεδούχος και ποιος ο φιλοξενούμενος
  • Κατά την διάρκεια του αγώνα θα πρέπει να μπορούμε ορίζουμε ποια ομάδα βάζει γκολ
  • Όταν τελειώσει ο αγώνας να μπορούμε να δείξουμε το τελικό σκορ και τον νικητή του αγώνα.

Στο συγκεκριμένο πρόβλημα, όπως και σε κάθε άλλο πρόβλημα που ίσως σας δοθεί, η προσέγγιση στην οποία είχαμε αναφερθεί στις προηγούμενες ενότητες είναι η ίδια – ψάχνουμε να βρούμε μέσα από τις λέξεις ποια είναι τα αντικείμενα που μας ενδιαφέρουν. Για αυτό και άλλωστε είναι πολύ σημαντικό να έχουμε κατανοήσει πλήρως το πρόβλημα και να έχουμε μαζέψει όσες πιο πολλές λεπτομέρειες γίνεται. Στο δικό μας πρόβλημα μπορούμε να ξεχωρίσουμε δύο αντικείμενα – εκείνο της ομάδας και εκείνο του αγώνα.

LETS CREATE OUR FIRST CLASS

Πριν όμως ξεκινήσουμε να αναλύουμε με λεπτομέρειες την ανάπτυξη του προγράμματος, ας δημιουργήσουμε ένα καινούργιο Java Project με το όνομα SoccerGame μέσα στο οποίο θα δημιουργήσουμε ένα πακέτο με το όνομα com.soccer.

Όπως ήδη αναφέραμε, ένα από τα αντικείμενα που θα χρειαστούμε είναι εκείνο που περιγράφει την ομάδα, ή καλύτερα την κάθε ομάδα που θα δημιουργούμε. Ένα αντικείμενο δημιουργείται από μια κλάση. Οπότε χρειάζεται να δημιουργήσουμε μια κλάση η οποία περιγράφει μια ομάδα. Είδατε πως ακολουθούμε κατά γράμμα όλα όσα έχουμε μάθει μέχρι τώρα? Δημιουργούμε λοιπόν μέσα στο πακέτο com.soccer μια κλάση με το όνομα Team.

Ποια χαρακτηριστικά θα θέλατε να προσθέσετε στην ομάδα για να την περιγράψετε? Με άλλα λόγια, πόσες instance μεταβλητές και με ποια ονόματα θα ικανοποιούσαν την ανάγκη περιγραφής μιας ομάδας? Μερικά από τα χαρακτηριστικά ίσως ήταν το όνομα της ομάδας, η πόλη στην οποία ανήκει, η βαθμολογία της, πόσα γκολ έχει σκοράρει μέχρι τώρα κτλ. Εμείς για να κρατήσουμε το πρόγραμμα μας σε μια απλή μορφή θα περιγράψουμε την ομάδα με δύο μεταβλητές: το όνομα και την πόλη. Ο ολοκληρωμένος κώδικας της κλάσης Team είναι ο εξής:

Team.java

package com.soccer;

public class Team {
    public String name;
    public String city;
}


LET’S NOW CREATE OUR SECOND CLASS

Τώρα ας δημιουργήσουμε μια ακόμα κλάση με το όνομα SoccerGame η οποία θα περιέχει μεθόδους που μπορούμε να καλέσουμε και να κάνουμε simulation τον αγώνα. Ας γράψουμε πρώτα τον κώδικα και αμέσως μετά θα εξηγήσουμε τι ακριβώς ιδιότητες περιέχει.

SoccerGame.java

package com.soccer;

public class SoccerGame {
    public Team home, visitor;
    public int homeScore, visitorScore;

    public void homeTeamScored(int numberOfGoals) {

        this.homeScore += numberOfGoals;
    }

    public void visitorTeamScored(int numberOfGoals) {
        this.visitorScore += numberOfGoals;
    }

    public void setHomeTeam(Team home) {
        this.home = home;
    }

    public void setVisitingTeam(Team visitor) {
        this.visitor = visitor;
    }

    public void gameOver() {
        if (this.homeScore > this.visitorScore) {
            System.out.println("That was a great victory by " + home.name);
            System.out.println("Final score was " + home.name
+ " " + homeScore +" - " + visitor.name + " " + visitorScore);
        } else {
            System.out.println("That was a great victory by " + visitor.name);
            System.out.println("Final score was " + home.name
+ " " + homeScore +" - " + visitor.name + " " + visitorScore);
        }
    }
}


Ορίζουμε λοιπόν μια κλάση με το όνομα SoccerGame μέσα στο ίδιο πακέτο com.soccer. Η κλάση αυτή είναι απαραίτητη γιατί μέσα από αυτήν θα δημιουργήσουμε το αντικείμενο game.

Για αρχή, ορίζουμε δύο instance μεταβλητές με το όνομα home και visitor που είναι είδος Team. Στην ουσία αυτές είναι reference που θα αναφέρονται στα αντικείμενα των δύο ομάδων που θα δημιουργήσουμε αργότερα. Αυτή τη στιγμή η τιμή τους είναι null, δηλαδή είναι ονόματα που δεν δείχνουν σε κανένα αντικείμενο.

Το καινούργιο στοιχείο που βλέπετε σε αυτό το παράδειγμα είναι ότι εκτός από τα συνηθισμένα data types που έχουμε δει μέχρι τώρα, σαν instance μεταβλητές μπορούμε να ορίσουμε και reference με data type μια κλάση. Ένα reference δεν είναι αντικείμενο γιατί δεν δείχνει ακόμα σε κάποιο σημείο της μνήμης που να υπάρχει αντικείμενο δημιουργημένο από κάποιον constructor. Απλά εδώ ετοιμάζουμε τις μεταβλητές που αργότερα θα κουμπώσουν στα αντικείμενα που θα περάσουμε στις μεθόδους. Λίγο πιο κάτω αυτή η εικόνα θα είναι πιο ξεκάθαρη.

 Η δεύτερη ομάδα από instance μεταβλητές είναι εκείνες με το όνομα homeScore και visitorScore. Όπως καταλαβαίνετε αυτές οι μεταβλητές θα περιέχουν τον αριθμό των γκολ που θα δηλώσουμε για τον γηπεδούχο αλλά και για τον φιλοξενούμενο αντίστοιχα. Σας υπενθυμίζω ότι όλες οι instance μεταβλητές όλων των data types μηδενίζονται εξ αρχής από την java. Οπότε η home και η visitor είναι ίσον με το null ενώ η homeScore και η visitorScore είναι ίσον με το μηδέν.

Η πρώτη μέθοδος είναι η homeTeamScored( ) που περιέχει μια παράμετρο και κατά την εκτέλεση της απαιτεί έναν int αριθμό που αντιπροσωπεύει των αριθμό των γκολ για τους γηπεδούχους. Αυτός ο αριθμός θα προστεθεί σαν επίσημη τιμή στην instance μεταβλητή homeScore. Αυτή η μέθοδος στην πραγματικότητα είναι μια setter μέθοδο γιατί δια μέσω αυτής ορίζουμε τιμή στην μεταβλητή. Μα θα αναρωτηθείτε, δεν θα μπορούσαμε να ορίσουμε την τιμή απευθείας επάνω στην μεταβλητή? Ναι, επειδή είναι public θα μπορούσαμε. Αλλά θα δούμε ότι αυτός ο τρόπος μπορεί να μας προκαλέσει πολλά προβλήματα για αυτό προτιμούμε να χρησιμοποιούμε getter και setters μεθόδους. Για την ώρα δεν θα αναφερθούμε άλλο σε αυτό το είδος των μεθόδων γιατί θα το κάνουμε στην επόμενη ενότητα αφού μιλήσουμε και για τα access specifiers. Για τώρα απλά δεχόμαστε το γεγονός ότι αντί να επηρεάζουμε απευθείας την μεταβλητή θα χρησιμοποιήσουμε μέθοδο για να το κάνουμε αυτό. Τέλος, η μέθοδος homeTeamScored( ) δεν επιστρέφει τίποτα πίσω στο πρόγραμμα για αυτό και έχει οριστεί σαν void.

Κάτω από την ίδια λογική λειτουργεί και η μέθοδος visitorTeamScored( ) μόνο που αυτή θα επηρεάσει το σκορ για την φιλοξενούμενη ομάδα και κατά συνέπεια την μεταβλητή visitorScore.

Τώρα ήρθε η σειρά της setHomeTeam( ) η οποία και αυτή έχει μια παράμετρο στην παρένθεση όμως το στοιχείο που περιμένει είναι ένα αντικείμενο είδος Team. Οπότε, στην τρίτη κλάση που θα δημιουργήσουμε και θα περιέχει την main( ) , θα δημιουργήσουμε ένα αντικείμενο από την κλάση Team και θα το περάσουμε σαν μεταβλητή στην παράμετρο της setHomeTeam. Τώρα το reference home δεν είναι πια null αλλά δείχνει στην περιοχή της μνήμης εκεί που έχει δημιουργηθεί το αντικείμενο.

Ακριβώς με την ίδια λογική έχει δημιουργηθεί και η setVisitingTeam( ) μέθοδο. Αν και αυτή η μέθοδο περιμένει ένα αντικείμενο είδος Team, εδώ θα περάσουμε το αντικείμενο που θα αντιπροσωπεύει την φιλοξενούμενη ομάδα. Με την ίδια λογική περνάμε το αντικείμενο που έχουμε περάσει στην μέθοδο στο reference που είχαμε ορίσει στην αρχή της κλάσης.

Τώρα έχουμε περάσει και το αντικείμενο για την γηπεδούχο ομάδα και το αντικείμενο για την φιλοξενούμενη ομάδα στις instance μεταβλητές home και visitor.

Η τελευταία μέθοδο gameOver( ) είναι αυτή που συγκρίνει τις τιμές που έχουν οι homeScore και visitorScore μεταβλητές και αποφασίζει με μια απλή λογική if-else ποια ομάδα έχει νικήσει τον αγώνα. Η συγκεκριμένη μέθοδο δεν δέχεται καμία παράμετρο και δεν επιστρέφει τίποτα πίσω στο πρόγραμμα.

LET’S CREATE OUR TEAMS OBJECTS AND RUN THE PROGRAM

Οι δύο κλάσεις μας είναι έτοιμες. Μπορούμε και να δημιουργήσουμε αντικείμενα είδος ομάδων αλλά και αντικείμενο αγώνα που περιέχει τις ομάδες που αγωνίζονται. Αυτό που μας λείπει είναι να δημιουργήσουμε μια τρίτη κλάση που θα την ονομάσουμε GameDemo μέσα στην οποία θα δημιουργήσουμε τα αντικείμενα, θα καλέσουμε τις μεθόδους, και θα δούμε το τελικό σκορ του αγώνα. Ας δούμε τον ολοκληρωμένο κώδικα της κλάσης και το αποτέλεσμα της πριν αναλύσουμε την θεωρία.

GameDemo.java

package com.soccer;

public class GameDemo {
    public static void main(String[] args) {
        Team olympiakos = new Team();
        olympiakos.city = "Pireas";
        olympiakos.name = "Olympiakos";

        Team realMadrid = new Team();
        realMadrid.city = "Madrid";
        realMadrid.name = "Real Madrid";

        SoccerGame game = new SoccerGame();
        game.setHomeTeam(olympiakos);
        game.setVisitingTeam(realMadrid);
        game.homeTeamScored(1);
        game.visitorTeamScored(1);
        game.homeTeamScored(1);
        game.gameOver();

    }
}

Output

That was a great victory by Olympiakos

Final score was Olympiakos 2 - Real Madrid 1

Ο κώδικας μας ξεκινάει με την δημιουργία δύο αντικειμένων που αντιπροσωπεύουν δύο ομάδες. Για την κάθε ομάδα ορίζουμε το όνομα της και την πόλη στην οποία ανήκει.

Μετά ορίζουμε ένα αντικείμενο είδος game. Τώρα μπορούμε να καλέσουμε όλες τις μεθόδους της κλάσης SoccerGame. Ορίζουμε ποια θα είναι η γηπεδούχος ομάδα περνώντας το αντικείμενο σαν μεταβλητή στην setHomeTeam και αντίστοιχα την φιλοξενούμενη περνώντας το αντικείμενο της δεύτερης ομάδας στην setVisitingTeam. Αφού καλέσουμε τις homeTeamScored και visitorTeamScored όσες φορές θέλουμε για να δημιουργήσουμε κάποιο σκορ αγώνα, καλούμε στο τέλος την gameOver( ) μέθοδο για να δούμε ποιος είναι ο νικητής και με ποιο σκορ.

 


Νομίζω ότι κάναμε μια πολύ γερή επανάληψη σε όλα όσα έχουμε αναφέρει σε όλες τις προηγούμενες ενότητες. Θα μπορούσε ένα παρόμοιο πρόγραμμα να είναι λίγο πιο πολύπλοκο και αυτοματοποιημένο όπως για παράδειγμα να δημιουργείται τυχαία το τελικό σκορ του αγώνα. Η ουσία όμως είναι να κρατήσουμε το πρόγραμμα όσο πιο απλό γίνεται για να μπορείτε να θυμηθείτε και να κατανοήσετε την θεωρία που έχουμε καλύψει μέχρι αυτό το σημείο.

Αφού διαβάσετε την δική μου περιγραφή, καλό θα ήταν να προσπαθήσετε να εξηγήσετε μόνοι σας το πρόγραμμα γραμμή προς γραμμή για να το κατανοήσετε καλύτερα και να βρείτε τυχόν κενά στην θεωρία που θα πρέπει να καλύψετε με μια γρήγορη επανάληψη.

Μην ξεχάσετε να κάνετε ένα μικρό donation έτσι ώστε αυτό το blog να μεγαλώσει ακόμα πιο πολύ και να έχει περισσότερες δυνατότητες στην online παράδοση δωρεάν μαθημάτων.

full-width

Post a Comment

0 Comments