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

Διατύπωση του προβλήματος

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

Οι απλούστερες επιλογές που έρχονται στο μυαλό είναι να γράψετε τρεις ξεχωριστές τάξεις και να εργαστείτε μαζί τους. Ή γράψτε μια κλάση που θα περιέχει όλες τις ιδιότητες που είναι εγγενείς και στους τρεις τύπους δημοσιεύσεων και θα χρησιμοποιούνται μόνο οι απαραίτητες. Αλλά για διαφορετικούς τύπους, οι μέθοδοι που είναι παρόμοιες στη λογική θα πρέπει να λειτουργούν διαφορετικά. Η δημιουργία πολλών μεθόδων του ίδιου τύπου για διαφορετικούς τύπους (get_news, get_announcements, get_articles) είναι παντελώς αδαής. Εδώ είναι χρήσιμος ο πολυμορφισμός.

Αφηρημένη τάξη

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

δημοσίευση αφηρημένης τάξης
{
// πίνακας που αποθηκεύει δεδομένα στο στοιχείο
προστατευμένο $τραπέζι ;

// Οι ιδιότητες του στοιχείου είναι άγνωστες σε εμάς
προστατευμένα $properties = array();

// κατασκευαστής

{
// σημειώστε ότι δεν ξέρουμε από ποιον πίνακα χρειαζόμαστε για να λάβουμε τα δεδομένα
$result = mysql_query ("SELECT * FROM `" . $this -> table . "` WHERE `id`="" . $id . "" LIMIT 1" );
// δεν γνωρίζουμε επίσης ποια δεδομένα λάβαμε
$this -> ιδιότητες = mysql_fetch_assoc ($result);
}

Η μέθοδος //, η ίδια για κάθε τύπο δημοσίευσης, επιστρέφει την τιμή της ιδιότητας
δημόσια συνάρτηση get_property ($name)
{
if (isset($this -> ιδιότητες [ $name ]))
επιστροφή $this -> ιδιότητες [ $name ];

Return false ;
}

Η μέθοδος //, η ίδια για κάθε τύπο δημοσίευσης, ορίζει την τιμή της ιδιότητας
δημόσια συνάρτηση set_property ($name, $value)
{
if (!isset($this -> ιδιότητες [ $name ]))
επιστροφή ψευδής ;

$this -> ιδιότητες [ $name ] = $value ;

Επιστροφή $value ;
}

// και αυτή η μέθοδος θα πρέπει να εκτυπώσει τη δημοσίευση, αλλά δεν ξέρουμε πώς ακριβώς να το κάνουμε και επομένως τη δηλώνουμε αφηρημένη
αφηρημένη δημόσια συνάρτηση do_print();
}

Παράγωγες τάξεις

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

class News επεκτείνει Δημοσίευση
{
// κατασκευαστής της κλάσης ειδήσεων, που προέρχεται από την κλάση δημοσιεύσεων
δημόσια συνάρτηση __κατασκευή ($id)
{
// ορίστε την τιμή του πίνακα στον οποίο αποθηκεύονται τα δεδομένα ειδήσεων
$this -> table = " news_table " ;
γονέας :: __construct ($id );
}

Δημόσια συνάρτηση do_print()
{
echo $this -> ιδιότητες ["τίτλος" ];
ηχώ "

" ;
echo $this -> ιδιότητες ["κείμενο" ];
ηχώ "
Πηγή: " . $this -> ιδιότητες [ "πηγή" ];
}
}

Η Ανακοίνωση τάξης παρατείνει τη δημοσίευση
{
// κατασκευαστής της κλάσης διαφημίσεων που προέρχεται από την κλάση δημοσίευσης
δημόσια συνάρτηση __κατασκευή ($id)
{
// ορίστε την τιμή του πίνακα στον οποίο αποθηκεύονται τα δεδομένα διαφημίσεων
$this -> table = " ανακοινώσεις_πίνακας " ;
// καλέστε τον κατασκευαστή της γονικής κλάσης
γονέας :: __construct ($id );
}

// παρακάμπτει τη μέθοδο αφηρημένης εκτύπωσης
δημόσια συνάρτηση do_print()
{
echo $this -> ιδιότητες ["τίτλος" ];
ηχώ "
Προσοχή! Η ανακοίνωση ισχύει μέχρι «
. $this -> ιδιότητες ["end_date" ];
ηχώ "

" . $this -> ιδιότητες [ "text" ];
}
}

Το άρθρο της τάξης επεκτείνει τη δημοσίευση
{
// κατασκευαστής της κλάσης άρθρου, που προέρχεται από την κλάση δημοσίευσης
δημόσια συνάρτηση __κατασκευή ($id)
{
// ορίστε την τιμή του πίνακα στον οποίο αποθηκεύονται δεδομένα για άρθρα
$this -> table = "articles_table" ;
// καλέστε τον κατασκευαστή της γονικής κλάσης
γονέας :: __construct ($id );
}

// παρακάμπτει τη μέθοδο αφηρημένης εκτύπωσης
δημόσια συνάρτηση do_print()
{
echo $this -> ιδιότητες ["τίτλος" ];
ηχώ "

" ;
echo $this -> ιδιότητες ["κείμενο" ];
ηχώ "
" . $this -> ιδιότητες [ "author" ];
}
}

Τώρα για τη χρήση

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

