Αντικαθιστά το VB.NET

click fraud protection

Αυτή είναι μια μίνι σειρά που καλύπτει τις διαφορές στις υπερφορτώσεις, τις σκιές και τις παρακάμψεις στο VB.NET. Αυτό το άρθρο καλύπτει τις παρακάμψεις. Τα άρθρα που καλύπτουν τα υπόλοιπα είναι εδώ:

-> Υπερφόρτωση
-> Σκιές

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

Αντικαθιστά

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

instagram viewer
βασική κατηγορία (μερικές φορές ονομάζεται γονική κλάση). Και το Overrides είναι το σφυρί. σας επιτρέπει να αντικαταστήσετε πλήρως μια μέθοδο (ή μια ιδιότητα) από μια βασική κλάση.

Στο άρθρο σχετικά με τις κατηγορίες και τη λέξη-κλειδί Σκιές (Βλέπε: Σκιές στο VB.NET), προστέθηκε μια λειτουργία για να δείξει ότι μπορεί να γίνει αναφορά σε μια κληρονομική διαδικασία.

Public Class ProfessionalContact. '... ο κωδικός δεν εμφανίζεται... Δημόσια λειτουργία HashTheName ( ByVal nm ως συμβολοσειρά) ως συμβολοσειρά. Επιστροφή nm. GetHashCode. Λειτουργία τερματισμού. Τέλος κλάσης.

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

Στο παράδειγμα, χρησιμοποίησα το VB.NET GetHashCode μέθοδος για να κρατήσει τον κώδικα απλό και αυτό επέστρεψε ένα αρκετά άχρηστο αποτέλεσμα, την τιμή -520086483. Ας υποθέσουμε ότι ήθελα ένα διαφορετικό αποτέλεσμα να επιστραφεί αντ 'αυτού αλλά,

-> Δεν μπορώ να αλλάξω την κλάση βάσης. (Ίσως το μόνο που έχω έχει συνταχθεί κώδικας από έναν πωλητή.)

... και ...

-> Δεν μπορώ να αλλάξω τον καλούντα κωδικό (Ίσως υπάρχουν χιλιάδες αντίγραφα και δεν μπορώ να τα ενημερώσω.)

Αν μπορώ να ενημερώσω την παράγωγη κλάση, τότε μπορώ να αλλάξω το αποτέλεσμα που επέστρεψα. (Για παράδειγμα, ο κώδικας θα μπορούσε να είναι μέρος ενός ενημερωμένου DLL.)

Υπάρχει ένα πρόβλημα. Επειδή είναι τόσο πλήρης και ισχυρός, πρέπει να έχετε την άδεια από τη βασική κλάση για να χρησιμοποιήσετε το Overrides. Αλλά καλά σχεδιασμένες βιβλιοθήκες κώδικα το παρέχουν. (Τα δικα σου οι βιβλιοθήκες κώδικα είναι όλα καλά σχεδιασμένα, έτσι;) Για παράδειγμα, η λειτουργία της Microsoft που χρησιμοποιήσαμε είναι υπερτιμημένη. Ακολουθεί ένα παράδειγμα της σύνταξης.

Δημόσια Overridable Λειτουργία GetHashCode ως ακέραιο

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

Δημόσια υπερκείμενη λειτουργία HashTheName ( ByVal nm ως συμβολοσειρά) ως συμβολοσειρά.

Απαγόρευση της μεθόδου είναι τώρα τόσο απλό όσο παρέχει ένα νέο με τη λέξη-κλειδί Overrides. Το Visual Studio ξανά σας δίνει μια τρέχουσα εκκίνηση συμπληρώνοντας τον κώδικα για εσάς με το AutoComplete. Όταν εισέλθετε ...


