Κληρονομικότητα Kotlin (με παραδείγματα)

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

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

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

Πριν εξετάσετε λεπτομέρειες σχετικά με την κληρονομιά του Kotlin, σας συνιστούμε να ελέγξετε αυτά τα δύο άρθρα:

  • Κατηγορία και αντικείμενα Kotlin
  • Πρωταρχικός κατασκευαστής Kotlin

Γιατί κληρονομιά;

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

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

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

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

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

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

Χρησιμοποιώντας κληρονομιά, τώρα που δεν εφαρμόζουν τον ίδιο κωδικό για walk(), talk()και eat()για κάθε κατηγορία. Απλά πρέπει να τα κληρονομήσετε .

Έτσι, για την MathTeacher(παράγωγη κλάση), κληρονομείτε όλες τις δυνατότητες μιας Person(βασικής κλάσης) και προσθέτετε μια νέα δυνατότητα teachMath(). Ομοίως, για την Footballerτάξη, κληρονομείτε όλες τις δυνατότητες της Personτάξης και προσθέτετε μια νέα δυνατότητα playFootball()και ούτω καθεξής.

Αυτό καθιστά τον κώδικα καθαρότερο, κατανοητό και επεκτάσιμο.

Είναι σημαντικό να θυμάστε: Όταν εργάζεστε με κληρονομιά, κάθε παράγωγη τάξη πρέπει να πληροί την προϋπόθεση εάν "είναι" βασική τάξη ή όχι. Στο παραπάνω παράδειγμα, MathTeacher είναι α Person , Footballer είναι α Person . Δεν μπορείς να έχεις κάτι σαν, Businessman είναι Business .

Κληρονομιά του Κότλιν

