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
java:objects [2017/03/01 15:31]
gthanos
java:objects [2018/02/16 16:03] (current)
gthanos
Line 2: Line 2:
  
 Μέχρι τώρα αναφέραμε στην [[ oop:​introduction | "​Εισαγωγή στον Αντικειμενοστραφή Προγραμματισμό"​ ]] ότι η κλάση είναι το βασικό σχέδιο μέσα από το οποίο δημιουργούνται επιμέρους αντικείμενα που φέρουν τα χαρακτηριστικά της κλάσης. Επίσης,​ δείξαμε πως ορίζουμε μία κλάση μέσα από παραδείγματα,​ αλλά δεν δείξαμε πως δημιουργούμε αντικείμενα από τις κλάσεις που ορίσαμε. ​ Μέχρι τώρα αναφέραμε στην [[ oop:​introduction | "​Εισαγωγή στον Αντικειμενοστραφή Προγραμματισμό"​ ]] ότι η κλάση είναι το βασικό σχέδιο μέσα από το οποίο δημιουργούνται επιμέρους αντικείμενα που φέρουν τα χαρακτηριστικά της κλάσης. Επίσης,​ δείξαμε πως ορίζουμε μία κλάση μέσα από παραδείγματα,​ αλλά δεν δείξαμε πως δημιουργούμε αντικείμενα από τις κλάσεις που ορίσαμε. ​
 +
 +Η δημιουργία αντικειμένων γίνεται με χρήση του τελεστή **new**. Για παράδειγμα,​ για να δημιουργήσουμε ένα αντικείμενο της κλάσης **Point** αρκεί να γράψουμε ​
 +
 +<code java>
 +  /* δημιουργεί ένα αντικείμενο τύπου Point 
 +   * με συντεταγμένες 3,5 και το αναθέτει στη
 +   * μεταβλητή p που είναι τύπου Point.
 +   ​*/  ​
 +  Point p;               // (a)
 +  p = new Point(3,​5); ​   // (b)
 +</​code>​
 +
 +Μπορείτε να σκεφτείτε τη μεταβλητή **p** ως ένα δείκτη σε αντικείμενα τύπου **Point**. Αρχικά ο δείκτης είναι μη αρχικοποιημένος δείχνοντας στην τιμή **null**. Στην επόμενη γραμμή καλείται ο κατασκευαστής ο οποίος δημιουργεί ένα αντικείμενο τύπου **Point** με συντεταγμένες 3,5 και αναθέτει το αντικείμενο αυτό στη μεταβλητή **p**. Τα παρακάτω σχήματα απεικονίζουν εποπτικά την διαδικασία.
 +
 +{{ java:​createobject.png }}
 +
 +
 +===== Ένα πιο εκτεταμένο παράδειγμα =====
  
 Παρακάτω δίνεται η κλάση **CreateObjectDemo** που δημιουργεί συγκεκριμένα αντικείμενα του τύπου **Point** και **Rectangle** και εκτυπώνει τα αποτελέσματα στην κονσόλα. Οι κλάσεις **Point** και **Rectangle** δίνονται επίσης παρακάτω:​ Παρακάτω δίνεται η κλάση **CreateObjectDemo** που δημιουργεί συγκεκριμένα αντικείμενα του τύπου **Point** και **Rectangle** και εκτυπώνει τα αποτελέσματα στην κονσόλα. Οι κλάσεις **Point** και **Rectangle** δίνονται επίσης παρακάτω:​
Line 48: Line 66:
   }   }
   ​   ​
-  public Rectangle(int initWidth, int initHeight) {+  public Rectangle(int initWidth, int initHeight, int originX, int originY) {
     width = initWidth;     width = initWidth;
     height = initHeight;     height = initHeight;
-    origin = null;+    origin = new Point(originX,​originY);
   }   }
     ​     ​
Line 84: Line 102:
        
   // Move rectangle origin by dx,dy   // Move rectangle origin by dx,dy