Δημόσια παράκαμψη Λειτουργία HashTheName (

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

Δημόσια παράκαμψη Λειτουργία HashTheName ( nm ως συμβολοσειρά) ως συμβολοσειρά. Επιστροφή στο MyBase. HashTheName (nm) Λειτουργία τερματισμού.

Σε αυτήν την περίπτωση, ωστόσο, πρόκειται να αντικαταστήσω τη μέθοδο με κάτι άλλο εξίσου άχρηστο για να επεξηγήσω πώς γίνεται: Η λειτουργία VB.NET που θα αναστρέψει τη συμβολοσειρά.

Δημόσια παράκαμψη Λειτουργία HashTheName ( nm ως συμβολοσειρά) ως συμβολοσειρά. Επιστροφή στη Microsoft. VisualBasic. StrReverse (nm) Λειτουργία τερματισμού.

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


ContactID: 246. BusinessName: Villain Defeaters, GmbH. Hash του BusinessName: HbmG, sretaefeD nialliV. 

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

Ιδιωτικό _Επικοινωνήστε με το ID ως ακέραιο. Το δημόσιο αγνοεί την ιδιότητα ContactID ως ακέραιο. Παίρνω. Επιστρέψτε το _ContactID. Τέλος Πάρτε. Ορισμός (τιμή ByVal ως ακέραιο) Αν τιμή> 123 Στη συνέχεια. _ContactID = 111. Αλλού. _ContactID = τιμή. Τέλος εαν. Ορισμός τέλους. End Property.

Στη συνέχεια, παίρνετε αυτό το αποτέλεσμα όταν περάσει μια μεγαλύτερη τιμή:


ContactID: 111. Όνομα επιχείρησης: Damsel Rescuers, LTD. 

Παρεμπιπτόντως, στον κωδικό παράδειγμα μέχρι τώρα, οι τιμές ακέραιας διπλασιάζονται στο νέο υπορουτίνα (Δείτε το άρθρο σχετικά με τις Σκιές), οπότε ένας ακέραιος αριθμός 123 αλλάζει σε 246 και στη συνέχεια αλλάζει και πάλι στο 111.

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

Επειδή η προεπιλογή για μια δημόσια τάξη είναι NotOverridable, γιατί θα έπρεπε ποτέ να το καθορίσετε; Εάν το δοκιμάσετε στη λειτουργία HashTheName στη βασική κλάση, θα εμφανιστεί ένα σφάλμα σύνταξης, αλλά το κείμενο του μηνύματος σφάλματος σας δίνει μια ιδέα:

Δεν είναι δυνατός ο ορισμός του 'NotOverridable' για μεθόδους που δεν παρακάμπτουν κάποια άλλη μέθοδο.

Η προεπιλογή για μια υπερτιμημένη μέθοδο είναι ακριβώς το αντίθετο: Overridable. Επομένως, αν θέλετε να σταματήσετε σίγουρα εκεί, πρέπει να καθορίσετε το NotOverridable σε αυτή τη μέθοδο. Στο παράδειγμα κώδικα:


Δημόσιο μη αμφισβητήσιμο Αντικαθιστά Λειτουργία HashTheName (... 

Στη συνέχεια, εάν η κλάση CodedProfessionalContact, με τη σειρά της, κληρονομήσει ...


Δημόσια κλάση NotOverridableEx. Κληρονομεί κωδικοποιημένη επαγγελματική επικοινωνία. 

... η λειτουργία HashTheName δεν μπορεί να αντικατασταθεί σε αυτήν την κλάση. Ένα στοιχείο που δεν μπορεί να αντικατασταθεί ονομάζεται μερικές φορές σφραγισμένο στοιχείο.

Βασικό μέρος του ο .NET Foundation είναι να απαιτείται ο σκοπός κάθε τάξης να ορίζεται σαφώς για να καταργηθεί κάθε αβεβαιότητα. Ένα πρόβλημα σε προηγούμενες γλώσσες OOP ονομάστηκε "εύθραυστη βασική κλάση". Αυτό συμβαίνει όταν μια βάση class προσθέτει μια νέα μέθοδο με το ίδιο όνομα με ένα όνομα μεθόδου σε μια υποκατηγορία που κληρονομεί από μια βάση τάξη. Ο προγραμματιστής που γράφει την υποκλάση δεν σχεδίαζε να παρακάμπτει την τάξη βάσης, αλλά αυτό ακριβώς συμβαίνει ούτως ή άλλως. Αυτό είναι γνωστό ότι έχει ως αποτέλεσμα την κραυγή του πληγωμένου προγραμματιστή, "Δεν άλλαξα τίποτα, αλλά το πρόγραμμά μου κατέρρευσε ούτως ή άλλως. "Εάν υπάρχει πιθανότητα η τάξη να ενημερωθεί στο μέλλον και να δημιουργηθεί αυτό το πρόβλημα, δηλώστε το NotOverridable.

Το MustOverride χρησιμοποιείται συχνότερα σε αυτό που ονομάζεται Abstract Class. (Στο C #, το ίδιο πράγμα χρησιμοποιεί τη λέξη-κλειδί Abstract!) Αυτή είναι μια κλάση που παρέχει μόνο ένα πρότυπο και αναμένεται να το γεμίσετε με τον δικό σας κώδικα. Η Microsoft παρέχει αυτό το παράδειγμα ενός:

Δημόσια MustInherit Class WashingMachine. Υπο Νέο () "Ο κώδικας για την παράσταση της κλάσης πηγαίνει εδώ. Τέλος δευτερεύοντος. Δημόσια MustOverride Sub Wash. Δημόσια MustOverride Sub Rinse (φόρτωση ως αθροιστής) Δημόσια λειτουργία MustOverride Spin (ταχύτητα ως ακέραιος) όσο καιρό. Τέλος κλάσης.

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

Εάν χρειάζεστε ακόμη περισσότερες εξηγήσεις σχετικά με τις διαφορές μεταξύ υπερφορτώσεων και αντικαταστάσεων, αναπτύσσεται ένα εντελώς διαφορετικό παράδειγμα σε μια γρήγορη συμβουλή: Overloads Versus Overrides

Το VB.NET σας δίνει ακόμα μεγαλύτερο έλεγχο, επιτρέποντας σε μια βασική κλάση να απαιτεί ή να εμποδίσει ειδικά μια παράγωγο κλάση να παρακάμψει χρησιμοποιώντας τις MustOverride και NotOverridable λέξεις-κλειδιά της βασικής κλάσης. Αλλά και οι δύο χρησιμοποιούνται σε αρκετά συγκεκριμένες περιπτώσεις. Πρώτον, NotOverridable.

Επειδή η προεπιλογή για μια δημόσια τάξη είναι NotOverridable, γιατί θα έπρεπε ποτέ να το καθορίσετε; Εάν το δοκιμάσετε στη λειτουργία HashTheName στη βασική κλάση, θα εμφανιστεί ένα σφάλμα σύνταξης, αλλά το κείμενο του μηνύματος σφάλματος σας δίνει μια ιδέα:

Δεν είναι δυνατός ο ορισμός του 'NotOverridable' για μεθόδους που δεν παρακάμπτουν κάποια άλλη μέθοδο.

Η προεπιλογή για μια υπερτιμημένη μέθοδο είναι ακριβώς το αντίθετο: Overridable. Επομένως, αν θέλετε να σταματήσετε σίγουρα εκεί, πρέπει να καθορίσετε το NotOverridable σε αυτή τη μέθοδο. Στο παράδειγμα κώδικα:


Δημόσιο μη αμφισβητήσιμο Αντικαθιστά Λειτουργία HashTheName (... 

Στη συνέχεια, εάν η κλάση CodedProfessionalContact, με τη σειρά της, κληρονομήσει ...


Δημόσια κλάση NotOverridableEx. Κληρονομεί κωδικοποιημένη επαγγελματική επικοινωνία. 

... η λειτουργία HashTheName δεν μπορεί να αντικατασταθεί σε αυτήν την κλάση. Ένα στοιχείο που δεν μπορεί να αντικατασταθεί ονομάζεται μερικές φορές σφραγισμένο στοιχείο.

Ένα θεμελιώδες μέρος του .NET Foundation είναι να απαιτεί ότι ο σκοπός κάθε τάξης ορίζεται ρητά για να καταργηθεί κάθε αβεβαιότητα. Ένα πρόβλημα σε προηγούμενες γλώσσες OOP ονομάστηκε "εύθραυστη βασική κλάση". Αυτό συμβαίνει όταν μια βάση class προσθέτει μια νέα μέθοδο με το ίδιο όνομα με ένα όνομα μεθόδου σε μια υποκατηγορία που κληρονομεί από μια βάση τάξη. Ο προγραμματιστής που γράφει την υποκλάση δεν σχεδίαζε να παρακάμπτει την τάξη βάσης, αλλά αυτό ακριβώς συμβαίνει ούτως ή άλλως. Αυτό είναι γνωστό ότι έχει ως αποτέλεσμα την κραυγή του πληγωμένου προγραμματιστή, "Δεν άλλαξα τίποτα, αλλά το πρόγραμμά μου κατέρρευσε ούτως ή άλλως. "Εάν υπάρχει πιθανότητα η τάξη να ενημερωθεί στο μέλλον και να δημιουργηθεί αυτό το πρόβλημα, δηλώστε το NotOverridable.

Το MustOverride χρησιμοποιείται συχνότερα σε αυτό που ονομάζεται Abstract Class. (Στο C #, το ίδιο πράγμα χρησιμοποιεί τη λέξη-κλειδί Abstract!) Αυτή είναι μια κλάση που παρέχει μόνο ένα πρότυπο και αναμένεται να το γεμίσετε με τον δικό σας κώδικα. Η Microsoft παρέχει αυτό το παράδειγμα ενός:

Δημόσια MustInherit Class WashingMachine. Υπο Νέο () "Ο κώδικας για την παράσταση της κλάσης πηγαίνει εδώ. Τέλος δευτερεύοντος. Δημόσια MustOverride Sub Wash. Δημόσια MustOverride Sub Rinse (φόρτωση ως αθροιστής) Δημόσια λειτουργία MustOverride Spin (ταχύτητα ως ακέραιος) όσο καιρό. Τέλος κλάσης.

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

Εάν χρειάζεστε ακόμη περισσότερες εξηγήσεις σχετικά με τις διαφορές μεταξύ υπερφορτώσεων και αντικαταστάσεων, αναπτύσσεται ένα εντελώς διαφορετικό παράδειγμα σε μια γρήγορη συμβουλή: Overloads Versus Overrides

instagram story viewer