// γεμίστε τον πίνακα δημοσίευσης με αντικείμενα που προέρχονται από τη Δημοσίευση
$publications = νέες Ειδήσεις ($news_id);
$publications = new Announcement($announcement_id);
$publications = νέο άρθρο($article_id);

Foreach ($publications ως $publication) (
// εάν συνεργαζόμαστε με κληρονόμους της Έκδοσης
if ($publication instanceof Publication) (
// στη συνέχεια εκτυπώστε τα δεδομένα
$publication -> do_print();
) άλλο (
// Εξαίρεση ή χειρισμός σφαλμάτων
}
}

Αυτό είναι όλο. Με μια ελαφριά κίνηση του χεριού, το παντελόνι μετατρέπεται σε κομψό σορτς :-).

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

Λίγη θεωρία

  • Οι μέθοδοι που απαιτούν παράκαμψη ονομάζονται αφηρημένες. Είναι λογικό ότι αν μια κλάση περιέχει τουλάχιστον μια αφηρημένη μέθοδο, τότε είναι και αφηρημένη.
  • Προφανώς, ένα αντικείμενο μιας αφηρημένης κλάσης δεν μπορεί να δημιουργηθεί, διαφορετικά δεν θα ήταν αφηρημένο.
  • Μια παραγόμενη κλάση έχει ιδιότητες και μεθόδους που ανήκουν στη βασική κλάση και μπορεί επίσης να έχει τις δικές της μεθόδους και ιδιότητες.
  • Μια μέθοδος που παρακάμπτεται σε μια παράγωγη κλάση ονομάζεται εικονική μέθοδος. Δεν υπάρχουν πληροφορίες σχετικά με αυτήν τη μέθοδο στη βασική αφηρημένη κλάση.
  • Το θέμα της αφαίρεσης είναι να ορίσουμε μια μέθοδο στο μέρος όπου υπάρχουν οι πιο ολοκληρωμένες πληροφορίες για το πώς πρέπει να λειτουργεί.
UPD:Όσον αφορά τις παραβιάσεις sql-inj και MVC - κύριοι, αυτό είναι απλώς ένα παράδειγμα, και ένα παράδειγμα πολυμορφισμού, στο οποίο δεν θεωρώ απαραίτητο να δώσω προσοχή σε αυτά τα πράγματα. Αυτό είναι ένα θέμα για εντελώς διαφορετικά άρθρα.

Αντικειμενοστραφής προγραμματισμός(OOP) είναι μια προσέγγιση για τη δημιουργία προγραμμάτων που βασίζονται στη χρήση κλάσεων και αντικειμένων που αλληλεπιδρούν μεταξύ τους.

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

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

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

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

Χρησιμοποιώντας την κληρονομικότητα, μπορείτε να δημιουργήσετε μια γενική "τάξη java" που ορίζει χαρακτηριστικά κοινά σε ένα σύνολο σχετικών στοιχείων. Στη συνέχεια, μπορείτε να κληρονομήσετε από αυτό και να δημιουργήσετε πρόσθετες κλάσεις για τις οποίες μπορείτε να ορίσετε πρόσθετα χαρακτηριστικά που είναι μοναδικά για αυτούς.

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

Ας εξετάσουμε ένα παράδειγμα περιγραφής της τάξης java "ένας σπουδαστής Μαθητής, ο οποίος έχει όνομα, επώνυμο, ηλικία και αριθμό ομάδας. Θα δημιουργήσουμε μια τάξη μαθητή με βάση την υπερ-κλάση του χρήστη χρήστη, η οποία έχει ήδη ορίζεται όνομα, επώνυμο και ηλικία:

