Sobes.tech
Junior

Εξηγήστε πώς λειτουργεί η λέξη-κλειδί 'super' στη γλώσσα Kotlin.

sobes.tech AI

Απάντηση από AI

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

Οι κύριες χρήσεις:

  1. Κλήση του κατασκευαστή της γονικής κλάσης: Συχνά χρησιμοποιείται στον κατασκευαστή της υποκλάσης για να καλέσει τον αντίστοιχο κατασκευαστή της γονικής. Αυτό είναι υποχρεωτικό αν η γονική κλάση έχει έναν κύριο κατασκευαστή με παραμέτρους.

    open class Parent(val name: String)
    
    class Child(name: String) : Parent(name) {
        // Ο κατασκευαστής Child καλεί τον κατασκευαστή Parent,
        // περνώντας την παράμετρο name.
    }
    
  2. Πρόσβαση στα μέλη της γονικής κλάσης, που έχουν υπερεκχωρηθεί στην υποκλάση: Επιτρέπει την πρόσβαση στην υλοποίηση μιας μεθόδου ή ιδιότητας στην γονική κλάση, ακόμα και αν έχουν υπερεκχωρηθεί (με override) στην υποκλάση.

    open class Base {
        open fun greet() {
            println("Hello from Base")
        }
    
        open val value: Int = 1
    }
    
    class Derived : Base() {
        override fun greet() {
            super.greet() // Κλήση της greet() από την Base
            println("Hello from Derived")
        }
    
        override val value: Int = 2
            get() {
                println("Πρόσβαση στην τιμή του Derived")
                return super.value + 1 // Πρόσβαση στην τιμή από την Base
            }
    }
    
  3. Πρόσβαση σε μέλη συγκεκριμένου υπερτύπου (σε περίπτωση πολλαπλής κληρονομικότητας διεπαφών): Αν μια κλάση υλοποιεί πολλές διεπαφές που έχουν μέλη με τα ίδια ονόματα, το super σε συνδυασμό με την αναφορά του ονόματος της διεπαφής σε αγκύλες (super<TypeName>) επιτρέπει να δηλωθεί με σαφήνεια σε ποιο μέλος ποιας διεπαφής αναφέρεται.

    interface MyInterface1 {
        fun foo() { println("MyInterface1 foo") }
    }
    
    interface MyInterface2 {
        fun foo() { println("MyInterface2 foo") }
    }
    
    class MyClass : MyInterface1, MyInterface2 {
        override fun foo() {
            super<MyInterface1>.foo() // Κλήση του foo() από MyInterface1
            super<MyInterface2>.foo() // Κλήση του foo() από MyInterface2
        }
    }