Ας προσπαθήσουμε να εφαρμόσουμε την παραπάνω συζήτηση σε κώδικα:

 ανοιχτή τάξη Πρόσωπο (ηλικία: Int) (// κωδικός για φαγητό, ομιλία, περπάτημα) μάθημα MathTeacher (ηλικία: Int): Πρόσωπο (ηλικία) (// άλλα χαρακτηριστικά του καθηγητή μαθηματικών) τάξη Ποδοσφαιριστής (ηλικία: Int): Πρόσωπο ( age) (// άλλα χαρακτηριστικά του ποδοσφαιριστή) τάξη Επιχειρηματίας (ηλικία: Int): Άτομο (ηλικία) (// άλλα χαρακτηριστικά του επιχειρηματία)

Εδώ, Personείναι μια βασική κλάση, και τάξεις MathTeacher, Footballerκαι Businessmanπροέρχονται από την κλάση Person.

Ανακοίνωση, η λέξη-κλειδί openπριν από την κλάση βάσης, Person. Είναι σημαντικό.

Από προεπιλογή, τα μαθήματα στο Kotlin είναι οριστικά. Εάν είστε εξοικειωμένοι με την Java, γνωρίζετε ότι δεν είναι δυνατή η υποκατηγορία μιας τελικής τάξης. Χρησιμοποιώντας τον ανοιχτό σχολιασμό σε μια τάξη, ο μεταγλωττιστής σάς επιτρέπει να αντλείτε νέες τάξεις από αυτήν.

Παράδειγμα: Κληρονομικότητα Kotlin

 open class Person(age: Int, name: String) ( init ( println("My name is $name.") println("My age is $age") ) ) class MathTeacher(age: Int, name: String): Person(age, name) ( fun teachMaths() ( println("I teach in primary school.") ) ) class Footballer(age: Int, name: String): Person(age, name) ( fun playFootball() ( println("I play for LA Galaxy.") ) ) fun main(args: Array) ( val t1 = MathTeacher(25, "Jack") t1.teachMaths() println() val f1 = Footballer(29, "Christiano") f1.playFootball() )

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

Το όνομα μου είναι τζάκ. Η ηλικία μου είναι 25 διδάσκω στο δημοτικό σχολείο. Το όνομά μου είναι Cristiano. Η ηλικία μου είναι 29, παίζω για το LA Galaxy.

Εδώ, δύο τάξεις MathTeacherκαι Footballerπροέρχονται από την Personτάξη.

Ο κύριος κατασκευαστής της Personκλάσης δήλωσε δύο ιδιότητες: ηλικία και όνομα και έχει ένα μπλοκ αρχικοποιητή. Το μπλοκ initilizer (και οι λειτουργίες μέλους) της κατηγορίας βάσης Personμπορεί να προσεγγιστεί από τα αντικείμενα των παραγόμενων κλάσεων ( MathTeacherκαι Footballer).

Παράγονται τάξεις MathTeacherκαι Footballerέχουν τις δικές τους λειτουργίες μελών teachMaths()και playFootball()αντίστοιχα Αυτές οι λειτουργίες είναι προσβάσιμες μόνο από τα αντικείμενα της αντίστοιχης κατηγορίας τους.

Όταν δημιουργείται το αντικείμενο t1 της MathTeacherκλάσης,

 val t1 = MathTeacher (25, "Τζακ")

Οι παράμετροι μεταβιβάζονται στον κύριο κατασκευαστή. Στο Kotlin, το initμπλοκ καλείται όταν δημιουργείται το αντικείμενο. Δεδομένου ότι MathTeacherπροέρχεται από την Personκλάση, αναζητά μπλοκ αρχικοποιητή στην βασική κλάση (Πρόσωπο) και το εκτελεί. Εάν το MathTeacherμπλοκ init, ο μεταγλωττιστής θα είχε επίσης εκτελέσει το μπλοκ init της προερχόμενης κλάσης.

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

Το πρόγραμμα λειτουργεί με παρόμοιο τρόπο, όταν αντικείμενο f1της Footballerδημιουργείται τάξη. Εκτελεί το μπλοκ init της βασικής κλάσης. Στη συνέχεια, η playFootball()μέθοδος της Footballerτάξης καλείται χρησιμοποιώντας δήλωση f1.playFootball().

Σημαντικές σημειώσεις: Kotlin Inheritance

  • Εάν η κλάση έχει έναν αρχικό κατασκευαστή, η βάση πρέπει να αρχικοποιηθεί χρησιμοποιώντας τις παραμέτρους του πρωτεύοντος κατασκευαστή. Στο παραπάνω πρόγραμμα, και οι δύο παράγωγες κλάσεις έχουν δύο παραμέτρους ageκαι name, και οι δύο αυτές παράμετροι αρχικοποιούνται στον πρωτογενή κατασκευαστή στην κατηγορία βάσης.
    Εδώ είναι ένα άλλο παράδειγμα:
     open class Person(age: Int, name: String) ( // some code ) class Footballer(age: Int, name: String, club: String): Person(age, name) ( init ( println("Football player $name of age $age and plays for $club.") ) fun playFootball() ( println("I am playing football.") ) ) fun main(args: Array) ( val f1 = Footballer(29, "Cristiano", "LA Galaxy") )  
    Εδώ ο κύριος κατασκευαστής της παραγόμενης κλάσης έχει 3 παραμέτρους και η βασική κλάση έχει 2 παραμέτρους Σημειώστε ότι, και οι δύο παράμετροι της κατηγορίας βάσης έχουν αρχικοποιηθεί.
  • Σε περίπτωση που δεν υπάρχει πρωτεύων κατασκευαστής, κάθε βασική κλάση πρέπει να προετοιμάσει τη βάση (χρησιμοποιώντας σούπερ λέξη-κλειδί) ή να αναθέσει σε άλλο κατασκευαστή που το κάνει. Για παράδειγμα,
     fun main(args: Array) ( val p1 = AuthLog("Bad Password") ) open class Log ( var data: String = "" var numberOfData = 0 constructor(_data: String) ( ) constructor(_data: String, _numberOfData: Int) ( data = _data numberOfData = _numberOfData println("$data: $numberOfData times") ) ) class AuthLog: Log ( constructor(_data: String): this("From AuthLog -> + $_data", 10) ( ) constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) ( ) )
    Για να μάθετε περισσότερα σχετικά με τον τρόπο λειτουργίας αυτού του προγράμματος, επισκεφθείτε το Kotlin Secondary Constructor.

Παράκαμψη λειτουργιών και ιδιοτήτων μελών

If the base class and the derived class contains a member function (or property) with the same name, you can need to override the member function of the derived class using override keyword, and use open keyword for the member function of the base class.

Example: Overriding Member Function

 // Empty primary constructor open class Person() ( open fun displayAge(age: Int) ( println("My age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

When you run the program, the output will be:

 My fake age is 26.

Here, girl.displayAge(31) calls the displayAge() method of the derived class Girl.

You can override property of the base class in similar way.

Visit how Kotlin getters and setters work in Kotlin before you check the example below.

 // Empty primary constructor open class Person() ( open var age: Int = 0 get() = field set(value) ( field = value ) ) class Girl: Person() ( override var age: Int = 0 get() = field set(value) ( field = value - 5 ) ) fun main(args: Array) ( val girl = Girl() girl.age = 31 println("My fake age is $(girl.age).") )

When you run the program, the output will be:

 My fake age is 26.

As you can see, we have used override and open keywords for age property in derived class and base class respectively.

Calling Members of Base Class from Derived Class

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

 open class Person() ( open fun displayAge(age: Int) ( println("My actual age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( // calling function of base class super.displayAge(age) println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

Όταν εκτελείτε το πρόγραμμα, η έξοδος θα είναι:

 Η ηλικία μου είναι 31. Η ψεύτικη ηλικία μου είναι 26.

ενδιαφέροντα άρθρα...