Customize Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorized as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customized advertisements based on the pages you visited previously and to analyze the effectiveness of the ad campaigns.

No cookies to display.

2.3 Η κληρονομικότητα στην Java

Η κληρονομικότητα στην Java αναφέρεται στη δυνατότητα μιας κλάσης να κληρονομεί τα χαρακτηριστικά (μεταβλητές και μεθόδους) μιας άλλης κλάσης. Αυτό σημαίνει ότι μια κλάση μπορεί να αποκτήσει τις ιδιότητες και τη συμπεριφορά της γονικής της κλάσης.

Η κληρονομικότητα υλοποιείται στη Java μέσω της δήλωσης της λέξης-κλειδιού extends στον ορισμό της κλάσης. Μια υποκλάση (ή παράγωγη κλάση) δηλώνεται με τη λέξη-κλειδί extends και το όνομα της γονικής κλάσης. Έτσι, η υποκλάση κληρονομεί τα χαρακτηριστικά της γονικής κλάσης και μπορεί επίσης να προσθέσει τα δικά της μοναδικά χαρακτηριστικά.

Η κληρονομικότητα στην Java επιτρέπει τη δημιουργία ιεραρχικών δομών κλάσεων, όπου οι κλάσεις μπορούν να οργανωθούν σε μια δομή που αντανακλά τις σχέσεις “είναι ένα” (is-a). Αυτό παρέχει τη δυνατότητα επαναχρησιμοποίησης του κώδικα, καθώς οι υποκλάσεις μπορούν να επωφεληθούν από τα ήδη υπάρχοντα χαρακτηριστικά και να προσθέσουν νέες λειτουργίες και συμπεριφορές.

Στο παρακάτω παράδειγμα, η κλάση GPU (υποκλάση) κληρονομεί τα χαρακτηριστικά και τις μεθόδους από την κλάση Workstation (γονική κλάση):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Workstation {
protected String model = "Unknown"; // Το μοντέλο του workstation
public void printModel() {
System.out.println("Model: " + model); // Εκτύπωση του μοντέλου
}
}
class GPU extends Workstation {
private String gpuModel = "Unknown"; // Το μοντέλο της GPU
public void printGPUModel() {
System.out.println("GPU Model: " + gpuModel); // Εκτύπωση του μοντέλου της GPU
}
}
public class Main {
public static void main(String[] args) {
GPU myGPU = new GPU();
myGPU.printModel(); // Κλήση της κληρονομημένης μεθόδου από τη γονική κλάση
myGPU.printGPUModel(); // Κλήση της μεθόδου της υποκλάσης
}
}
class Workstation { protected String model = "Unknown"; // Το μοντέλο του workstation public void printModel() { System.out.println("Model: " + model); // Εκτύπωση του μοντέλου } } class GPU extends Workstation { private String gpuModel = "Unknown"; // Το μοντέλο της GPU public void printGPUModel() { System.out.println("GPU Model: " + gpuModel); // Εκτύπωση του μοντέλου της GPU } } public class Main { public static void main(String[] args) { GPU myGPU = new GPU(); myGPU.printModel(); // Κλήση της κληρονομημένης μεθόδου από τη γονική κλάση myGPU.printGPUModel(); // Κλήση της μεθόδου της υποκλάσης } }
class Workstation {
  protected String model = "Unknown"; // Το μοντέλο του workstation

  public void printModel() {
    System.out.println("Model: " + model); // Εκτύπωση του μοντέλου
  }
}

class GPU extends Workstation {
  private String gpuModel = "Unknown"; // Το μοντέλο της GPU

