Αφηρημένες κλάσεις

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

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

Προσοχή! Για να είναι μια κλάση αφηρημένη θα πρέπει τουλάχιστον να περιέχει μια αφηρημένη μέθοδο.

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

Μια αφηρημένη κλάση ή μέθοδο δηλώνεται με την λέξη κλειδί «abstract» ύστερα «class» και ένα όνομα κλάσης.

<?php
 abstract class vehicle{
  private $wheels,$max_speed;
  
  function kanoniki(){
   echo "λειτουργεί";
  }
  
  abstract function afirimeni();
 }
 
 $a = new vehicle();
 $a->kanoniki();
?>

Μέσα στο παραπάνω παράδειγμα έχουμε μια «κανονική» μέθοδο μέσα στην αφηρημένη κλάση και μια «αφηρημένη» μέθοδο. Εμείς προσπαθήσαμε να δημιουργήσουμε ένα αντικείμενο μέσα από την συγκεκριμένη κλάση και ύστερα να καλέσουμε την «κανονική» μέθοδο της. Όπως βλέπετε και εσείς η php μας έβγαλε σφάλμα χρήσης αφηρημένης μεθόδου για δημιουργία αντικειμένου. Ας δούμε την σωστή χρήση:

<?php
 abstract class vehicle{
  private $wheels,$max_speed;
  
  function kanoniki(){
   echo "λειτουργεί";
  }
  
  abstract function afirimeni(); //αφηρημένη μέθοδος
 }
 class car extends vehicle{ // υποκλάση car
  function afirimeni(){ //υλοποιεί την αφηρημένη μέθοδο
   echo "Αφού υλοποιήθηκε μέσα σε μια υποκλάση, τότε η υποκλάση δεν είναι αφηρημένη η μέθοδος «τρέχει»";
  }
 }
 $a = new car(); //Φτιάχνουμε ένα αντικείμενο της υποκλάσης
 $a->kanoniki();
 echo "<br/>";
 $a->afirimeni();
?>

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

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

Διεπαφές

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

Όπως σε μια αφηρημένη μέθοδο, έτσι και σε μια διεπαφή δεν μπορούμε να δημιουργήσουμε αντικείμενα με αυτήν, αλλά μια διεπαφή μπορεί να κληρονομήσει στοιχεία από μια η περισσότερες άλλες διεπαφές. Αυτό σημαίνει ότι μπορεί να έχει και πατέρα και μητέρα, πράγμα που οι απλές κλάσεις δεν μπορούν να το κάνουν αυτό. Οι απλές κλάσεις όμως μπορούν να «υλοποιήσουν» μια διεπαφή όπως γίνεται και στις αφηρημένες κλάσεις αλλά χωρίς να «κληρονομούνται στοιχεία».

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

Ας υποθέσουμε πως μια διεπαφή τηλεκοντρόλ, μας δίνει κάποιες λειτουργίες όπως το άνοιγμα μιας τηλεόρασης, την αλλαγή καναλιού και την αλλαγή έντασης της τηλεόρασης. Για να χρησιμοποιηθεί αυτή η διεπαφή θα πρέπει να υπάρχει μια αντίστοιχη κλάση που να την υλοποιεί. Η λέξεις κλειδιά στην προκειμένη περίπτωση είναι «interface» για την δημιουργία της διεπαφής και «implements» για την υλοποίηση της.

<?php
 interface tilekontrol{
  function anoigmaTileorasis();
  function allagiKanaliou($a);
  function allagiEntasis($a);
 }
 
 class tileorasi implements tilekontrol{
  public $katastasi,$kanali,$entasi;
  
  function anoigmaTileorasis(){ //υλοποίηση πρώτης μεθόδου
   $this->katastasi=true;
  }
  function allagiKanaliou($a){ // υλοποίηση δεύτερης
   $this->kanali = $a;
  }
  function allagiEntasis($a){ // υλοποίηση τρίτης
   $this->entasi = $a;
  }
 }
 
 $a = new tileorasi; //δημιουργία αντικείμενου με βάση την κλάση
 $a->anoigmaTileorasis();
 $a->allagiKanaliou(4);
 $a->allagiEntasis(20);
 
 echo "Ενεργή:".$a->katastasi.", Κανάλι:".$a->kanali.", Ένταση:".$a->entasi;
?>