java:objects

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
java:objects [2015/02/05 10:14]
gthanos
java:objects [2016/01/22 15:48]
gthanos
Line 3: Line 3:
 Μέχρι τώρα αναφέραμε στην [[ oop:​introduction | "​Εισαγωγή στον Αντικειμενοστραφή Προγραμματισμό"​ ]] ότι η κλάση είναι το βασικό σχέδιο μέσα από το οποίο δημιουργούνται επιμέρους αντικείμενα που φέρουν τα χαρακτηριστικά της κλάσης. Επίσης,​ δείξαμε πως ορίζουμε μία κλάση μέσα από παραδείγματα,​ αλλά δεν δείξαμε πως δημιουργούμε αντικείμενα από τις κλάσεις που ορίσαμε. ​ Μέχρι τώρα αναφέραμε στην [[ oop:​introduction | "​Εισαγωγή στον Αντικειμενοστραφή Προγραμματισμό"​ ]] ότι η κλάση είναι το βασικό σχέδιο μέσα από το οποίο δημιουργούνται επιμέρους αντικείμενα που φέρουν τα χαρακτηριστικά της κλάσης. Επίσης,​ δείξαμε πως ορίζουμε μία κλάση μέσα από παραδείγματα,​ αλλά δεν δείξαμε πως δημιουργούμε αντικείμενα από τις κλάσεις που ορίσαμε. ​
  