  public void printGPUModel() {
    System.out.println("GPU Model: " + gpuModel); // Εκτύπωση του μοντέλου της GPU
  }
}

public class Main {
  public static void main(String[] args) {
    GPU myGPU = new GPU();
    myGPU.printModel(); // Κλήση της κληρονομημένης μεθόδου από τη γονική κλάση
    myGPU.printGPUModel(); // Κλήση της μεθόδου της υποκλάσης
  }
}

Ο παραπάνω κώδικας ορίζει τρεις κλάσεις: Workstation, GPU, και Main.

Η κλάση Workstation έχει ένα προστατευμένο πεδίο με την μεταβλητή model, το οποίο αρχικοποιείται με την τιμή “Unknown”. Η κλάση περιέχει μια μέθοδο με το όνομα printModel(), η οποία εκτυπώνει την τιμή του πεδίου model.

Η κλάση GPU κληρονομεί από την κλάση Workstation και διαθέτει ένα ιδιωτικό πεδίο με την μεταβλητή gpuModel, το οποίο αρχικοποιείται επίσης με την τιμή “Unknown”. Η κλάση περιέχει μια μέθοδο με το όνομα printGPUModel(), η οποία εκτυπώνει την τιμή του πεδίου gpuModel.

Η κλάση Main περιέχει τη μέθοδο main, η οποία είναι η εκκίνηση του προγράμματος. Μέσα σε αυτήν τη μέθοδο, δημιουργείται ένα αντικείμενο της κλάσης GPU με το όνομα myGPU. Στη συνέχεια, καλούνται οι μέθοδοι printModel() και printGPUModel() για να εκτυπωθούν τα μοντέλα του myGPU.

Έτσι, ο κώδικας εκτυπώνει στην οθόνη το μοντέλο του myGPU, που παίρνει από την κλάση Workstation, καθώς και το μοντέλο της GPU, που ορίζεται στην κλάση GPU.

Η κληρονομικότητα επιτρέπει σε μια υποκλάση να αποκτήσει τα χαρακτηριστικά και τις μεθόδους της γονικής κλάσης και, ταυτόχρονα, να προσθέσει τα δικά της χαρακτηριστικά και μεθόδους. Με αυτόν τον τρόπο, μπορούμε να αποφύγουμε την επανάληψη κώδικα και να δημιουργήσουμε έναν πιο οργανωμένο και ευανάγνωστο κώδικα.

Παρακάτω παρουσιάζουμε ένα ακόμα παράδειγμα κληρονομικότητας, όπου η κλάση Car (υποκλάση) κληρονομεί τα χαρακτηριστικά και τις μεθόδους από την κλάση Vehicle (γονική κλάση):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class Vehicle {
protected String brand = "Unknown"; // Η μάρκα του οχήματος
public void honk() {
System.out.println("Tuut, tuut!"); // Εκτύπωση ήχου κόρνας
}
}
class Car extends Vehicle {
private String model = "Unknown"; // Το μοντέλο του αυτοκινήτου
public void setModel(String model) {
this.model = model; // Ορισμός του μοντέλου του αυτοκινήτου
}
public void printModel() {
System.out.println("Model: " + model); // Εκτύπωση του μοντέλου του αυτοκινήτου
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car(); // Δημιουργία ενός αντικειμένου αυτοκινήτου
myCar.setBrand("Ford"); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για ορισμό της μάρκας
myCar.setModel("Mustang"); // Κλήση μεθόδου της υποκλάσης για ορισμό του μοντέλου
System.out.println("Brand: " + myCar.brand); // Εκτύπωση της μάρκας (κληρονομημένο χαρακτηριστικό)
myCar.printModel(); // Κλήση μεθόδου της υποκλάσης για εκτύπωση του μοντέλου
myCar.honk(); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για τον ήχο της κόρνας
}
}
class Vehicle { protected String brand = "Unknown"; // Η μάρκα του οχήματος public void honk() { System.out.println("Tuut, tuut!"); // Εκτύπωση ήχου κόρνας } } class Car extends Vehicle { private String model = "Unknown"; // Το μοντέλο του αυτοκινήτου public void setModel(String model) { this.model = model; // Ορισμός του μοντέλου του αυτοκινήτου } public void printModel() { System.out.println("Model: " + model); // Εκτύπωση του μοντέλου του αυτοκινήτου } } public class Main { public static void main(String[] args) { Car myCar = new Car(); // Δημιουργία ενός αντικειμένου αυτοκινήτου myCar.setBrand("Ford"); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για ορισμό της μάρκας myCar.setModel("Mustang"); // Κλήση μεθόδου της υποκλάσης για ορισμό του μοντέλου System.out.println("Brand: " + myCar.brand); // Εκτύπωση της μάρκας (κληρονομημένο χαρακτηριστικό) myCar.printModel(); // Κλήση μεθόδου της υποκλάσης για εκτύπωση του μοντέλου myCar.honk(); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για τον ήχο της κόρνας } }
class Vehicle {
  protected String brand = "Unknown"; // Η μάρκα του οχήματος

  public void honk() {
    System.out.println("Tuut, tuut!"); // Εκτύπωση ήχου κόρνας
  }
}

class Car extends Vehicle {
  private String model = "Unknown"; // Το μοντέλο του αυτοκινήτου

  public void setModel(String model) {
    this.model = model; // Ορισμός του μοντέλου του αυτοκινήτου
  }