-  public void move(int dx, int dy) {+  public void moveOrigin(int dx, int dy) {
     origin.setX( origin.getX() + dx );     origin.setX( origin.getX() + dx );
     origin.setY( origin.getY() + dy );     origin.setY( origin.getY() + dy );
Line 94: Line 112:
 public class CreateObjectDemo { public class CreateObjectDemo {
  
-    ​public static void main(String[] args) { +  ​public static void main(String[] args) { 
-  +   ​ 
-        // Declare ​and create a point object and two rectangle objects. +    // Declare ​variables 
-        Point originOne = new Point(23, 94); +    Point originOne, originTwo;​ 
-        ​Rectangle ​rectOne = new Rectangle(100,​ 200, originOne);​ +    Rectangle rectOne, rectTwo; 
-        ​Rectangle ​rectTwo = new Rectangle(50,​ 100); +    // Create objects 
-  +    ​originOne = new Point(23, 94); 
-        // display rectOne'​s width, height, and area +    ​originTwo = new Point(15, -33); 
-        System.out.println("​Width of rectOne: " + rectOne.getWidth() ); +    ​rectOne = new Rectangle(100,​ 200, originOne);​ 
-        System.out.println("Height of rectOne: " + rectOne.getHeight() ); +    rectTwo = new Rectangle(50,​ 100, originTwo); 
-        System.out.println("​Area of rectOne: " + rectOne.getArea()); +     
-  +    // display rectOne'​s width, height, and area 
-        // set rectTwo'​s position +    System.out.println("​[rectOne]  xPos: " + rectOne.getOrigin().getX() + ", yPos: " + rectOne.getOrigin().getY()); 
-        rectTwo.setOrigin(originOne);​ +    System.out.println("​[rectOne]  width: " + rectOne.getWidth() + ", height: " + rectOne.getHeight()); 
-  +     
-        ​// display rectTwo'​s position +    // set rectTwo'​s position 
-        System.out.println("​X Position of rectTwo: " + rectTwo.getOrigin().getX()); +    rectTwo.setOrigin(originOne); ​    
-        System.out.println("Y Position of rectTwo: " + rectTwo.getOrigin().getY());​ +    // display rectTwo'​s position 
-  +    System.out.println("​[rectTwo]  xPos: " + rectTwo.getOrigin().getX() ​", yPos: " + rectTwo.getOrigin().getY());​ 
-        // move rectTwo and display its new position +     
-        rectTwo.move(40, -20); +    // move rectTwo and display its new position 
-        System.out.println("​X Position of rectTwo: " + rectTwo.getOrigin().getX());​ +    rectTwo.moveOrigin(40, -20); 
-        System.out.println("​Y Position of rectTwo: " + rectTwo.getOrigin().getY());​ +    System.out.println("​[rectTwo]  xPos: " + rectTwo.getOrigin().getX() + ", yPos: " + rectTwo.getOrigin().getY()); 
-    }+     
 +    // display rectOne'​s position 
 +    ​System.out.println("​[rectOne] ​ xPos: " + rectOne.getOrigin().getX()+",​ yPos: " + rectOne.getOrigin().getY());​ 
 + 
 +    ​// assign originOne value to originTwo 
 +    originTwo = originOne;​ 
 +  ​}
 } }
 </​code>​ </​code>​
  
-Για να μεταγλωτίσουμε τα παραπάνω πρόγραμμα αρκεί να γράψουμε+Αποθηκεύστε και τα τρία αρχεία στον ίδιο κατάλογο. ​Για να μεταγλωττίσετε τα παραπάνω πρόγραμμα αρκεί να γράψετε
  
 <​code>​ <​code>​
Line 129: Line 153:
 </​code>​ </​code>​
  
-και για να το τρέξουμε γράφουμε+Για να το τρέξετε γράφετε
  
 <​code>​ <​code>​
Line 138: Line 162:
  
 <​code>​ <​code>​
-Width of rectOne: ​100 +[rectOne]  xPos23, yPos: 94 
-Height of rectOne: 200 +[rectOne] width: 100, height: 200 
-Area of rectOne: 20000 +[rectTwo]  xPos: 23, yPos: 94                                                                                                                                                                 
-X Position of rectTwo: 23 +[rectTwo]  xPos: 63, yPos: 74                                                                                                                                                                ​ 
-Y Position of rectTwo: 94 +[rectOne] ​ xPos: 63, yPos: 74  
-X Position of rectTwo: 63 +
-Y Position of rectTwo: 74+
 </​code>​ </​code>​
  
-Από τα παραπάνω αξίζει να προσέξουμε τα εξής. +==== Επεξήγηση του παραπάνω κώδικα ​=====
-  - Εκτελούμε την κλάση η οποία περιέχει την μέθοδο **main** η οποία εκκινεί την εκτέλεση του προγράμματος <​code>​public static void main(String[] args) { .... } </​code>​ +
-  - Η κλάση Rectangle έχει δύο κατασκευαστές οι οποίοι καλούνται εναλλάξ στη συνάρτηση **main** προκειμένου να αρχικοποιήσουν τα αντικείμενα (**objects**) ''​rectOne''​ και ''​rectTwo''​. +
-  - Κάθε κατασκευαστής φροντίζει να αρχικοποιεί όλα τα πεδία, ακόμη και αυτά για τα οποία δεν υπάρχει αντίστοιχη παράμετρος. +
-  - H συνάρτηση ''​System.out.println()''​ εκτυπώνει ένα αλφαριθμητικό (string) ​ακολουθούμενο από χαρακτήρα αλλαγής γραμμής.+
  
-===== Δήλωση Reference μεταβλητών και δημιουργία αντικειμένων ====== +Στο παραπάνω πρόγραμμα ορίζονται στη ​μέθοδο ​''​main''​ τα εξής
- +
-Στο παραπάνω πρόγραμμα ορίζονται στη ​συνάρτηση ​''​main''​ τα εξής+
 <code java> <code java>
-Point originOne = new Point(23, 94); +    // Declare variables 
-Rectangle ​rectOne = new Rectangle(100,​ 200, originOne);​ +    ​Point originOne, originTwo;​ 
-Rectangle ​rectTwo = new Rectangle(50,​ 100);+    Rectangle rectOne, rectTwo; 
 +    // Create objects 
 +    ​originOne = new Point(23, 94); 
 +    ​originTwo = new Point(15, -33); 
 +    ​rectOne = new Rectangle(100,​ 200, originOne);​ 
 +    rectTwo = new Rectangle(50,​ 100, originTwo);
 </​code>​ </​code>​
  
-Τα παραπάνω μπορούν να γραφούν αναλυτικότερα ως εξής. +Οι πρώτες δύο γραμμές ορίζουν τις μεταβλητές ''​originOne'',​ ''​originTwo'',''​rectOne''​ και ''​rectTwo''​. Οι μεταβλητές δυνητικά δείχνουν σε τύπους δεδομένων **Point** και **Rectangle**. Προς το παρόν όμως το περιεχόμενο των μεταβλητών αυτών είναι απροσδιόριστο (στην πραγματικότητα ο compiler αρχικοποιεί τις μεταβλητές αυτές στην τιμή **null**)
-<code java> +
-Point originOne;​ +
-Rectangle rectOne, rectTwo; ​+
  
-originOne = new Point(23, 94); +<WRAP tip 80% center round> 
-rectOne = new Rectangle(100,​ 200, originOne); +__Σε αναλογία με την γλώσσα C__φανταστείτε τις μεταβλητές αυτές ως pointers που δεν είναι αρχικοποιημένοι σε κάποια υφιστάμενη διεύθυνση μνήμης. Η τιμή τους είναι απροσδιόριστη και η προσπάθεια να γράψουμε στη διεύθυνση μνήμης όπου δείχνουν θα προκαλέσει τερματισμό του προγράμματος από το λειτουργικό σύστημα. 
-rectTwo = new Rectangle(50100); +</WRAP>
-</code>+
  
-Οι πρώτες δύο γραμμές ορίζουν τις μεταλητές ''​originOne'',​ ''​rectOne'',​ ''​rectTwo''​. Οι μεταβλητές δυνητικά δείχνουν σε τύπους δεδομένων Point, Rectangle, Rectangle. Προς το παρόν όμως ​το περιεχόμενο των μεταβλητών αυτών είναι απροσδιόριστο (στην πραγματικότητα ​ο compiler ​αρχικοποεί τις μεταβλητές αυτές ​στην τιμή **null**)+Η παρακάτω εικόνα ​δείχνει την ύπαρξη των τεσσάρων μη αρχικοποιημένων δεικτών. Όλοι αρχικά δείχνουν στην τιμή **null**.
  
-//__Σε αναλογία με την γλώσσα C__, φανταστείτε τις μεταβλητές αυτές ως pointers που δεν είναι αρχικοποιημένοι σε κάποια υφιστάμενη διεύθυνση μνήμηςΗ τιμή τους είναι απροσδιόριστη και η προσπάθεια να γράψουμε στη διεύθυνση μνήμης όπου δείχνουν θα προκαλέσει Segmentation Fault.// ​+{{:​java:​createobjectdemoreference1.png|}}
  
-Η παρακάτω εικόνα ​δείχνει την ​ύπαρξη ενός μη αρχικοποιημένου ​δείκτη.+Αμέσως μετά τις δηλώσεις των μεταβλητών ​ακολουθούν οι κλήσεις ​των κατασκευαστών των αντίστοιχων ​κλάσεων. Όπως προαναφέραμε,​ ο κατασκευαστής ​όταν καλείται δεσμεύει την ​απαραίτητη μνήμη για το αντικείμενο,  ​αρχικοποιεί τα πεδία του αντικειμένου ​και ​επιστρέφει μία αναφορά προς ​το αντικείμενο που δημιούργησε.
  
-{{ :​java:​reference-variables-01.png |}}+Η παρακάτω εικόνα δείχνει τις μεταβλητές ''​originOne'',​ ''​originTwo'',​ ''​rectOne'',​ ''​rectTwo''​ μετά την αρχικοποίηση τους από τους αντίστοιχους κατασκευαστές.
  
-Προκειμένου να αρχικοποιηθούν οι μεταβλητές αυτές απαιτούνται δύο βήματα: +{{:java:​createobjectdemoreference2.png|}}
-  - Η δέσμευση της απαραίτητης μνήμης,​ ώστε να μπορούμε να αποθηκεύσουμε τα δεδομένα που προδιαγράφονται από τον συγκεκριμένο τύπο (κλάση). +
-  - Η αρχικοποίηση των επιμέρους μεταβλητών των αντικειμένων που ορίζονται απο την εκάστοτε κλάση.+
  
-Η παρακάτω εικόνα δείχνει τον δείκτη μετά την δέσμευση της ​απαιτούμενης μνήμης και την αρχικοποίηση των δεδομένων (μεταβλητών) του αντικειμένου ''​originOne''​.+Στη συνέχεια ακολουθούν οι εξής γραμμές κώδικα:
  
-{{ :java:reference-variables-02.png ?400 |}}+<​code ​java
 +    // set rectTwo'​s position 
 +    rectTwo.setOrigin(originOne); ​    
 +    // display rectTwo'​s position 
 +    System.out.println("​[rectTwo] ​ xPos" + rectTwo.getOrigin().getX() + ", yPos: " + rectTwo.getOrigin().getY());​ 
 +  
 +    // move rectTwo and display its new position 
 +    rectTwo.moveOrigin(40, ​-20); 
 +    System.out.println("​[rectTwo] ​ xPos: " + rectTwo.getOrigin().getX() + ", yPos: " + rectTwo.getOrigin().getY());​ 
 +  
 +    // display rectOne'​s position 
 +    System.out.println("​[rectOne] ​ xPos: " + rectOne.getOrigin().getX()+",​ yPos: " + rectOne.getOrigin().getY()); 
 +</​code>​
  
-Ο παρακάτω κώδικας+Στις γραμμές αυτές συμβαίνουν τα εξής: 
 +    - Το αντικείμενο ''​rectTwo''​ επιλέγει ως πεδίο origin to ''​originOne''​. Στη συνέχεια,​ μέσω του ''​rectTwo''​ μεταβάλλονται οι συντεταγμένες του αντικειμένου ''​originOne''​. 
 +    - Εκτυπώνονται οι αλλαγές για το ''​rectTwo''​ στην ​κονσόλα
 +    - Εκτυπώνονται οι αλλαγές για το ''​rectOne''​ στην κονσόλα. Παρατηρούμε ότι οι συντεταγμένες του πεδίου **origin** άλλαξαν και για το αντικείμενο ''​rectOne''​.
  
-<code java>​rectOne = new Rectangle(100200, originOne);</​code> ​+Tα παρακάτω δύο σχήματα αποτυπώνουν α) την αλλαγή του πεδίου **origin** του ''​rectTwo''​ώστε να δείχνει στο αντικείμενο ''​rectOne''​ και βτην αλλαγή των περιεχομένων του ''​originOne''​ μέσω του αντικειμένου ''​rectTwo''​. Οι αλλαγές αυτές επηρεάζουν και το πεδίο **origin** του ''​rectOne''​ που δείχνει στο κοινό αντικείμενο ''​origineOne''​.
  
-δηλώνει ​την δέσμευση μνήμης για ένα αντικείμενο ​τύπου ''​Rectangle'' ​όπου το σημείο της αρχής του είναι το σημείο ​''​originOne''​. Επίσης ορίζονται οι τιμές των **width** και **height** σε 100 και 200 αντίστοιχα. O παραπάνω ορισμός σημαίνει ένα αρχικοποιημένο αντικείμενο ​μπορεί να έχει πολλούς δείκτες ​προς αυτό, όπως δείχνει το παρακάτω σχήμα.+Παρατηρείστε ​ότι πλέον μόνο η μεταβλητή ''​originTwo'' ​δείχνει στο αντικείμενο ​τύπου ​**Point** με συντεταγμένες 15, -33.
  
-{{ :java:reference-variables-03.png ?500 | }}+|  **(a)** ​ | |  **(b)** ​ | 
 +{{:java:createobjectdemoreference3.png|}} ​|  |{{:​java:​createobjectdemoreference4.png|}} |
  
-===== Ο τελεστής new =====+Τέλος το πρόγραμμα τελειώνει με την γραμμή κώδικα:​ 
 +<code java> 
 +    // assign originOne value to originTwo 
 +    originTwo ​originOne;​ 
 +</​code>​ 
 + 
 +Μετά την γραμμή αυτή η μεταβλητή ''​originTwo''​ δείχνει στο αντικείμενο που δείχνει και η μεταβλητή ''​originOne''​. Πλέον δεν υπάρχει καμία μεταβλητή ή αναφορά που να δείχνει στο αντικείμενο τύπου **Point** με συντεταγμένες 15, -33. Το αντικείμενο αυτό θα διαγραφεί αυτόματα από την λειτουργία **[[#​garbage_collection|Garbage Collection]]** του JVM. 
 + 
 +{{:​java:​createobjectdemoreference5.png|}} 
 +===== Επεξήγηση της χρήσης του ​τελεστή new =====
  
 Προκειμένου να δημιουργηθούν νέα αντικείμενα χρησιμοποιείται ο τελεστής **new**. O τελεστής **new** χρησιμοποιείται συνήθως με τον κατασκευαστή μίας κλάσης προκειμένου να κάνει τα εξής: Προκειμένου να δημιουργηθούν νέα αντικείμενα χρησιμοποιείται ο τελεστής **new**. O τελεστής **new** χρησιμοποιείται συνήθως με τον κατασκευαστή μίας κλάσης προκειμένου να κάνει τα εξής:
   - Δέσμευση της απαραίτητης μνήμης και δημιουργία του αντικειμένου. Η αρχικά ορισμένη μεταβλητή δείχνει πλέον στην περιοχή μνήμης που έχει δεσμευτεί.   - Δέσμευση της απαραίτητης μνήμης και δημιουργία του αντικειμένου. Η αρχικά ορισμένη μεταβλητή δείχνει πλέον στην περιοχή μνήμης που έχει δεσμευτεί.
-  - Αρχικοποίηση των εσωτερικών μεταβλητών (πεδίων) του αντικειμένου με κλήση του κατάλληλου κατασκευαστή της κλάσης. Εάν δεν έχει οριστεί κατασκευαστής τότε ο τελεστής new καλείται με χρήση του default κατασκευαστή (default constructor) που δεν έχει ορίσματα (π.χ. ''​MyObject obj = new MyObject();'',​ όπου για την κλάση ''​MyObject''​ δεν έχει οριστεί κανένας κατασκευατής).+  - Αρχικοποίηση των εσωτερικών μεταβλητών (πεδίων) του αντικειμένου με κλήση του κατάλληλου κατασκευαστή της κλάσης. Εάν δεν έχει οριστεί κατασκευαστής τότε ο τελεστής ​**new** καλείται με χρήση του default κατασκευαστή (default constructor) που δεν έχει ορίσματα (π.χ. ''​MyObject obj = new MyObject();'',​ όπου για την κλάση ''​MyObject''​ δεν έχει οριστεί κανένας κατασκευατής).
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Κατά την χρήση **primitive** τύπων δεδομένων (int, float, double) δεν απαιτείται η χρήση του τελεστή **new** ​διότι ​η απαραίτητη μνήμη ​δεσμεύεται στο stack της μεθόδου που εκτελείται. ​+Κατά την χρήση **primitive** τύπων δεδομένων ​σε ένα πρόγραμμα ​(int, float, double) δεν απαιτείται η χρήση του τελεστή **new**. Ο λόγος που συμβαίνει αυτό είναι ότι ​για τους συγκεκριμένους τύπους δεδομένων,​ η διαδικασία δέσμευσης της μνήμης είναι ​στατική,​ καθώς είναι γνωστό εκ των προτέρων το εύρος μνήμης που απαιτούν. Οι **primitive** τύποι δεδομένων αποθηκεύονται ​πάντοτε ​στο ​**stack** της μεθόδου ​μέσα στην οποία δηλώνονται. 
 + 
 +Αντίθετα,​ για τα αντικείμενα των κλάσεων ο compiler δεν μπορεί να γνωρίζει εκ των προτέρων το μέγεθος τους, καθώς με την σειρά τους αυτά μπορεί να περιέχουν άλλα αντικείμενα, ​τα οποία με την σειρά τους μπορεί να περιέχουν άλλα αντικείμενα κ.ο.κ. Για ​τον λόγο ​αυτό, για τα αντικείμενα δεσμεύεται πάντοτε η απαραίτητη μνήμη δυναμικά,​ στην περιοχή δυναμικής δέσμευσης μνήμης που παραδοσιακά ονομάζεται **heap**.
 </​WRAP>​ </​WRAP>​
  
 ===== Πολλαπλοί κατασκευαστές σε μία κλάση ===== ===== Πολλαπλοί κατασκευαστές σε μία κλάση =====
  
-Μία κλάση μπορεί να έχει πολλούς διαφορετικούς κατασκευαστές. Κάθε κατασκευαστής ορίζει μία διαφορετική αρχικοποίηση των εσωτερικών μεταβλητών των αντικειμένων που δημιουργούνται με βάση το "​σχέδιο"​ της κλάσης. Το ποιός κατασκευαστής θα κληθεί εξαρτάται από τον τύπο, τη σειρά και τον αριθμό των ορισμάτων σε αναλογία με την υπερφόρτωση μεθόδων. ​Έτσι ​στη ​συνάρτηση ​**main** του παραδείγματος μας ​καλούνται δύο διαφορετικοί κατασκευαστές για δύο διαφορετικά αντικείμενα της ίδιας κλάσης.+Μία κλάση μπορεί να έχει πολλούς διαφορετικούς κατασκευαστές. Κάθε κατασκευαστής ορίζει μία διαφορετική αρχικοποίηση των εσωτερικών μεταβλητών των αντικειμένων που δημιουργούνται με βάση το "​σχέδιο"​ της κλάσης. Το ποιoς κατασκευαστής θα κληθεί εξαρτάται από τον τύπο, τη σειρά και τον αριθμό των ορισμάτων σε αναλογία με την υπερφόρτωση μεθόδων. ​Ας υποθέσουμε ​την ​παρακάτω μέθοδο ​**main**, στην οποία καλούνται δύο διαφορετικοί κατασκευαστές για δύο διαφορετικά αντικείμενα της ίδιας κλάσης ​**Rectangle**. Παρατηρήστε ότι η μεταβλητή **rectOne** αρχικοποιείται από την 1ο κατασκευαστή της κλάσης και η μεταβλητή **rectTwo** από τον 2ο κατασκευαστή.
  
 <code java> <code java>
-rectOne = new Rectangle(100,​ 200, originOne);​ +public class CreateRectangleObjects { 
-rectTwo = new Rectangle(50,​ 100);+  public static void main(String []args) { 
 +    Point originOne = new Point(10,​5);​ 
 +    ​rectOne = new Rectangle(100,​ 200, originOne);​ 
 +    rectTwo = new Rectangle(50,​ 100, -40, 80); 
 +  } 
 +}
 </​code>​ </​code>​
 +
  
 ===== Χρήση Αντικειμένων ===== ===== Χρήση Αντικειμένων =====
Line 225: Line 273:
 <code java> <code java>
    // fields are width, height    // fields are width, height
-   ​Rectangle rect = new Rectangle(10,​20);​+   ​Rectangle rect = new Rectangle(10,​20, -5, 22);
    ​System.out.println("​Rectangle dimensions are " + rect.width + ", " + rect.height);​    ​System.out.println("​Rectangle dimensions are " + rect.width + ", " + rect.height);​
 </​code>​ </​code>​
  
 <WRAP important 80% center round> <WRAP important 80% center round>
-Απαραίτητη προϋπόθεση για να δουλέψει ο παραπάνω κώδικας είναι τα πεδία width και height να είναι προσβάσιμα,​ δηλαδή να ΜΗΝ ​έχουν προσδιοριστή πρόσβασης τύπου **private**.+Απαραίτητη προϋπόθεση για να δουλέψει ο παραπάνω κώδικας είναι τα πεδία width και height να είναι προσβάσιμα,​ δηλαδή να μην ​έχουν προσδιοριστή πρόσβασης τύπου **private**.
 </​WRAP>​ </​WRAP>​
  
Line 239: Line 287:
 ==== Χρήση των μεθόδων ενός αντικειμένου ==== ==== Χρήση των μεθόδων ενός αντικειμένου ====
  
-Σε αναλογία με τα πεδία οι μέθοδοι ενός αντικειμένου είναι προσβάσιμες μέσω του ονόματος του αντικειμένου,​ μία τελεία '​.'​ και το όνομα του πεδίου. Για παράδειγμα, ​+Σε αναλογία με τα πεδία οι μέθοδοι ενός αντικειμένου είναι προσβάσιμες μέσω του ονόματος του αντικειμένου,​ μία τελεία '​.'​ και το όνομα της μεθόδου. Για παράδειγμα, ​
  
 <code java> <code java>
-   // fields are width, height +   ​Rectangle rect = new Rectangle(10,​20, -5, 22);
-   Rectangle rect = new Rectangle(10,​20);​+
    ​System.out.println("​Rectangle dimensions are " + rect.getWidth() + ", " + rect.getHeight() );    ​System.out.println("​Rectangle dimensions are " + rect.getWidth() + ", " + rect.getHeight() );
 </​code>​ </​code>​
Line 253: Line 300:
 ===== Garbage Collection ===== ===== Garbage Collection =====
  
-Η γλώσσα ​**C** που μέχρι τώρα έχετε γνωρίσει αναθέτει την ευθύνη δέσμευσης μνήμης στον προγραμματιστή μέσω των συναρτήσεων **malloc()** και **free()**. Σε αντιδιαστολή,​ η **JAVA** αφήνει τον προγραμματιστεί να ορίσει όσα αντικείμενα επιθυμεί και δεσμεύει την μνήμη για αυτά μέσω του τελεστή **new**.+Οι γλώσσες προγραμματισμού ​που μέχρι τώρα έχετε γνωρίσει ​(βλέπε **C**) ​αναθέτουν ​την ευθύνη δέσμευσης μνήμης στον προγραμματιστή μέσω των συναρτήσεων **malloc()** και **free()**. Σε αντιδιαστολή,​ η **JAVA** αφήνει τον προγραμματιστεί να ορίσει όσα αντικείμενα επιθυμεί και δεσμεύει την μνήμη για αυτά μέσω του τελεστή **new**.
  
-Πώς όμως αποδεσμεύεται η μνήμη που δεσμεύτηκε προηγούμενα από το πρόγραμμα μας, αλλά δεν την χρειαζόμαστε πλέον; ​Αν η μνήμη ​δεν αποδεσμεύεται και το πρόγραμμα μας τρέξει για αρκετή ώρα δεσμεύοντας διαρκώς ​μνήμη, τότε ​είναι σίγουρο ότι θα το τερματίσει ​το λειτουργικό σύστημα. Η απάντηση, όσον ​αφορά την αποδέσμευση μνήμης ​στη Java γίνεται μέσω του μηχανισμού **Garbage Collection** και επεξηγείται εν συντομία παρακάτω.+Πώς όμως αποδεσμεύεται η μνήμη που δεσμεύτηκε προηγούμενα από το πρόγραμμα μας, αλλά δεν την χρειαζόμαστε πλέον; ​Περιοδικά το **JVM** κοιτάει εάν υπάρχει δεσμευμένη μνήμη ​για αντικείμενα ​στα οποία δεν υφίστανται πλέον ​αναφορές/​references που δείχνουν σε αυτά. Σε αυτές τις περιπτώσεις, ελευθερώνεται ​η μνήμη ​που έχει δεσμευτεί για τα αντικείμενα αυτής της κατηγορίαςΠαράλληλα η αποδέσμευση ​της ​μνήμης ​και ​η διαγραφή των αντικειμένων πιθανόν συνεπάγεται ​ότι και άλλα αντικείμενα δεν διαθέτουν πια αναφορές προς αυτά κ.ο.κ. Η διαδικασία συνεχίζεται μέχρι να αποδεσμευτεί όλη η δυναμικά δεσμευμένη μνήμη
  
-Περιοδικά το **JVM** κοιτάει εάν υπάρχει δεσμευμένη μνήμη για αντικείμενα στα οποία δεν υφίστανται πλέον μεταβλητές που δείχνουν σε αυτά, δηλαδή δεν υφίστανται αναφορές (//​references//​) προς αυτά. Σε αυτές τις περιπτώσεις,​ ελευθερώνεται η μνήμη που έχει δεσμευτεί για τα αντικείμενα αυτή της κατηγορίας. Παράλληλα η αποδέσμευση της μνήμης και η διαγραφή των αντικειμένων πιθανόν συνεπάγεται ότι και άλλα αντικείμενα δεν διαθέτουν πια αναφορές προς αυτά κ.ο.κ. Η διαδικασία συνεχίζεται μέχρι να αποδεσμευτεί όλη η δυναμικά δεσμευμένη μνήμη.  +Ο μηχανισμός **Garbage Collection** απαντάται σε αρκετές γλώσσες υψηλού επιπέδου,​ απελευθερώνοντας τον προγραμματιστή από την ευθύνη αποδέσμευσης της μνήμης που δεσμεύτηκε προηγούμενα. Η ευθύνη της ​δεύσμευσης/​αποδέσμευσης μνήμης ​δεν ​επαφίεται στον προγραμματιστή,​ πράγμα που ​κάνει ​λιγότερο επίπονο ​τον προγραμματισμό
- +
-Ο μηχανισμός **Garbage Collection** απαντάται σε αρκετές γλώσσες υψηλού επιπέδου,​ απελευθερώνοντας τον προγραμματιστή από την ευθύνη αποδέσμευσης της μνήμης που δεσμεύτηκε προηγούμενα. Η ευθύνη της αποδέσμευσης μνήμης επαφίεται στο Garbage Collector, πράγμα που κάνει λιγότερο επίπονο ​τον προγραμματισμό.  +
- +
-Φυσικά η δυνατότητα του **Garbage Collection** συνεπάγεται ότι ένα παράλληλο νήμα, τρέχει περιοδικά και ελευθερώνει την μνήμη, πράγμα που ​πιθανόν να εισάγει καθυστερήσεις σε συγκεκριμένες εφαρμογές. Σε προγράμματα ​που απαιτούν πολύ υψηλές επιδόσεις ή έχουν αυστηρούς ​περιορισμούς ως προς τον χρόνο εκτέλεσης τους, η παράλληλη εκτέλεση του Garbage Collector μπορεί να εισάγει ​μη αποδεκτή καθυστέρηση.+
  
 Περισσότερα για την λειτουργία του Garbage Collector και τις εναλλακτικές υλοποιήσεις μπορείτε να βρείτε [[http://​www.oracle.com/​webfolder/​technetwork/​tutorials/​obe/​java/​gc01/​index.html|εδώ]]. Περισσότερα για την λειτουργία του Garbage Collector και τις εναλλακτικές υλοποιήσεις μπορείτε να βρείτε [[http://​www.oracle.com/​webfolder/​technetwork/​tutorials/​obe/​java/​gc01/​index.html|εδώ]].
  
-|Προηγούμενο:​ [[:​java:​class_constructors | Κατασκευαστές της κλάσης ]] |  [[:toc | Περιεχόμενα ]] | Επόμενο:​ [[:java:this_operator ​O τελεστής this ]]| +|Προηγούμενο:​ [[:​java:​class_constructors | Κατασκευαστές της κλάσης ]] |  [[:toc | Περιεχόμενα ]] | Επόμενο:​ [[:java:arrays ​Πίνακες 
- + ]]|
- +
- +
  
java/objects.txt · Last modified: 2018/02/16 16:03 by gthanos