-Παρακάτω δίνεται ένα πρόγραμμα που δημιουργεί συγκεκριμένα αντικείμενα και εκτυπώνει τα αποτελέσματα στην κονσόλα.+Παρακάτω δίνεται ένα πρόγραμμα που δημιουργεί συγκεκριμένα αντικείμενα ​του τύπου **Point** και **Rectangle** ​και εκτυπώνει τα αποτελέσματα στην κονσόλα.
  
 <code java Point.java>​ <code java Point.java>​
 public class Point { public class Point {
-   ​private int xCoord, yCoord+    private int x; 
-   ​ +    ​private int y
-   ​public Point(int ​x, int y) { +     
-       xCoord = x; +    public Point(int ​xPos, int yPos) { 
-       yCoord = y; +      = xPos
-   ​+      = yPos
-   ​public ​void setX(int x) { +    
-       xCoord = x; +     
-   ​+    ​public ​int getX() { 
-   ​public void setY(int y) { +      ​return ​x; 
-       yCoord ​y+    
-   ​+     
-   ​public int getX() { +    ​public void setX(int xPos) { 
-       ​return ​xCoord+      ​x ​xPos
-   ​+    
-   ​public ​int getY() { +     
-       return yCoord+    ​public int getY() { 
-   ​ +      return ​y
 +    
 +     
 +    ​public ​void setY(int yPos) { 
 +      y = yPos
 +    }
 } }
 </​code>​ </​code>​
Line 30: Line 35:
 <code java Rectangle.java>​ <code java Rectangle.java>​
 public class Rectangle { public class Rectangle {
-   private int widthheight; +     
-   ​private Point origin; +  // the Rectangle class has 3 fields 
-   ​ +  ​private int width
-   ​public Rectangle(Point p, int w, int h) { +  private int height; 
-       origin ​p+  private Point origin; 
-       width w+     
-       height ​h+  // the Rectangle class has one constructor 
-   ​+  ​public Rectangle(int ​setWidth, int setHeight, Point o) { 
-   ​ +    ​width ​setWidth
-   ​public Rectangle(int ​w, int h) { +    ​height ​setHeight
-       ​width = w+    ​origin ​o
-       ​height = h+  
-   ​+   
-   ​ +  public Rectangle(int ​setWidth, int setHeight) { 
-   ​public void setOrigin(Point p) { +    width = setWidth
-      ​origin ​p+    height = setHeight
-   ​+  
-   ​ +     
-   ​public ​void setHeight(int h) { +  // the Rectangel class has 3 methods 
-       height = h+  public void setWidth(int newWidth ​) { 
-   ​+    ​width ​newWidth
-   ​ +  
-   ​public void setWidth(int w) { +   
-       width w+  public int getWidth() { 
-   ​+    ​return width
-   ​ +  
-   ​public ​Point getOrigin() { +     
-       ​return ​origin+  public void setHeight(int newHeight ​) { 
-   ​+    ​height ​newHeight
-   ​ +  
-   ​public ​int getHeight() { +   
-       return height+  public ​int getHeight() { 
-   ​+    return ​height
-   ​ +  
-   ​public ​int getWidth() { +     
-       ​return ​width+  public ​void setOrigin(Point o) { 
-   ​+    ​origin = o
-   ​ +  
-   ​public int getArea() {+   
 +  public ​Point getOrigin() { 
 +    return ​origin
 +  
 +   
 +  public int getArea() {
        ​return width * height;        ​return width * height;
-   } +  }
-    +
-   // Move rectangle origin by x,y +
-   ​public void move(int x, int y) { +
-       ​origin.setX( origin.getX() + x ); +
-       ​origin.setY( origin.getY() + y ); +
-   }+
        
 +  // Move rectangle origin by x,y
 +  public void move(int dx, int dy) {
 +    origin.setX( origin.getX() + dx );
 +    origin.setY( origin.getY() + dy );
 +  }
 } }
 </​code>​ </​code>​
Line 88: Line 97:
         // Declare and create a point object and two rectangle objects.         // Declare and create a point object and two rectangle objects.
         Point originOne = new Point(23, 94);         Point originOne = new Point(23, 94);
-        Rectangle rectOne = new Rectangle(originOne, ​100, 200);+        Rectangle rectOne = new Rectangle(100,​ 200, originOne);
         Rectangle rectTwo = new Rectangle(50,​ 100);         Rectangle rectTwo = new Rectangle(50,​ 100);
   
Line 138: Line 147:
  
 Από τα πάραπάνω αξίζει να προσέξουμε τα εξής. Από τα πάραπάνω αξίζει να προσέξουμε τα εξής.
-  - Εκτελούμε την κλάση η οποία περιέχει την μέθοδο <​code>​public static void main(String[] args) { .... } </​code>​+  - Εκτελούμε την κλάση η οποία περιέχει την μέθοδο ​**main** η οποία εκκινεί την εκτέλεση του προγράμματος ​<​code>​public static void main(String[] args) { .... } </​code>​
   - Η κλάση Rectangle έχει δύο κατασκευαστές οι οποίοι καλούνται εναλλάξ στη συνάρτηση **main** προκειμένου να αρχικοποιήσουν τα αντικείμενα (**objects**) ''​rectOne''​ και ''​rectTwo''​.   - Η κλάση Rectangle έχει δύο κατασκευαστές οι οποίοι καλούνται εναλλάξ στη συνάρτηση **main** προκειμένου να αρχικοποιήσουν τα αντικείμενα (**objects**) ''​rectOne''​ και ''​rectTwo''​.
   - H συνάρτηση ''​System.out.println()''​ εκτυπώνει ένα αλφαριθμητικό (string) ακολουθούμενο από χαρακτήρα αλλαγής γραμμής.   - H συνάρτηση ''​System.out.println()''​ εκτυπώνει ένα αλφαριθμητικό (string) ακολουθούμενο από χαρακτήρα αλλαγής γραμμής.
  
-===== Δήλωση Reference μεταβλητών και δημιουργία αντικειμένων ====== +|Προηγούμενο:​ [[:​java:​class_methods | Μέθοδοι της Κλάσης ]] | Επόμενο:​ [[:​java:​this_operator | O τελεστής this ]]|
- +
-Στο παραπάνω πρόγραμμα ορίζονται στη συνάρτηση ''​main''​ τα εξής +
-<code java> +
-Point originOne = new Point(23, 94); +
-Rectangle rectOne = new Rectangle(originOne,​ 100, 200); +
-Rectangle rectTwo = new Rectangle(50,​ 100); +
-</​code>​ +
- +
-Τα παραπάνω μπορούν να γραφούν αναλυτικότερα ως εξής. +
-<code java> +
-Point originOne;​ +
-Rectangle rectOne, rectTwo;  +
- +
-originOne = new Point(23, 94); +
-rectOne = new Rectangle(originOne,​ 100, 200); +
-rectTwo = new Rectangle(50,​ 100); +
-</​code>​ +
- +
-Οι πρώτες δύο γραμμές ορίζουν τις μεταλητές ''​originOne'',​ ''​rectOne'',​ ''​rectTwo''​. Οι μεταβλητές δυνητικά δείχνουν σε τύπους δεδομένων Point, Rectange, Rectangle. Προς το παρόν όμως το περιεχόμενο των μεταβλητών αυτών είναι απροσδιόριστο (undefined). Σε αναλογία με την γλώσσα C φανταστείτε τις μεταβλητές αυτές ως pointers που δεν είναι αρχικοποιημένοι σε κάποια υφιστάμενη διεύθυνση μνήμης. Η τιμή τους είναι απροσδιόριστη και η προσπάθεια να γράψουμε στη διεύθυνση μνήμης που δείχνουν θα προκαλάσει Segmentation Fault. Η παρακάτω εικόνα δείχνει την ύπαρξη ενός μη αρχικοποιημένου δείκτη. +
- +
-{{ :​java:​reference-variables-01.png |}} +
- +
-Προκειμένου να αρχικοποιηθούν οι μεταβλητές αυτές απαιτούνται δύο βήματα:​ +
-  - Η δέσμευση της απαραίτητης μνήμης,​ ώστε να μπορούμε να αποθηκεύσουμε τα δεδομένα που προδιαγράφονται απο τον συγκεκριμένο τύπο (κλάση). +
-  - Η αρχικοποίηση των επιμέρους μεταβλητών των αντικειμένων που ορίζονται απο την εκάστοτε κλάση. +
- +
-Η παρακάτω εικόνα δείχνει τον δείκτη μετά την δέσμευση της απαιτούμενης μνήμης και την αρχικοποίηση των δεδομένων (μεταβλητών) του αντικειμένου ''​originOne''​. +
- +
-{{ :​java:​reference-variables-02.png ?400 |}} +
- +
-Ο παρακάτω κώδικας +
- +
-<code java>​rectOne = new Rectangle(originOne,​ 100, 200);</​code>​  +
- +
-δηλώνει την δέσμευση μνήμης για ένα αντικείμενο τύπου ''​Rectangle''​ όπου το σημείο της αρχής του είναι το σημείο ''​originOne''​. Επίσης ορίζονται οι τιμές των **width** και **height** σε 100 και 200 αντίστοιχα. O παραπάνω ορισμός σημαίνει ένα αρχικοποιημένο αντικείμενο μπορεί να έχει πολλούς δείκτες προς αυτό, όπως δείχνει το παρακάτω σχήμα. +
- +
-{{ :​java:​reference-variables-03.png ?500 | }} +
- +
-===== Ο τελεστής new ===== +
- +
-Προκειμένου να δημιουργηθούν νέα αντικείμενα χρησιμοποιείται ο τελεστής **new**. O τελεστής **new** χρησιμοποιείται συνήθως με τον κατασκευαστή μίας κλάσης προκειμένου να κάνει τα εξής: +
-  - Δέσμευση της απαραίτητης μνήμης και δημιουργία του αντικειμένου. Η αρχικά ορισμένη μεταβλητή δείχνει πλέον στην περιοχή μνήμης που έχει δεσμευτεί. +
-  - Αρχικοποίηση των εσωτερικών μεταβλητών (πεδίων) του αντικειμένου με κλήση του κατάλληλου κατασκευαστή της κλάσης. Εάν δεν έχει οριστεί κατασκευαστής τότε ο τελεστής new καλείται με χρήση του default κατασκευαστή (default constructor) που δεν έχει ορίσματα (π.χ. ''​MyObject obj = new MyObject();'',​ όπου για την κλάση ''​MyObject''​ δεν έχει οριστεί κανένας κατασκευατής). +
- +
-<WRAP tip> +
-Κατά την χρήση **primitive** τύπων δεδομένων (int, float, double) δεν απαιτείται η χρήση του τελεστή **new** διότι η απαραίτητη μνήμη δεσμεύεται στο stack της μεθόδου που εκτελείται.  +
-</​WRAP>​ +
- +
-===== Πολλαπλοί κατασκευαστές σε μία κλάση ===== +
- +
-Μία κλάση μπορεί να έχει πολλούς διαφορετικούς. Κάθε κατασκευαστής ορίζει μία διαφορετική αρχικοποίηση των εσωτερικών μεταβλητών των αντικειμένων που δημιουργούντια με βάση το "​σχέδιο"​ της κλάσης. Το ποιός κατασκευαστής θα κληθεί εξαρτάται από τον τύπο, τη σειρά και τον αριθμό των ορισμάτων σε αναλογία με την υπερφόρτωση συναρτήσεων. Έτσι στη συνάρτηση main του παραδείγματος μας καλούνται δύο διαφορετικοί κατασκευαστές για δύο διαφορετικά αντικείμενα της ίδιας κλάσης. +
- +
-<code java> +
-rectOne = new Rectangle(originOne,​ 100, 200); +
-rectTwo = new Rectangle(50,​ 100); +
-</​code>​ +
- +
-===== Χρήση Αντικειμένων ===== +
- +
-Όταν φτιάξετε ένα αντικείμενο είναι σίγουρο ότι θα θέλετε να το χρησιμοποιήσετε προκειμένου να κάνετε μία εργασία όπως να γράψετε κάτι στα δεδομένα του, να διαβάσετε από αυτά ή να χρησιμοποιήσετε κάποια από τις μεθόδους του. +
- +
-==== Χρήση των πεδίων ενός αντικειμένου ==== +
- +
-Τα πεδία ενός αντικειμένου είναι προσβάσιμα με χρήση του ονόματος του αντικειμένου,​ μία τελεία '​.'​ και το όνομα του πεδίου. Για παράδειγμα,​ +
- +
-<code java> +
-                          // cadence, speed, gear +
-   ​Bicycle bicycle = new Bicycle(10, 20, 30); +
-   ​System.out.println("​Bicycle speed is " + bicycle.speed);​ +
-</​code>​ +
- +
-<WRAP important>​ +
-Απαραίτητη προϋπόθεση για να δουλέψει ο παραπάνω κώδικας είναι το πεδίο speed να είναι προσβάσιμο,​ δηλαδή να μην έχει προσδιοριστή τύπου **private**. +
-</​WRAP>​ +
- +
-<WRAP tip> +
-Όπως προείπαμε μία καλή προγραμματιστική πρακτική είναι η απόκρυψη των πεδίων κάθε κλάσης και η δήλωση συναρτήσεων για την πρόσβαση στα δεδομένα της. Σε αυτή την περίπτωση η πρόσβαση στα πεδία των αντικειμένων είναι μη επιτρεπτή (ο compiler δεν μεταγλωττίζει το πρόγραμμα). +
-</​WRAP>​ +
- +
-==== Χρήση των μεθόδων ενός αντικειμένου ==== +
- +
-Σε αναλογία με τα πεδία οι μέθοδοι ενός αντικειμένου είναι προσβάσιμες μέσω του ονόματος του αντικειμένου,​ μία τελεία '​.'​ και το όνομα του πεδίου. Για παράδειγμα,​  +
- +
-<code java> +
-                          // cadence, speed, gear +
-   ​Bicycle bicycle = new Bicycle(10, 20, 30); +
-   ​System.out.println("​Bicycle speed is " + bicycle.getSpeed() ); +
-</​code>​ +
- +
-<WRAP important>​ +
-Ισχύουν και για τις μεθόδους όσα αναφέρονται για τους προσδιοριστές τύπου **public**, **private** των πεδίων. +
-</​WRAP>​ +
- +
-===== Garbage Collection ===== +
- +
-Οι γλώσσες υψηλού επιπέδου που μέχρι τώρα έχετε γνωρίσει (**C**) αναθέτουν την ευθύνη δέσμευση μνήμης στον προγραμματιστή μέσω των συναρτήσεων **malloc()** και **free()**. Σε αντιδιαστολή,​ η **JAVA** αφήνει τον προγραμματιστεί να ορίσει όσα αντικείμενα επιθυμεί και δεσμεύει την μνήμη για αυτά μέσω του τελεστή **new**. +
- +
-Περιοδικά το **JVM** κοιτάει εάν υπάρχουν αντικείμενα για τα οποία δεν υπάρχουν πλέον μεταβλητές που δείχνουν σε αυτά. Σε αυτές τις περιπτώσεις ελευθερώνει την μνήμη που έχει δεσμευτεί για τα αντικείμενα που εντόπισε. Ο μηχανισμός αυτός ονομάζεται **Garbage Collection** και απαντάται σε αρκετές γλώσσες υψηλού επιπέδου απελευθερώνοντας τον προγραμματιστή από την ευθύνη αποδέσμευσης της μνήμης που δεσμέυτηκε. +
- +
-Περισσότερα για την λειτουργία του Garbage Collector μπορείτε να βρείτε [[http://​www.oracle.com/​webfolder/​technetwork/​tutorials/​obe/​java/​gc01/​index.html|εδώ]]. +
- +
- +
-|Προηγούμενο:​ [[:​java:​class_methods | Μέθοδοι της Κλάσης ]] | Επόμενο:​ [[:​java:​this_operator | Oι τελεστές this και super ]]|+
  
  
java/objects.txt · Last modified: 2018/02/16 16:03 by gthanos