  public void printModel() {
    System.out.println("Model: " + model); // Εκτύπωση του μοντέλου του αυτοκινήτου
  }
}

public class Main {
  public static void main(String[] args) {
    Car myCar = new Car(); // Δημιουργία ενός αντικειμένου αυτοκινήτου
    myCar.setBrand("Ford"); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για ορισμό της μάρκας
    myCar.setModel("Mustang"); // Κλήση μεθόδου της υποκλάσης για ορισμό του μοντέλου
    System.out.println("Brand: " + myCar.brand); // Εκτύπωση της μάρκας (κληρονομημένο χαρακτηριστικό)
    myCar.printModel(); // Κλήση μεθόδου της υποκλάσης για εκτύπωση του μοντέλου
    myCar.honk(); // Κλήση κληρονομημένης μεθόδου από τη γονική κλάση για τον ήχο της κόρνας
  }
}

Ο κώδικας δημιουργεί δύο κλάσεις, την κλάση “Vehicle” και την κλάση “Car”. Η κλάση “Car” κληρονομεί την κλάση “Vehicle”, προσθέτοντας ένα επιπλέον χαρακτηριστικό “model” και δύο μεθόδους “setModel” και “printModel”. Η κλάση “Vehicle” έχει ένα προστατευμένο χαρακτηριστικό “brand” και μια μέθοδο “honk” που εκτυπώνει έναν ήχο κόρνας.

Στην κύρια κλάση “Main” δημιουργείται ένα αντικείμενο τύπου “Car” με όνομα “myCar”. Στη συνέχεια, καλούνται μεθόδοι πάνω στο αντικείμενο “myCar”. Η μέθοδος “setBrand” καλείται για να ορίσει τη μάρκα του αυτοκινήτου, η μέθοδος “setModel” καλείται για να ορίσει το μοντέλο του αυτοκινήτου. Στη συνέχεια, εκτυπώνεται η μάρκα του αυτοκινήτου και το μοντέλο του αυτοκινήτου με τη χρήση της μεθόδου “printModel”. Τέλος, καλείται η μέθοδος “honk” για να εκτυπωθεί ο ήχος της κόρνας του αυτοκινήτου.

Συνολικά, ο κώδικας δημιουργεί ένα αντικείμενο αυτοκινήτου, ορίζει τη μάρκα και το μοντέλο του, και εκτυπώνει τις πληροφορίες αυτές στην οθόνη.

Το αποτέλεσμα που θα εμφανιστεί στην οθόνη είναι:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Brand: Ford
Model: Mustang
Tuut, tuut!
Brand: Ford Model: Mustang Tuut, tuut!
Brand: Ford
Model: Mustang
Tuut, tuut!

Αυτό συμβαίνει επειδή πρώτα ορίζεται η μάρκα “Ford” και το μοντέλο “Mustang” στο αντικείμενο “myCar”. Έπειτα, εκτυπώνεται η μάρκα και το μοντέλο με τη χρήση της μεθόδου “printModel”. Τέλος, καλείται η μέθοδος “honk”, η οποία εκτυπώνει τον ήχο “Tuut, tuut!” στην οθόνη.

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

[adinserter block=”2″]

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
final class MyClass {
// κώδικας της κλάσης
}
final class MyClass { // κώδικας της κλάσης }
final class MyClass {
  // κώδικας της κλάσης
}

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

Μπορούμε να δείξουμε ένα παράδειγμα σφάλματος όταν προσπαθούμε να κληρονομήσουμε μια τελική κλάση. Για παράδειγμα:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
final class Vehicle {
// κώδικας της κλάσης
}
class Car extends Vehicle {
// κώδικας της κλάσης
}
final class Vehicle { // κώδικας της κλάσης } class Car extends Vehicle { // κώδικας της κλάσης }
final class Vehicle {
  // κώδικας της κλάσης
}

class Car extends Vehicle {
  // κώδικας της κλάσης
}

Στο παραπάνω παράδειγμα, η κλάση Vehicle έχει δηλωθεί ως τελική με τη χρήση του final. Καθώς η κλάση Car προσπαθεί να κληρονομήσει από την Vehicle, θα λάβετε ένα σφάλμα κατά τη μεταγλώττιση που θα σας ενημερώνει ότι η κλάση Vehicle δεν μπορεί να κληρονομηθεί επειδή είναι τελική.

Το σφάλμα θα εμφανιστεί κατά τη μεταγλώττιση και θα αναφέρει κάτι παρόμοιο με το ακόλουθο μήνυμα:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cannot inherit from final Vehicle
class Car extends Vehicle {
^
cannot inherit from final Vehicle class Car extends Vehicle { ^
cannot inherit from final Vehicle
class Car extends Vehicle {
                     ^

Αυτό σημαίνει ότι η κλάση Car δεν μπορεί να κληρονομήσει την Vehicle, επειδή η Vehicle δηλώθηκε ως τελική.

14 Ιουνίου, 2023
top
error: Content is protected !!
Μετάβαση σε γραμμή εργαλείων