This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
java:this_operator [2015/02/05 10:41] gthanos |
java:this_operator [2016/02/26 11:15] 127.0.0.1 external edit |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Oι τελεστές this και super ====== | + | ====== Ο τελεστής this ====== |
- | ===== Ο τελεστής this ===== | + | ===== Πρόσβαση σε πεδία και μεθόδους των αντικειμένων της κλάσης μέσω του τελεστή this ===== |
- | ==== Πρόσβαση στους κατασκευαστές της κλάσης μέσω του τελεστή this ==== | + | Ας ξαναγράψουμε το παρακάτω τμήμα κώδικα το οποίο συναντήσαμε προηγούμενα, ως εξής |
- | + | ||
- | Ας ξαναγράψουμε το παρακάτω τμήμα κώδικα το οποίο συναντήσαμε προηγούμενα | + | |
<code java> | <code java> | ||
public class Rectangle { | public class Rectangle { | ||
- | private int width, height; | + | |
- | private Point origin; | + | private int width; |
- | | + | private int height; |
- | public Rectangle(Point p, int w, int h) { | + | private Point origin; |
- | origin = p; | + | |
- | width = w; | + | // the Rectangle class has one constructor |
- | height = h; | + | public Rectangle(int width, int height, Point origin) { |
- | } | + | width = width; |
- | + | height = height; | |
- | public Rectangle(int x, int y) { | + | origin = origin; |
- | width = w; | + | } |
- | height = h; | + | ... |
- | } | + | |
- | .... | + | |
} | } | ||
</code> | </code> | ||
- | ως εξής | + | Στον παραπάνω κώδικα οι τοπικές παράμετροι του κατασκευαστή συμπίπτουν με τα ονόματα των μεταβλητών της κλάσης. Σε αυτή την περίπτωση η τοπική μεταβλητή/παράμετρος "κρύβει" (shadows) την μεταβλητή του αντικειμένου της κλάσης. Προκειμένου να έχουμε πρόσβαση στην μεταβλητή του αντικειμένου της κλάσης θα πρέπει να χρησιμοποιήσουμε τον τελεστή **this**, ως εξής: |
<code java> | <code java> | ||
public class Rectangle { | public class Rectangle { | ||
- | private int width, height; | + | |
- | private Point origin; | + | private int width; |
- | | + | private int height; |
- | public Rectangle(Point p, int w, int h) { | + | private Point origin; |
- | origin = p; | + | |
- | this(w,h) | + | // the Rectangle class has one constructor |
- | } | + | public Rectangle(int width, int height, Point origin) { |
- | + | this.width = width; | |
- | public Rectangle(int w, int h) { | + | this.height = height; |
- | width = w; | + | this.origin = origin; |
- | height = h; | + | } |
- | } | + | ... |
- | .... | + | |
} | } | ||
</code> | </code> | ||
- | Ο τελεστής **this** δείχνει στο τρέχον αντικείμενο και χρησιμοποιείται για να προσπελαστεί ένας άλλος κατασκευαστής της ίδιας κλάσης. | + | __O τελεστής **this** υποδεικνύει το τρέχον αντικείμενο__. Με τον παραπάνω τρόπο μπορούμε να διακρίνουμε μία μεταβλητής του τρέχοντος αντικειμένου (της μορφής **this.**//variable//) από μία τοπική μεταβλητή (//variable//) με το ίδιο όνομα. |
- | ==== Πρόσβαση σε πεδία και μεθόδους των αντικειμένων της κλάσης μέσω του τελεστή this ==== | + | ===== Πρόσβαση στους κατασκευαστές της κλάσης μέσω του τελεστή this ===== |
- | Ας ξαναγράψουμε το παρακάτω τμήμα κώδικα το οποίο συναντήσαμε προηγούμενα: | + | Ας ξαναδούμε το παρακάτω τμήμα κώδικα το οποίο συναντήσαμε προηγούμενα θέλοντας να επιχειρήσουμε να επαναχρησιμοποιήσουμε τμήματα κώδικα ενός κατασκευαστή από έναν άλλο κατασκευαστή. |
<code java> | <code java> | ||
public class Rectangle { | public class Rectangle { | ||
- | private int width, height; | + | |
- | private Point origin; | + | private int width; |
- | + | private int height; | |
- | public Rectangle(Point p, int w, int h) { | + | private Point origin; |
- | origin = p; | + | |
- | width = w; | + | public Rectangle(int initWidth, int initHeight, Point initOrigin) { |
- | height = h; | + | width = initWidth; |
- | } | + | height = initHeight; |
- | ... | + | origin = initOrigin; |
- | + | } | |
+ | |||
+ | public Rectangle(int initWidth, int initHeight, int xPos, int yPos) { | ||
+ | width = initWidth; | ||
+ | height = initHeight; | ||
+ | origin = new Point(xPos,yPos); | ||
+ | } | ||
+ | .... | ||
} | } | ||
</code> | </code> | ||
- | Εναλλακτικά, το παραπάνω μπορεί να γραφεί ως εξής. | + | Ιδανικά θα θέλαμε να καλέσουμε έναν κατασκευαστή μέσα από έναν άλλο κατασκευαστή. Στη Java αυτό είναι εφικτό με χρήση του τελεστή **this**, ως εξής: |
<code java> | <code java> | ||
public class Rectangle { | public class Rectangle { | ||
- | private int width, height; | + | |
- | private Point origin; | + | private int width; |
- | + | private int height; | |
- | public Rectangle(Point origin, int width, int height) { | + | private Point origin; |
- | this.origin = origin; | + | |
- | this.width = width; | + | public Rectangle(int initWidth, int initHeight, Point initOrigin) { |
- | this.height = height; | + | width = initWidth; |
- | } | + | height = initHeight; |
- | ... | + | origin = initOrigin; |
+ | } | ||
+ | |||
+ | public Rectangle(int initWidth, int initHeight, int xPos, int yPos) { | ||
+ | this(initWidth, initHeight, new Point(xPos,yPos)); | ||
+ | } | ||
+ | .... | ||
} | } | ||
</code> | </code> | ||
- | Στον παραπάνω κώδικα η τοπική μεταβλητή ''origin'' που δίνεται ως τυπική παράμετρος στον κατασκευαστή, συμπίπτει με την μεταβλητή της κλάσης. Σε αυτή την περίπτωση η τοπική μεταβλητή "κρύβει" (shadows) την μεταβλητή του αντικειμένου της κλάσης. Προκειμένου να έχουμε πρόσβαση στην μεταβλητή του αντικειμένου της κλάσης θα πρέπει να χρησιμοποιήσουμε τον τελεστή **this**. | + | __Το παραπάνω, είναι αποδεκτό από τον compiler της Java__. Ο τελεστής **this** χρησιμοποιείται για να κληθεί από ένα κατασκευαστή ένας άλλος κατασκευαστής της ίδιας κλάσης. |
- | Συμπερασματικά, ο τελεστής **this** δείχνει στο τρέχον αντικείμενο και χρησιμοποιείται για να προσπελαστούν δεδομένα ή μεταβλητές που ανήκουν σε αντικείμενα της κλάσης. | + | <WRAP important 80% center round> |
+ | Η κλήση ενός κατασκευαστή μέσα από άλλο κατασκευαστή θα πρέπει να γίνει στην αρχή του σώματος του κατασκευαστή. Αν δεν το κάνετε και προηγηθεί μία άλλη εντολή πριν την κλήση του κατασκευαστή θα λάβετε ένα μήνυμα λάθους από τον compiler. Ενδεικτικό είναι το παρακάτω παράδειγμα: | ||
- | <WRAP tip> | + | <code java> |
- | O τελεστής **this** δείχνει στο τρέχον αντικείμενο της εκάστοτε κλάσης, για λογαριασμό του οποίου εκτελείται. | + | public class Rectangle { |
- | </WRAP> | + | |
- | ===== Ο τελεστής super ===== | + | private int width; |
- | + | private int height; | |
- | Σε αναλογία με τον τελεστή **this**, ο τελεστής **super** δείχνει στο αντικείμενο της γονικής κλάσης. Προϋπόθεση για την χρήση του τελεστή **super** είναι να υφίσταται γονική κλάση μέσω της διαδικασίας της κληρονομικότητας. | + | private Point origin; |
- | + | ||
- | ==== Πρόσβαση στους κατασκευαστές της γονικής κλάσης μέσω του τελεστή super ==== | + | public Rectangle(int width, int height, Point origin) { |
- | + | this.origin = origin; | |
- | Λαμβάνοντας κώδικα από το προηγούμενο παράδειγμα του ποδηλάτου έχουμε τα εξής: | + | this(width, height); |
- | + | ||
- | <code java Bicycle.java> | + | } |
- | public class Bicycle { | + | |
- | | + | public Rectangle(int width, int height) { |
- | // the Bicycle class has | + | this.width = width; |
- | // three fields | + | this.height = height; |
- | public int cadence; | + | } |
- | public int gear; | + | .... |
- | public int speed; | + | |
- | | + | |
- | // the Bicycle class has | + | |
- | // one constructor | + | |
- | public Bicycle(int startCadence, int startSpeed, int startGear) { | + | |
- | gear = startGear; | + | |
- | cadence = startCadence; | + | |
- | speed = startSpeed; | + | |
- | } | + | |
- | + | ||
- | // the Bicycle class has | + | |
- | // four methods | + | |
- | public void setCadence(int newValue) { | + | |
- | cadence = newValue; | + | |
- | } | + | |
- | + | ||
- | public void setGear(int newValue) { | + | |
- | gear = newValue; | + | |
- | } | + | |
- | | + | |
- | public void applyBrake(int decrement) { | + | |
- | speed -= decrement; | + | |
- | } | + | |
- | + | ||
- | public void speedUp(int increment) { | + | |
- | speed += increment; | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </code> | + | |
- | + | ||
- | <code java MountainBike.java> | + | |
- | public class MountainBike extends Bicycle { | + | |
- | + | ||
- | // the MountainBike subclass has | + | |
- | // one field | + | |
- | public int seatHeight; | + | |
- | + | ||
- | // the MountainBike subclass has | + | |
- | // one constructor | + | |
- | public MountainBike(int startHeight, int startCadence, | + | |
- | int startSpeed, int startGear) { | + | |
- | super(startCadence, startSpeed, startGear); | + | |
- | seatHeight = startHeight; | + | |
- | } | + | |
- | + | ||
- | // the MountainBike subclass has | + | |
- | // one method | + | |
- | public void setHeight(int newValue) { | + | |
- | seatHeight = newValue; | + | |
- | } | + | |
- | + | ||
} | } | ||
</code> | </code> | ||
+ | </WRAP> | ||
- | H χρήση του τελεστή super χρησιμοποιείται για να προσπελάσει τον κατασκευαστή της γονικής κλάσης και να αρχικοποιήσει τις μεταβλητές που ανήκουν στην κλάση αυτή. | ||
- | |||
- | ==== Πρόσβαση σε πεδία και μεθόδους των αντικειμένων της γονικής κλάσης μέσω του τελεστή super ==== | ||
- | |||
- | Ο κατασκευαστής της κλάσης ''MountainBike'' θα μπορούσε να γραφεί ως εξής. | ||
- | |||
- | <code java MountainBike.java> | ||
- | public class MountainBike extends Bicycle { | ||
- | |||
- | // the MountainBike subclass has | ||
- | // one field | ||
- | public int seatHeight; | ||
- | |||
- | // the MountainBike subclass has | ||
- | // one constructor | ||
- | public MountainBike(int startHeight, int startCadence, | ||
- | int startSpeed, int startGear) { | ||
- | super(startCadence, startSpeed, startGear); | ||
- | super.cadence = startCadence; | ||
- | super.speed = startSpeed; | ||
- | super.gear = startGear; | ||
- | seatHeight = startHeight; | ||
- | } | ||
- | |||
- | // the MountainBike subclass has | ||
- | // one method | ||
- | public void setHeight(int newValue) { | ||
- | seatHeight = newValue; | ||
- | } | ||
- | |||
- | } | ||
- | </code> | ||
- | Συμπερασματικά, ο τελεστής **super** δείχνει στο αντικείμενο της γονικής κλάσης και χρησιμοποιείται για να προσπελαστούν δεδομένα ή μεταβλητές που ανήκουν στο τμήμα του τρέχοντος αντικειμένου που αφορά την γονική κλάση. | + | <WRAP tip 80% center round> |
+ | O τελεστής **this** δείχνει στο τρέχον αντικείμενο της εκάστοτε κλάσης, για λογαριασμό του οποίου εκτελείται. Μπορείτε να τον χρησιμοποιείτε τόσο για να προσπελάσετε τα πεδία του αντικειμένου ή να καλέσετε τον κατασκευαστή της κλάσης για το τρέχον αντικείμενο. Με χρήση του τελεστή **this** μπορείτε επίσης να καλέσετε και μεθόδους της κλάσης από το τρέχον αντικείμενο, πράγμα που όμως δεν θα το δείτε, καθώς στην πράξη δεν υπάρχει ανάγκη για κάτι τέτοιο. | ||
- | <WRAP important>Απαραίτητη προϋποθεση για την χρήση του τελεστη **super** είναι τα παιδιά της γονικής κλάσης να έχουν πρόσβαση στα δεδομένα ή τις μεθόδους της γονικής κλάσης. Για να γίνει αυτό, τα πεδία και οι μέθοδοι της γονικής κλάσης που θέλουμε να προσπελάσουμε δεν θα πρέπει να έχουν των προσδιοριστή πρόσβασης **private**. Περισσότερα για τους προσδιοριστές πρόσβασης θα δούμε παρακάτω, όταν θα έχουμε εξήγήσει την φιλοσοφία των πακέτων στην γλώσσα JAVA. | + | Μπορείτε να δείτε την κλάση **Rectangle**, όπως διαμορφώνεται με χρήση του τελεστή **this** τόσο για την κλήση ενός κατασκευαστή της κλάσης από άλλο, όσο για την πρόσβαση στα πεδία της κλάσης όταν αυτά επισκιάζονται από τοπικές μεταβλητές ή παραμέτρους μεθόδων με το ίδιο όνομα {{:java:rectangle.java-this.tgz|εδώ}}. |
</WRAP> | </WRAP> | ||
- | |Προηγούμενο: [[:java:this_operator | Oι τελεστές this και super ]] | Επόμενο: [[:java:static_keyword | Στατικές μεταβλητές και μέθοδοι ]]| | + | |Προηγούμενο: [[:java:objects| Δημιουργώντας Αντικείμενα ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[:java:static_keyword | Στατικές μεταβλητές και μέθοδοι ]]| |