Χρήστης δημόσιας τάξης ( int age; String firstName; String lastName; // Constructor public User (int age, String firstName, String lastName) ( this.age = ηλικία; this.firstName = firstName; this.lastName = lastName; ) )

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

Δημόσια τάξη Μαθητής επεκτείνει Χρήστη ( ομάδα int; // Κατασκευαστής δημόσια Student(int ηλικία, String firstName, String lastName) ( super(ηλικία, όνομα, επώνυμο); ) boolean isMyGroup(int g) ( return g == ομάδα; ) )

Λέξη-κλειδί εκτείνεταιδείχνει ότι κληρονομούμε από την κλάση User.

Λέξη-κλειδί σούπερ

Στον κατασκευαστή της κλάσης Student, καλούμε τον κατασκευαστή της γονικής κλάσης μέσω του τελεστή σούπερ, περνώντας του όλο το απαραίτητο σύνολο παραμέτρων. Στη Java η λέξη-κλειδί σούπερδηλώνει μια υπερκλάση, δηλ. Η κλάση από την οποία προέρχεται η τρέχουσα κλάση. Η λέξη-κλειδί super μπορεί να χρησιμοποιηθεί για την κλήση ενός κατασκευαστή υπερκλάσης και για την πρόσβαση σε ένα μέλος υπερκλάσης που είναι κρυμμένο από ένα μέλος υποκλάσης.

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

Student student = new Student(18, "Kisa", "Vorobyaninov", 221);

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

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

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

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

Η κλάση A ( int i; ) // κληρονομεί από την κλάση A η κλάση B επεκτείνεται A ( int i; // το όνομα μεταβλητής ταιριάζει και αποκρύπτει τη μεταβλητή i στην κλάση A B(int a, int b) ( super.i = a; // πρόσβαση στη μεταβλητή i από την κλάση A i = b; // πρόσβαση στη μεταβλητή i από την κλάση B ) void show() (System.out.println("i από την υπερκλάση είναι " + super.i); System.out.println(" i). στην υποκλάση είναι " + i); ) ) κλάση MainActivity (Β υποκατηγορία = νέα B(1, 2); subClass.show(); )

Ως αποτέλεσμα, θα πρέπει να δούμε στην κονσόλα:

Το I από την υπερκλάση είναι το 1 i στην υποκατηγορία είναι το 2

Παράκαμψη μεθόδου, Παράκαμψη

Εάν σε μια ιεραρχία κλάσης, το όνομα και η υπογραφή τύπου μιας μεθόδου υποκλάσης ταιριάζει με τα χαρακτηριστικά μιας μεθόδου superclass, τότε η μέθοδος subclass αντικαθιστά τη μέθοδο superclass. Όταν μια παράκαμψη μέθοδος καλείται από την υποκλάση της, θα αναφέρεται πάντα στην έκδοση της υποκλάσης αυτής της μεθόδου. Και η έκδοση superclass της μεθόδου θα είναι κρυφή.

Εάν χρειάζεται να αποκτήσετε πρόσβαση σε μια έκδοση μιας παρακαμφθείσας μεθόδου που ορίζεται σε μια υπερκλάση, πρέπει να χρησιμοποιήσετε τη λέξη-κλειδί σούπερ.

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

Ο σχολιασμός εμφανίστηκε στο Java SE5 @Καταπατώ;. Εάν πρέπει να παρακάμψετε μια μέθοδο, χρησιμοποιήστε το @Override και ο μεταγλωττιστής θα εμφανίσει ένα σφάλμα εάν την υπερφορτώσετε κατά λάθος αντί να την παρακάμψετε.

Στην Java, μπορείτε να κληρονομήσετε μόνο από μία κλάση.

Ενθυλάκωση

Στην επιστήμη των υπολογιστών, η ενθυλάκωση (Λατινικά: en capsula) είναι η συσκευασία δεδομένων ή/και λειτουργιών σε ένα ενιαίο αντικείμενο.

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

Τροποποιητές πρόσβασης

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

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

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

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

Παράδειγμα απλής περιγραφής ρομπότ

Ρομπότ δημόσιας κλάσης ( ιδιωτικό διπλό x = 0; // Τρέχουσα συντεταγμένη Χ ιδιωτικό διπλό y = 0; // Τρέχουσα συντεταγμένη Υ ιδιωτικό διπλό μάθημα = 0; // Τρέχον μάθημα (σε μοίρες) δημόσιο διπλό getX() ( επιστροφή x; ) public void setX(double x) ( this.x = x; ) public double getY() ( return y; ) public void setY(double y) ( this.y = y; ) public double getCourse() (return course; ) // Προσδιορισμός του μαθήματος public void setCourse(double course) ( this.course = course; ) // Moving to a distance public void forward(int distance) ( // Πρόσβαση στο πεδίο αντικειμένου X x = x + distance * Math.cos ( course / 180 * Math.PI // Πρόσβαση στο πεδίο αντικειμένου Y y = y + απόσταση * Math.sin(course / 180 * Math.PI ) // Εκτύπωση συντεταγμένων ρομπότ public void printCoordinates() ( System.out); .println(x + "," + y);

Το παράδειγμα ρομπότ που παρουσιάζεται χρησιμοποιεί σύνολα μεθόδων ξεκινώντας από σειράΚαι παίρνω. Αυτό το ζεύγος μεθόδων ονομάζεται συχνά setter/getter. Αυτές οι μέθοδοι χρησιμοποιούνται για την πρόσβαση στα πεδία ενός αντικειμένου. Τα ονόματα των μεθόδων τελειώνουν με το όνομα του πεδίου που αρχίζει με ΚΕΦΑΛΑΙΟ γράμμα.

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

Αυτό.μάθημα = πορεία...

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

Πολυμορφισμός

Ο πολυμορφισμός είναι μια από τις θεμελιώδεις έννοιες στον αντικειμενοστραφή προγραμματισμό, μαζί με την κληρονομικότητα και την ενθυλάκωση. Η λέξη πολυμορφισμός είναι ελληνικής προέλευσης και σημαίνει «έχω πολλές μορφές». Για να κατανοήσετε τι σημαίνει ο πολυμορφισμός σε σχέση με τον αντικειμενοστραφή προγραμματισμό, εξετάστε ένα παράδειγμα δημιουργίας ενός διανυσματικού επεξεργαστή γραφικών στο οποίο είναι απαραίτητο να χρησιμοποιήσετε έναν αριθμό κλάσεων με τη μορφή ενός συνόλου γραφικών πρωτόγονων - τετράγωνο, Γραμμή, Κύκλος, Τρίγωνο, και τα λοιπά. Κάθε μία από αυτές τις κλάσεις πρέπει να έχει καθορισμένη μέθοδο σχεδιάζωγια να εμφανίσετε το αντίστοιχο πρωτόγονο στην οθόνη.

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

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

// Καθορισμός πινάκων γραφικών πρωτόγονων Τετράγωνο s = νέο Τετράγωνο ; Γραμμή l = νέα γραμμή. Κύκλος c = νέος Κύκλος ; Τρίγωνο t = νέο Τρίγωνο; // Συμπληρώστε όλους τους πίνακες με τα κατάλληλα αντικείμενα. . . // Επανάληψη βρόχου σε όλα τα κελιά του πίνακα. για (int i = 0; i< s.length; i++){ // вызов метода draw() в случае, если ячейка не пустая. if (s[i] != null) s.draw(); } for(int i = 0; i < l.length; i++){ if (l[i] != null) l.draw(); } for(int i = 0; i < c.length; i++){ if (c[i] != null) c.draw(); } for(int i = 0; i < t.length; i++){ if (t[i] != null) t.draw(); }

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

Χρησιμοποιώντας τον πολυμορφισμό, μπορείτε να απλοποιήσετε σημαντικά την υλοποίηση μιας τέτοιας λειτουργικότητας. Πρώτα απ 'όλα, ας δημιουργήσουμε μια κοινή γονική τάξη Shape για όλες τις κλάσεις μας.

Public class Shape ( public void draw() ( System.out.println("Stub"); ) )

Μετά από αυτό, δημιουργούμε διάφορες τάξεις απογόνων: Τετράγωνο, Γραμμή, Κύκλος και Τρίγωνο:

Η δημόσια κλάση Σημείο επεκτείνει το σχήμα ( δημόσιο κενό σχέδιο() ( System.out.println("Τετράγωνο"); ) ) η δημόσια κλάση Γραμμή επεκτείνει το σχήμα (δημόσιο κενό σχέδιο() ( System.out.println("Γραμμή"); ) ) δημόσια κλάση Κύκλος επεκτείνει το σχήμα ( δημόσιο κενό σχέδιο() ( System.out.println("Κύκλος"); ) ) δημόσια κλάση Τρίγωνο επεκτείνει το σχήμα ( δημόσιο κενό σχέδιο() ( System.out.println("Τρίγωνο"); ) )

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

Τώρα ας δούμε το εκπληκτικό χαρακτηριστικό του πολυμορφισμού:

// Ορισμός και προετοιμασία του πίνακα Shape a = new Shape (new Shape(), new Triangle(), new Square(), new Circle()); // Επαναφορά στοιχείων πίνακα για(int i = 0; i< a.length; i++) { a[i].draw(); }

Οι ακόλουθες γραμμές θα βγουν στην κονσόλα:

Κενός τετράγωνος κύκλος τριγώνου

Με αυτόν τον τρόπο, κάθε κλάση καταγωγής κάλεσε τη δική της μέθοδο draw, αντί να καλέσει τη μέθοδο draw από τη μητρική κλάση Shape.

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

Υπερφόρτωση μεθόδου, υπερφόρτωση

Στον διαδικαστικό προγραμματισμό, υπάρχει επίσης η έννοια του πολυμορφισμού, η οποία διαφέρει από τον εξεταζόμενο μηχανισμό στο OOP. Ο διαδικαστικός πολυμορφισμός υποδηλώνει τη δυνατότητα δημιουργίας πολλών διαδικασιών ή συναρτήσεων με το ίδιο όνομα, αλλά διαφορετικούς αριθμούς ή τύπους παραμέτρων που έχουν περάσει. Τέτοιες συναρτήσεις με το ίδιο όνομα ονομάζονται υπερφορτωμένες και το ίδιο το φαινόμενο ονομάζεται υπερφόρτωση. Η υπερφόρτωση συναρτήσεων υπάρχει επίσης στο OOP και ονομάζεται υπερφόρτωση μεθόδου. Ένα παράδειγμα χρήσης της υπερφόρτωσης μεθόδου στη γλώσσα Java είναι η κλάση PrintWriter, η οποία χρησιμοποιείται ιδιαίτερα για την εκτύπωση μηνυμάτων στην κονσόλα. Αυτή η κλάση έχει πολλές μεθόδους println που διαφέρουν ως προς τους τύπους και/ή τον αριθμό των παραμέτρων εισαγωγής. Εδώ είναι μερικά μόνο από αυτά:

Void println() // μετάβαση σε μια νέα γραμμή void println(boolean x) // εκτυπώνει την τιμή μιας Boolean μεταβλητής (true or false) void println(String x) // εκτυπώνει μια συμβολοσειρά - την τιμή μιας παραμέτρου κειμένου

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

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

Εν συντομία, η έννοια του πολυμορφισμού μπορεί να εκφραστεί με τη φράση: «Μία διεπαφή, πολλές υλοποιήσεις».

Ο πολυμορφισμός είναι ένας από τους τέσσερις πιο σημαντικούς μηχανισμούς αντικειμενοστρεφούς προγραμματισμού (μαζί με την αφαίρεση, την ενθυλάκωση και την κληρονομικότητα).

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

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

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

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

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

Σε αντικειμενοστρεφείς γλώσσες

Στις αντικειμενοστρεφείς γλώσσες, μια κλάση είναι ένας αφηρημένος τύπος δεδομένων.[Σημείωση. 1] Ο πολυμορφισμός υλοποιείται χρησιμοποιώντας κληρονομικότητα κλάσης και εικονικές συναρτήσεις. Μια θυγατρική κλάση κληρονομεί τις υπογραφές των μεθόδων της γονικής κλάσης και η υλοποίηση, ως αποτέλεσμα της παράκαμψης μεθόδου, αυτών των μεθόδων μπορεί να είναι διαφορετική, ανάλογα με τις ιδιαιτερότητες της κλάσης καταγωγής. Άλλες συναρτήσεις μπορεί να αντιμετωπίζουν ένα αντικείμενο ως παρουσία μιας γονικής κλάσης, αλλά εάν το αντικείμενο είναι στην πραγματικότητα μια παρουσία μιας θυγατρικής κλάσης, η μέθοδος που έχει παρακαμφθεί στη θυγατρική κλάση θα κληθεί κατά το χρόνο εκτέλεσης. Αυτό ονομάζεται όψιμο δέσιμο. [Μια περίπτωση χρήσης παραδείγματος θα ήταν η επεξεργασία ενός πίνακα που περιέχει στιγμιότυπα και μιας γονικής και μιας θυγατρικής κλάσης: προφανώς, ένας τέτοιος πίνακας μπορεί να δηλωθεί μόνο ως πίνακας του τύπου της γονικής κλάσης και μόνο οι μέθοδοι αυτής της κλάσης μπορούν να καλούνται σε αντικείμενα του πίνακα, αλλά εάν στο Εάν ορισμένες μέθοδοι έχουν παρακαμφθεί στην κλάση καταγωγής, τότε στη λειτουργία χρόνου εκτέλεσης για περιπτώσεις αυτής της κλάσης θα κληθούν αυτές και όχι οι μέθοδοι της γονικής κλάσης.]

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

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

Μια κλάση μπορεί να κληρονομήσει λειτουργικότητα από πολλές κλάσεις. Αυτό ονομάζεται πολλαπλή κληρονομικότητα. Η πολλαπλή κληρονομικότητα δημιουργεί ένα πολύ γνωστό πρόβλημα (στην C++) όταν μια κλάση κληρονομεί από πολλαπλές κλάσεις μεσολάβησης, οι οποίες με τη σειρά τους κληρονομούν από την ίδια κλάση (το λεγόμενο "Πρόβλημα διαμαντιών"): εάν μια μέθοδος κοινού προγονέα παρακαμφθεί στον διακομιστή μεσολάβησης , είναι άγνωστο ποια εφαρμογή της μεθόδου πρέπει να κληρονομηθεί από έναν κοινό απόγονο. Αυτό το πρόβλημα επιλύεται με την άρνηση πολλαπλής κληρονομικότητας για κλάσεις και επιτρέποντας πολλαπλή κληρονομικότητα για εντελώς αφηρημένες κλάσεις (δηλαδή, διεπαφές) (C#, Delphi, Java) ή μέσω εικονικής κληρονομικότητας (C++).

Σε λειτουργικές γλώσσες

Ο πολυμορφισμός σε λειτουργικές γλώσσες θα συζητηθεί χρησιμοποιώντας το Haskell ως παράδειγμα.

Πολυμορφισμός (προγραμματισμός)

Εν συντομία, η έννοια του πολυμορφισμού μπορεί να εκφραστεί με τη φράση: «Μία διεπαφή, πολλές υλοποιήσεις».

Ο πολυμορφισμός είναι ένας από τους τέσσερις πιο σημαντικούς μηχανισμούς αντικειμενοστρεφούς προγραμματισμού (μαζί με την αφαίρεση, την ενθυλάκωση και την κληρονομικότητα).

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

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

Παραδείγματα

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

Σε λειτουργικές γλώσσες

Υπάρχουν δύο τύποι πολυμορφισμού στο Haskell - παραμετρικός (καθαρός) και ειδικός (βασισμένος στην τάξη). Ειδικό ονομάζεται επίσης ad hoc(από τα λατινικά ad hoc - ειδικά). Μπορούν να διακριθούν ως εξής:

Παραμετρικός πολυμορφισμός

Ειδικός πολυμορφισμός

Το Haskell έχει μια διαίρεση σε κλάσεις και στιγμιότυπα, η οποία δεν βρίσκεται στο OOP. Η κλάση ορίζει ένα σύνολο και υπογραφές μεθόδων (ίσως δίνοντας προεπιλεγμένες υλοποιήσεις για ορισμένες ή όλες) και οι παρουσίες τις υλοποιούν. Έτσι, το πρόβλημα της πολλαπλής κληρονομικότητας εξαφανίζεται αυτόματα. Οι κλάσεις δεν κληρονομούν ούτε παρακάμπτουν μεθόδους άλλων κλάσεων - κάθε μέθοδος ανήκει μόνο σε μία κλάση. Αυτή η προσέγγιση είναι απλούστερη από το σύνθετο διάγραμμα των σχέσεων τάξης στο OOP. Ένας δεδομένος τύπος δεδομένων μπορεί να ανήκει σε πολλές κλάσεις. μια κλάση μπορεί να απαιτεί κάθε τύπος της να ανήκει απαραίτητα σε μια άλλη κλάση, ή ακόμα και σε πολλές. η ίδια απαίτηση μπορεί να προβληθεί από μια περίπτωση. Αυτά είναι ανάλογα πολλαπλής κληρονομικότητας. Υπάρχουν επίσης ορισμένες ιδιότητες που δεν έχουν ανάλογα στο OOP. Για παράδειγμα, η υλοποίηση μιας λίστας ως παρουσίας της κατηγορίας συγκρίσιμων ποσοτήτων απαιτεί τα στοιχεία της λίστας να ανήκουν επίσης στην κατηγορία συγκρίσιμων ποσοτήτων.

Οι προγραμματιστές που μετακινούνται από το OOP στο FP θα πρέπει να γνωρίζουν μια σημαντική διαφορά μεταξύ των συστημάτων κλάσης τους. Εάν στο OOP μια κλάση είναι «συνδεδεμένη» με ένα αντικείμενο, δηλ. με δεδομένα, τότε στο FP συνδέεται με μια συνάρτηση. Στο FP, οι πληροφορίες σχετικά με τη συμμετοχή κλάσης διαβιβάζονται όταν καλείται μια συνάρτηση, αντί να αποθηκεύονται στα πεδία του αντικειμένου. Αυτή η προσέγγιση, ειδικότερα, μας επιτρέπει να λύσουμε το πρόβλημα μιας μεθόδου πολλών αντικειμένων (στο OOP, μια μέθοδος καλείται σε ένα αντικείμενο). Παράδειγμα: η μέθοδος προσθήκης (αριθμοί, συμβολοσειρές) απαιτεί δύο ορίσματα, και τα δύο του ίδιου τύπου.

Σιωπηρή πληκτρολόγηση

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

Μορφές πολυμορφισμού

Στατικός και δυναμικός πολυμορφισμός

(αναφέρεται στο κλασικό βιβλίο των Sutter και Alexandrescu, που είναι η πηγή).

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

Σε μια περίπτωση, η συγκεκριμένη σημασία ενός τμήματος εξαρτάται από το περιβάλλον στο οποίο δημιουργήθηκε ο κώδικας. Αυτό είναι το λεγόμενο στατικός πολυμορφισμός. Η υπερφόρτωση συναρτήσεων και τα πρότυπα στη C++ εφαρμόζουν στατικό πολυμορφισμό. Εάν, για παράδειγμα, το std::sort καλείται στον κώδικα μιας κλάσης προτύπου, τότε το πραγματικό νόημα της κλήσης εξαρτάται από ποιες παραμέτρους τύπου θα αναπτυχθεί αυτό το πρότυπο - θα καλείται μία από τις std::sort .

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

Πολυμορφισμός εγκλεισμού

Αυτός ο πολυμορφισμός ονομάζεται καθαρός πολυμορφισμός. Χρησιμοποιώντας αυτή τη μορφή πολυμορφισμού, τα σχετικά αντικείμενα μπορούν να χρησιμοποιηθούν με γενικό τρόπο. Χρησιμοποιώντας τον πολυμορφισμό αντικατάστασης και συμπερίληψης, μπορείτε να γράψετε μία μέθοδο για να εργαστείτε με όλους τους τύπους αντικειμένων TPerson. Χρησιμοποιώντας τον πολυμορφισμό συμπερίληψης και υποκατάστασης, μπορείτε να εργαστείτε με οποιοδήποτε αντικείμενο που περνά τη δοκιμή "είναι-Α". Ο πολυμορφισμός συμπερίληψης απλοποιεί την εργασία της προσθήκης νέων υποτύπων σε ένα πρόγραμμα, καθώς δεν χρειάζεται να προσθέσετε μια συγκεκριμένη μέθοδο για κάθε νέο τύπο, μπορείτε να χρησιμοποιήσετε μια υπάρχουσα, μόνο αλλάζοντας τη συμπεριφορά του συστήματος σε αυτό. Με τον πολυμορφισμό, μπορείτε να επαναχρησιμοποιήσετε μια βασική κλάση. χρησιμοποιήστε οποιονδήποτε απόγονο ή μεθόδους που χρησιμοποιεί η βασική κλάση.

Παραμετρικός πολυμορφισμός

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

Παραμετρικές Μέθοδοι

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

Παραμετρικοί τύποι

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

Παράκαμψη πολυμορφισμού

Οι αφηρημένες μέθοδοι αναφέρονται συχνά ως αναβαλλόμενες μέθοδοι. Η κλάση στην οποία ορίζεται αυτή η μέθοδος μπορεί να καλέσει τη μέθοδο και ο πολυμορφισμός διασφαλίζει ότι η κατάλληλη έκδοση της αναβαλλόμενης μεθόδου καλείται σε θυγατρικές κλάσεις. Ο ad hoc πολυμορφισμός επιτρέπει μια ειδική υλοποίηση για κάθε τύπο δεδομένων.

Πολυμορφισμός-υπερφόρτωση

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

Σύγκριση πολυμορφισμού σε λειτουργικό και αντικειμενοστραφή προγραμματισμό

Τα συστήματα κλάσεων στο FP και στο OOP είναι δομημένα διαφορετικά, επομένως οι συγκρίσεις μεταξύ τους θα πρέπει να προσεγγίζονται πολύ προσεκτικά.

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

Παρά τις εννοιολογικές διαφορές μεταξύ των συστημάτων κλάσης σε FP και OOP, υλοποιούνται με τον ίδιο περίπου τρόπο - χρησιμοποιώντας πίνακες εικονικών μεθόδων που χρησιμοποιούνται συχνά στην Java.

δείτε επίσης

Συνδέσεις

Σημειώσεις


Ίδρυμα Wikimedia. 2010.

Δείτε τι είναι ο «Πολυμορφισμός (προγραμματισμός)» σε άλλα λεξικά:

    Αυτός ο όρος έχει άλλες έννοιες, βλέπε Πολυμορφισμός. Ο πολυμορφισμός ιών υπολογιστών (ελληνικά: πολυ πολλά + ελληνικά: μορφή, εμφάνιση) είναι μια ειδική τεχνική που χρησιμοποιείται από τους συντάκτες κακόβουλου λογισμικού... ... Wikipedia

    Στον αντικειμενοστραφή προγραμματισμό, η ικανότητα ενός αντικειμένου να επιλέγει τη σωστή μέθοδο ανάλογα με τον τύπο των δεδομένων που λαμβάνονται στο μήνυμα. Στα Αγγλικά: Polymorphism Δείτε επίσης: Αντικειμενοστραφής προγραμματισμός Οικονομικό Λεξικό... ... Οικονομικό Λεξικό

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

ΕΝΤΑΞΕΙ. Ο πολυμορφισμός δεν πρέπει ποτέ να εξετάζεται χωριστά από άλλες θεμελιώδεις έννοιες - αφαίρεση, ενθυλάκωση και κληρονομικότητα. Το αντικείμενο και τα παρόμοια είναι προσαρτημένα από αξιώματα (αν και αυτά είναι επίσης αξιώματα).

Στην πραγματικότητα, ας φανταστούμε ένα ποτήρι, μια κούπα, έναν βραστήρα, μια καφετιέρα, ένα ποδήλατο και ένα skateboard κοντά. Τι κοινό έχουν όλα αυτά; Λοιπόν, τουλάχιστον ότι υπάρχουν. Δηλαδή, αυτά είναι αντικείμενα που δημιουργήθηκαν. Πώς δημιουργήθηκαν όμως; Πιθανότατα στο εργοστάσιο του κατασκευαστή σύμφωνα με σχέδια. Εντάξει, ας ονομάσουμε τον κατασκευαστή σχέδιο. Λοιπόν, τι γίνεται με την τάξη; Και τι είναι αυτό; Αλλά δεν είναι στο σύμπαν μας - αυτή η ουσία είναι μια αφαίρεση που ζει μόνο στις σκέψεις μας. Στον πραγματικό κόσμο δεν υπάρχει και δεν θα υπάρξει ποτέ, έτσι είναι η φυσική - δεν τη νοιάζει που τα πουλιά και τα θηλαστικά έχουν μακρινούς συγγενείς - παρέχει μόνο τη δυνατότητα φυσικής επιλογής. Και εμείς οι άνθρωποι βρίσκουμε συγγενείς ο ένας για τον άλλον.

Τακτοποιήσαμε αντικείμενα και τάξεις, αλλά τι γίνεται με τα γυαλιά και τα ποδήλατά μας; Έχουμε ήδη καταλάβει ότι τα πάντα είναι ένα αντικείμενο, δηλαδή, χονδρικά, όλα τα αντικείμενα μπορούν να κληρονομηθούν από κάποιον υπερπρόγονο, υπερκλάση, που εφαρμόζεται σε ορισμένες γλώσσες. Τι άλλο όμως κοινό έχουν ένα skateboard και ένα ποτήρι, για παράδειγμα; Φυσικά, μπορείτε να πάτε πιο βαθιά και να σκεφτείτε ότι είναι όλα φτιαγμένα από μόρια, και όλα από στερεά. Ωστόσο, όλα αυτά είναι ανοησίες και SRSG, οπότε η απάντηση είναι απλή - τίποτα. Δηλαδή, πρόκειται για εντελώς διαφορετικά αντικείμενα με εντελώς διαφορετική λειτουργικότητα. Επιπλέον, φυσικά, τα μοντέλα υπολογιστών και οι ιεραρχίες θα διαφέρουν πολύ από τη φυσική και τη χημεία. Και αυτό είναι φυσιολογικό, το ζήτημα της επάρκειας των μοντέλων τίθεται μόνο όταν το μοντέλο είναι ανεπαρκές, και μέχρι τότε μπορείς να κόψεις οτιδήποτε αρκεί να λειτουργεί.

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

Ωστόσο, τι γίνεται με τα υπόλοιπα; Έχουμε επίσης αφαίρεση, ενθυλάκωση και κληρονομικότητα. Οκ, ας ξεκινήσουμε με την κληρονομιά, είναι το πιο κοντινό. Τι κοινό έχουμε ανάμεσα σε ένα ποτήρι και μια κούπα; Λοιπόν, μπορείτε να ρίξετε νερό και στα δύο, αλλά η κούπα έχει μια λαβή για να την κρατάτε. Δηλαδή, μπορείτε να καταλήξετε σε μια συγκεκριμένη γενική κατηγορία - χωρητικότητα. Ωστόσο, τι είναι αυτή η τάξη; Για παράδειγμα, μπορείτε να πάρετε ένα ποτήρι για αυτήν την κατηγορία, τότε όλα τα δοχεία είναι ποτήρια από προεπιλογή και όλα τα άλλα είναι τροποποιημένα ποτήρια. Κάποιοι όμως προτιμούν τις κανάτες, για παράδειγμα, κάποιες γκόμενοι τις φορούν στο κεφάλι, νομίζοντας ότι είναι βολικό. Λοιπόν, ας τα φορέσουν, αλλά κάπως πρέπει να αποφασίσουν τι είναι πιο σημαντικό και ιδανικό. Άρα - το ανέφικτο ιδανικό είναι το κύριο - αυτό ονομάζεται αφηρημένη τάξη. Δηλαδή ένα δοχείο που δεν μπορεί να δημιουργηθεί, για το οποίο δεν υπάρχει πλήρες σχέδιο. Και όλα τα σχέδια που έχουν επεκταθεί σε πλήρη μορφή είναι κληρονομημένες κλάσεις από την κατηγορία χωρητικότητας.

Εδώ ερχόμαστε στην αφαίρεση. Αυτή η ιεραρχική κληρονομιά μας οδηγεί ίσως στην κύρια ιδέα του OOP. Έτσι, πήραμε και επισημάναμε τα πάντα όπου μπορούσε να χυθεί νερό σε μια ξεχωριστή τάξη, σχεδιάσαμε ένα γενικό σχέδιο, αλλά δεν το ολοκληρώσαμε συγκεκριμένα, αφήνοντας ένα κενό για τους μελλοντικούς δημιουργούς και ονομάσαμε το σχέδιο ένα δοχείο. Για χιλιάδες χρόνια έχουν εφεύρει όλους τους κόσμους και έχουν δημιουργήσει τα δικά τους δοχεία, το ένα καλύτερο από το άλλο. Είναι διαφορετικό για διαφορετικούς ανθρώπους, φυσικά. Αλλά η ομαδοποίηση των μορίων του γυαλιού με έναν συγκεκριμένο τρόπο κάθε φορά δεν είναι εύκολη υπόθεση. Ως εκ τούτου, οι τεχνίτες κατέφυγαν σε ένα τέχνασμα: δημιούργησαν ένα μυστικό συμβούλιο τεχνιτών του κόσμου και αποφάσισαν να μοιραστούν τα επιτεύγματά τους μεταξύ τους. Δηλαδή, δημιουργήστε μικρά σχέδια και δηλώστε ως κλάση, για παράδειγμα, ένα στριμμένο στυλό σε σχήμα λωρίδας Möbius, για παράδειγμα. Ίσως ένα τέτοιο στυλό είναι βολικό μόνο για εξωγήινα πλάσματα, αλλά το σχέδιο έχει δημιουργηθεί και μπορείτε να ανατρέξετε σε αυτό όταν δημιουργείτε το δικό σας σχέδιο. Έτσι, αφαιρούμε από το έργο χαμηλού επιπέδου του «σχηματισμού δοχείων με κίνηση μορίων» στην «κατασκευή ενός δοχείου με συνδυασμό μερών και στοιχείων». Αυτό είναι αφαίρεση.

Αλλά φτάνουμε στο τελευταίο σημείο - την ενθυλάκωση. Είναι αδιαχώριστο από την αφαίρεση και στην πραγματικότητα είναι χάρη σε αυτήν που λειτουργεί. Η ενθυλάκωση είναι ένα είδος κόλλας (ή μπλε ταινίας) που χρησιμοποιείται για τη συγκόλληση διαφορετικών σχεδίων σε ένα. Δηλαδή, ο συνδυασμός εξαρτημάτων για να δημιουργήσετε το δικό σας είναι ενθυλάκωση. Επιπλέον, όταν συνδυάζουμε, ενδέχεται να μην περιγράψουμε τις λεπτομέρειες αυτού του συνδυασμού (δηλαδή, τα μέλη της τάξης μπορούν να είναι ιδιωτικά), βοηθώντας έτσι στην αφαίρεση αυτών που χρησιμοποιούν αυτό το σχέδιο. Ας δούμε την τσαγιέρα - τι είναι; Αυτό είναι ένα ποτήρι (ή κούπα) στο οποίο είναι κολλημένο ένα θερμαντικό στοιχείο στο κάτω μέρος (ή μήπως μέσα στη μέση;). Περνώντας ένα ρεύμα μέσα από αυτό, σύμφωνα με το νόμο του Ohm που είναι εγκλωβισμένος στο θερμαντικό στοιχείο, θα απελευθερωθεί θερμότητα και το νερό θα θερμανθεί. Τι γίνεται με μια καφετιέρα; Αυτή είναι μια πολύ πιο σύνθετη συσκευή, με πολλές αντλίες, δοχεία, αεροφράξεις, μύλοι και βραστήρες. Και όλα είναι κολλημένα μεταξύ τους με κόλλα. Ή ίσως μπλε ηλεκτρική ταινία. Αυτό είναι πάλι ενθυλάκωση.

Έτσι, η αφαίρεση είναι αδύνατη χωρίς ενθυλάκωση και κληρονομικότητα, όπως ο πολυμορφισμός είναι αδύνατος χωρίς την ίδια την κληρονομικότητα. Λοιπόν, ο πολυμορφισμός είναι επίσης αδύνατος χωρίς ενθυλάκωση, κάτι που είναι απλά άχρηστο χωρίς κληρονομικότητα και πολυμορφισμό. Αυτά είναι τα τρίγωνα με πίτες. Κρίμα που είπαν ψέματα για την πίτα. Και για τα γενέθλια.


Κλείσε