User Tools

Site Tools


java:member_initialization

Αρχικοποίηση των μελών της κλάσης

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

public class BedAndBreakfast {
 
    // initialize to 10
    public static int capacity = 10;
 
    // initialize to false
    private boolean full = false;
}

Η παραπάνω μέθοδος αφορά στατικά (static) και μη στατικά πεδία, προϋποθέτει όμως ότι η ανάθεση της τιμής μπορεί αν γίνει μόνο με μία εντολή (όπως παραπάνω). Πιο σύνθετες μέθοδοι ανάθεσης (π.χ. αρχικοποίηση πινάκων) μπορούν να γίνουν μέσα στους κατασκευαστές τις κλάσης για τα μη στατικά πεδία. Η αρχικοποίηση στατικών πεδίων δεν έχει νόημα να γίνεται μέσα στους κατασκευαστές.

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

  • για στατικά πεδία
    • static initialization blocks.
    • static methods (στατικές μέθοδοι).
  • για μη-στατικά πεδία
    • initialization blocks (non-static).
    • final methods

Αρχικοποιώντας στατικά πεδία

Static Initialization Blocks

To static initialization block είναι ένα τμήμα κώδικα τοποθετημένο μέσα σε άγκιστρα { } που προσδιορίζεται από τη λέξη static, όπως παρακάτω:

static {
...
}

Κάθε κλάση μπορεί να έχει περισσότερα από ένα static initialization blocks, τα οποία μπορεί να βρίσκονται οπουδήποτε μέσα στο σώμα της. Τα block αυτά καλούνται κατά την αρχικοποίηση της κλάσης με τη σειρά που εμφανίζονται στο σώμα της.

Στατικές Μέθοδοι

Εναλλακτικά των static initialization blocks μπορούν να χρησιμοποιηθούν στατικές μέθοδοι, όπως παρακάτω

class MyClass {
    public static varType myVar = initializeClassVariable();
 
    private static varType initializeClassVariable() {
 
        // initialization code goes here
    }
}

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

Αρχικοποιώντας μη-στατικά πεδία

Initialization Blocks

Τα initialization blocks ομοιάζουν με τα static initialization blocks με την διαφορά ότι δεν περιέχουν το keyword static. Και αυτά καλούνται με την σειρά που εμφανίζονται στο σώμα της κλάσης με την διαφορά ότι καλούνται μέσα σε κάθε κατασκευαστή της κλάσης, όποτε αυτός εκτελείται. Τα initialization blocks μπορούν να χρησιμοποιηθούν για να διαμοιραστεί κώδικας μεταξύ διαφορετικών κατασκευαστών (εναλλακτικά μπορείτε να χρησιμοποιήσετε μία βοηθητική συνάρτηση).

Final Methods

Παρακάτω δίνεται ένα παράδειγμα χρήσης final μεθόδου για την αρχικοποίηση ενός μη στατικού πεδίου. Μία final μέθοδος δεν μπορεί να γίνει override από μία άλλη μέθοδο με το ίδιο prototype κατά την διαδικασία της κληρονομικότητας (θα το δούμε παρακάτω, όταν θα εξετάσουμε σε βάθος την ιδιότητα της κληρονομικότητας).

class Whatever {
    private varType myVar = initializeInstanceVariable();
 
    protected final varType initializeInstanceVariable() {
 
        // initialization code goes here
    }
}

Προφανώς οποιαδήποτε final μέθοδος μπορεί να επαναχρησιμοποιηθεί και σε άλλα σημεία του κώδικα της κλάσης. Η χρήση final μεθόδου κρίνεται απαραίτητη για την αρχικοποίηση μη στατικών πεδίων, διότι σε περίπτωση ύπαρξης υποκλάσεων της κλάσης (μέσω της ιδιότητας της κληρονομικότητας) η μέθοδος μπορεί να οριστεί ξανά στις υποκλάσεις αυτές πράγμα που θα μεταβάλλει τον υφιστάμενο κώδικα αρχικοποίησης.

Παράδειγμα αρχικοποίησης στατικών και μη στατικών πεδίων

Rectangle.java
class Rectangle {
 
  // the Rectangle class has 3 fields
  int width;
  int height;
  Point origin;
 
  int id = initializeId();
 
  // add a class variable for the
  // number of Rectangle objects instantiated
  static int numberOfRectangles = initNumberOfRectangles();
 
  Rectangle(int initWidth, int initHeight, Point initOrigin) {
    this(initWidth, initHeight);
    origin = initOrigin;
  }
 
  Rectangle(int initWidth, int initHeight) {
    width = initWidth;
    height = initHeight;
    origin = new Point(0,0);
    id = ++numberOfRectangles;
    System.out.println("Initialized object id in constructor, id:" + id);
  }
 
 
  // static method for initializing static variable.
  static int initNumberOfRectangles() {
    System.out.println("initialize numberOfRectangles in static method");
    return 0;
  }
 
  //static initialization block 
  static {
    System.out.println("initialize numberOfRectangles in static block");
    numberOfRectangles = 0;
  }
 
  //non-static initialization block 
  {
    id = 100;
    System.out.println("initialize objectId in block, id: " + id);
  }
 
  //final method
  final int initializeId() {
    int _id = 200;
    System.out.println("initialize objectId in final method, id: " + _id  );
    return _id;
  }
 
  int getID() {
    return id;
  }
 
  static int getNumberOfRectangles() {
    return numberOfRectangles;
  }
 
  void setWidth(int newWidth ) {
    width = newWidth;
  }
 
  int getWidth() {
    return width;
  }
 
  void setHeight(int newHeight ) {
    height = newHeight;
  }
 
  int getHeight() {
    return height;
  }
 
  void setOrigin(Point newOrigin) {
    origin = newOrigin;
  }
 
  Point getOrigin() {
    return origin;
  }
 
  int getArea() {
       return width * height;
  }
 
  String description(String objName) {
      return "["+objName+"] (id: "+ id +") Width: " + width + ", Height: " + height;
  }
 
  public static void main(String []args) {
    System.out.println("-------------------------------");
    Point p = new Point(10,20);
 
    Rectangle rectOne = new Rectangle(30,40, p);
    System.out.println("-------------------------------");
    System.out.println(rectOne.description("rectOne"));
    System.out.println("Number of Rectangles: " + getNumberOfRectangles() );
  }
}

Το αποτέλεσμα εκτέλεσης του παραπάνω κώδικα είναι το παρακάτω:

$ java Rectangle
initialize numberOfRectangles in static method
initialize numberOfRectangles in static block
-------------------------------
initialize objectId in final method, id: 200
initialize objectId in block, id: 100
Initialized object id in constructor, id:1
-------------------------------
[rectOne] (id: 1) Width: 30, Height: 40
Number of Rectangles: 1

Από τα παραπάνω προκύπτει ότι η σειρά εκτέλεσης μεταξύ στατικών και μη στατικών μεθόδων, μπλοκ και κατασκευαστών είναι η εξής:

  1. Στατικές μέθοδοι
  2. Στατικά μπλοκ
  3. Μη στατικές final μέθοδοι
  4. Μη στατικά μπλοκ
  5. Κατασκευαστές της κλάσης
java/member_initialization.txt · Last modified: 2022/02/24 12:39 (external edit)