Προγραμματισμός

Εσωτερικές τάξεις

Ε: Λοιπόν, ποιες είναι οι καλές εσωτερικές τάξεις;

ΕΝΑ: Οι εσωτερικές τάξεις φωλιάζουν σε άλλες τάξεις. Μια κανονική τάξη είναι ένα άμεσο μέλος ενός πακέτου, μια κατηγορία ανώτατου επιπέδου. Τα εσωτερικά μαθήματα, τα οποία διατέθηκαν με το Java 1.1, διατίθενται σε τέσσερις γεύσεις:

  • Στατικές τάξεις μελών
  • Τάξεις μελών
  • Τοπικές τάξεις
  • Ανώνυμα μαθήματα

Ας ρίξουμε μια γρήγορη ματιά σε κάθε σειρά.

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

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

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

Τέλος, ένα Ανώνυμος class είναι μια τοπική τάξη που δεν έχει όνομα.

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

Το αντικειμενοστρεφόμενο πλεονέκτημα

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

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

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

Το οργανωτικό πλεονέκτημα

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

πακέτο1 τάξη 1 τάξη 2 ... τάξη ν ... πακέτο ν 

Με εσωτερικές τάξεις μπορούμε να κάνουμε τα εξής:

πακέτο 1 τάξη 1 τάξη 2 τάξη 1 τάξη 2 ... τάξη ν 

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

Το πλεονέκτημα επανάκλησης

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

Τα περισσότερα Java GUI έχουν κάποιο είδος στοιχείου που υποκινεί ένα actionPerformed () μέθοδος κλήσης. Δυστυχώς, οι περισσότεροι προγραμματιστές έχουν απλώς το κύριο παράθυρο εφαρμογής τους ActionListener. Ως αποτέλεσμα, όλα τα στοιχεία μοιράζονται το ίδιο actionPerformed () μέθοδος. Για να καταλάβετε ποια συνιστώσα πραγματοποίησε τη δράση, υπάρχει συνήθως ένας τεράστιος, άσχημος διακόπτης στο actionPerformed () μέθοδος.

Ακολουθεί ένα παράδειγμα μονολιθικής εφαρμογής:

δημόσια τάξη Το SomeGUI επεκτείνει το JFrame υλοποιεί το ActionListener {προστατευμένο κουμπί JButton1; προστατευμένο κουμπί JButton2; ... προστατευμένο κουμπί JButtonN; public void actionPerformed (ActionEvent e) {if (e.getSource () == button1) {// κάνει κάτι} άλλο αν (e.getSource () == button2) {... έχετε τη φωτογραφία 

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

Αντ 'αυτού, μπορούμε να ορίσουμε μια εσωτερική τάξη που εφαρμόζει ActionListener για κάθε στοιχείο στο οποίο θέλουμε να ακούσουμε. Αυτό μπορεί να οδηγήσει σε πολλές εσωτερικές τάξεις. Ωστόσο, μπορούμε να αποφύγουμε τις μεγάλες δηλώσεις εναλλαγής και να έχουμε το πρόσθετο πλεονέκτημα της ενθυλάκωσης της λογικής δράσης μας. Επιπλέον, αυτή η προσέγγιση μπορεί να βελτιώσει την απόδοση. Σε ένα διακόπτη όπου υπάρχουν ν συγκρίσεις, μπορούμε να περιμένουμε n / 2 συγκρίσεις στη μέση περίπτωση. Οι εσωτερικές τάξεις μας επιτρέπουν να δημιουργήσουμε μια αντιστοιχία 1: 1 μεταξύ του εκτελεστή δράσης και του ακροατή δράσης. Σε ένα μεγάλο GUI, τέτοιες βελτιστοποιήσεις μπορούν να επηρεάσουν σημαντικά την απόδοση. Μια ανώνυμη προσέγγιση μπορεί να μοιάζει με αυτήν:

δημόσια τάξη Το SomeGUI επεκτείνει το JFrame {... δηλώσεις μελών κουμπιού ... προστατευμένο κενό buildGUI () {button1 = νέο JButton (); button2 = νέο JButton (); ... button1.addActionListener (νέο java.awt.event.ActionListener () {public void actionPerformed (java.awt.event.ActionEvent e) {// κάνει κάτι}}); .. επαναλάβετε για κάθε κουμπί 

Χρησιμοποιώντας εσωτερικές τάξεις μελών, το ίδιο πρόγραμμα θα μοιάζει με αυτό:

δημόσια τάξη Το SomeGUI επεκτείνει το JFrame {... δηλώσεις μελών κουμπιών // εσωτερικοί ορισμοί κλάσης Το κουμπί Button1Handler εφαρμόζει το ActionListener {public void actionPerformed (ActionEvent e) {// do something}} ... ορίστε μια εσωτερική κλάση μέλους για κάθε κουμπί που προστατεύεται από άκυρο buildGUI () {// αρχικοποίηση του κουμπιού1 = νέο JButton (); button2 = νέο JButton (); ... // καταχωρίστε μια παρουσία ακροατή εσωτερικής τάξης // για κάθε κουμπί button1.addActionListener (νέο Button1Handler ()); .. επαναλάβετε για κάθε κουμπί 

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

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

Μειονεκτήματα;

Όπως με οτιδήποτε άλλο, πρέπει να πάρετε το καλό με το κακό. Οι εσωτερικές τάξεις έχουν τα μειονεκτήματά τους. Από άποψη συντήρησης, οι άπειροι προγραμματιστές Java ενδέχεται να δυσκολεύονται να κατανοήσουν την εσωτερική τάξη. Η χρήση εσωτερικών τάξεων θα αυξήσει επίσης τον συνολικό αριθμό τάξεων στον κωδικό σας. Επιπλέον, από την άποψη της ανάπτυξης, τα περισσότερα εργαλεία Java καταλήγουν λίγο στην υποστήριξη των εσωτερικών τάξεων. Για παράδειγμα, χρησιμοποιώ το VisualAge για Java της IBM για την καθημερινή μου κωδικοποίηση. Ενώ οι εσωτερικές τάξεις θα μεταγλωττιστούν στο VisualAge, δεν υπάρχει πρόγραμμα περιήγησης ή πρότυπο εσωτερικής κλάσης. Αντ 'αυτού, πρέπει απλά να πληκτρολογήσετε την εσωτερική τάξη απευθείας στον ορισμό της τάξης. Αυτό δυστυχώς καθιστά δύσκολη την περιήγηση στην εσωτερική τάξη. Είναι επίσης δύσκολο να πληκτρολογήσετε, καθώς χάνετε πολλά από τα βοηθήματα ολοκλήρωσης κώδικα του VisualAge όταν πληκτρολογείτε τον ορισμό κλάσης ή χρησιμοποιείτε μια εσωτερική κλάση.

Ο Tony Sintes είναι ανώτερος σύμβουλος της ObjectWave, ειδικεύεται στις τηλεπικοινωνίες. Ο Sintes, ένας προγραμματιστής Java 1.1 και προγραμματιστής Java 2 πιστοποιημένος από την Sun, συνεργάζεται με την Java από το 1997.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Η "Inner Classes Specification" από την Sun παρέχει μια σε βάθος ματιά στις εσωτερικές τάξεις

    //java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html

Αυτή η ιστορία, "Εσωτερικά μαθήματα" δημοσιεύθηκε αρχικά από την JavaWorld.