Table of Contents

Κληρονομικότητα

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

Κάθε κλάση που κληρονομεί από μία άλλη κλάση ονομάζεται υποκλάση (subclass) της γονικής κλάσης από την οποία κληρονομεί. Αντίστοιχα, η γονική κλάση ονομάζεται υπερκλάση (superclass) της κληρονομούμενης κλάσης.

Όπως φαίνεται και στο παραπάνω σχήμα μία κλάση (subclass) μπορεί να κληρονομεί ΜΟΝΟ ΜΙΑ άλλη κλάση. Αντίστροφα μία κλάση (superclass) μπορεί να κληρονομείται από πολλές διαφορετικές κλάσεις. Παρακάτω δίνουμε ένα παράδειγμα κληρονομικότητας ως συνέχεια των προηγούμενων ενοτήτων. Ορίζουμε την κλάση BasicRectangle η οποία αποτελεί το απλό ορθογώνιο παραλληλόγραμμο που γνωρίσαμε στην αρχή και την κλάση Rectangle που αποτελεί εξειδίκευση της κλάσης BasicRectangle ορίζοντας επιπλέον το πεδίο origin.

BasicRectangle.java
public class BasicRectangle {
 
  int width;
  int height;
 
  public BasicRectangle(int initWidth, int initHeight) {
    width = initWidth;
    height = initHeight;
  }
 
  public void setWidth(int newWidth ) {
    width = newWidth;
  }
 
  public void setHeight(int newHeight ) {
    height = newHeight;
  }
 
  public int getWidth() {
    return width;
  }
 
  public int getHeight() {
    return height;
  }
 
  public String toString() {
    return "width: "+width+", height: "+height;
  }
}
Point.java
class Point {
  int x;   // x coordinate
  int y;   // y coordinate
 
  public Point(int xPos, int yPos) {
    x = xPos;
    y = yPos;
  }
 
  int getX() {
    return x;
  }
 
  void setX(int xPos) {
    x = xPos;
  }
 
  int getY() {
    return y;
  }
 
  void setY(int yPos) {
    y = yPos;
  }
 
  public String toString() {
    return "("+x+","+y+")";
  }
}
Rectangle.java
public class Rectangle extends BasicRectangle {
 
  Point origin;
 
  public Rectangle(int initWidth, int initHeight, Point initOrigin) {
    super(initWidth, initHeight);
    origin = initOrigin;
  }
 
  public Rectangle(int initWidth, int initHeight, int originX, int originY) {
    super(initWidth, initHeight);
    origin = new Point(originX,originY);
  }
 
  public void setOrigin(Point newOrigin) {
    origin = newOrigin;
  }
 
  public Point getOrigin() {
    return origin;
  }
 
  int area() {
    return width * height;
  }
 
  // Move rectangle origin by dx,dy
  public void moveOrigin(int dx, int dy) {
    origin.setX( origin.getX() + dx );
    origin.setY( origin.getY() + dy );
  }
 
  public String toString() {
    String str = origin.toString() + " ";
    str = str + super.toString();
    return str;
  }
}

Παρατηρήσεις

  • Η κλάση BasicRectangle έχει τα πεδία width, height, ενώ η κλάση Rectangle διαθέτει τα πεδία αυτά και επιπλέον το πεδίο origin.
  • Βασικό χαρακτηριστικό της κληρονομικότητας είναι ότι η κληρονομούμενη κλάση έχει όλα τα χαρακτηριστικά της γονικής κλάσης. Υπό αυτή την έννοια, τα αντικείμενα της κλάσης Rectangle είναι και του τύπου BasicRectangle.
  • Παρατηρήστε τη δεσμευμένη λέξη super ως πρώτη εντολή του κάθε κατασκευαστή. Μέσω της κλήσης super καλείται ο κατασκευαστής της γονικής κλάσης.

Προσβασιμότητα των κληρονομούμενων πεδίων

Μία κλάση η οποία κληρονομεί μία άλλη κλάση έχει πρόσβαση στα μέλη (πεδία και μεθόδους) της κλάσης αυτής ως εξής:

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

Τι μπορούμε να κάνουμε σε μία υποκλάση...

ΔΕΝ συνιστάται να κάνουμε σε μία υποκλάση...