English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
L'ereditarietà possiamo intenderla come una classe che acquisisce i metodi e le proprietà di un'altra classe.
Quando una classe eredita da un'altra classe, la classe derivata si chiama sottoclasse, mentre la classe ereditata si chiama superclasse (o classe padre)
In Swift, una classe può chiamare e accedere ai metodi, alle proprietà e agli indici di superclasse, e può sovrascriverli.
Possiamo anche aggiungere osservatori di proprietà alle proprietà ereditate dalla classe.
Una classe che non eredita da altre classi si chiama classe base (Base Class).
Nell'esempio seguente, abbiamo definito la classe base StudDetails, che descrive lo studente (stname) e i punteggi di ciascun esame (mark1, mark2, mark3):
class StudDetails { var stname: String! var mark1: Int! var mark2: Int! var mark3: Int! init(stname: String, mark1: Int, mark2: Int, mark3: Int) { self.stname = stname self.mark1 = mark1 self.mark2 = mark2 self.mark3 = mark3 } } let stname = "swift" let mark1 = 98 let mark2 = 89 let mark3 = 76 let sds = StudDetails(stname:stname, mark1:mark1, mark2:mark2, mark3:mark3); print(sds.stname) print(sds.mark1) print(sds.mark2) print(sds.mark3)
L'output dell'esecuzione del programma sopra è:
swift 98 89 76
La sottoclasse si riferisce a una nuova classe creata sulla base di una classe esistente.
Per indicare la superclasse di una classe, scrivi il nome della superclasse dopo il nome della sottoclasse, separati da due punti (:), e il formato grammaticale è il seguente
class SomeClass: SomeSuperclass { // Definizione della classe }
Nell'esempio seguente, abbiamo definito il superClasse StudDetails e poi l'abbiamo utilizzato per creare il sottoClasse Tom:
class StudDetails { var mark1: Int; var mark2: Int; init(stm1: Int, results: Int) { mark1 = stm1; mark2 = stm2; } func show() { print("Mark1:\(self.mark1), Mark2:\(self.mark2)") } } class Tom: StudDetails { init() { super.init(stm1: 93, results: 89) } } let tom = Tom() tom.show()
L'output dell'esecuzione del programma sopra è:
Mark1:93, Mark2:89
Il sottoClasse può implementare funzionalità personalizzate utilizzando i metodi di esempio, i metodi di classe, gli attributi di esempio o gli script di indici ereditati, che chiamiamo sovrascrittura (overriding).
Possiamo utilizzare la parola chiave override per implementare la sovrascrittura.
Puoi accedere ai metodi, attributi o script di indici del superClasse utilizzando il prefisso super.
Sovrascrittura | Accedi ai metodi, attributi e script di indici |
---|---|
Metodo | super.somemethod() |
Attributo | super.someProperty() |
Script di indici | super[someIndex] |
Nel nostro sottoClasse possiamo utilizzare la parola chiave override per sovrascrivere il metodo del superClasse.
Nell'esempio seguente, abbiamo sovrascritto il metodo show():
class SuperClass { func show() { print("Questo è il superClasse SuperClass") } } class SubClass: SuperClass { override func show() { print("Questo è il sottoClasse SubClass") } } let superClass = SuperClass() superClass.show() let subClass = SubClass() subClass.show()
L'output dell'esecuzione del programma sopra è:
Questo è il superClasse SuperClass Questo è il sottoClasse SubClass
Puoi fornire getter (o setter) personalizzati per sovrascrivere qualsiasi attributo ereditato, indipendentemente dall'attributo essere di tipo memorizzato o calcolato.
La sottoclasse non conosce se l'attributo ereditato è di tipo di memorizzazione o di calcolo, sa solo che l'attributo avrà un nome e un tipo. Pertanto, quando sovrascrivi un attributo, è necessario scrivere sia il nome che il tipo.
Punti di attenzione:
Se fornisci un setter per una proprietà sovrascritta, allora dovrai fornire anche un getter.
Se non vuoi modificare il valore dell'attributo ereditato nel getter della versione sovrascritta, puoi restituire direttamente il valore ereditato tramite super.someProperty, dove someProperty è il nome dell'attributo che vuoi sovrascrivere.
Nell'esempio seguente abbiamo definito la superclasse Cerchio e la sottoclasse Rettangolo, nella classe Rettangolo abbiamo sovrascritto la proprietà area:
class Cerchio { var raggio = 12.5 变量area: String { ritorna "Il raggio del rettangolo è \(raggio) " } } // Eredità superclasse Cerchio class Rectangle: Circle { var stampa = 7 覆盖变量area: String { ritorna super.area + " ,ma ora è sovrascritto da \(stampa)" } } let rettangolo = Rettangolo() rettangolo.raggio = 25.0 rettangolo.stampa = 3 stampa("Raggio \(rettangolo.area)")
L'output dell'esecuzione del programma sopra è:
Raggio rettangolo 25.0 , ma ora è sovrascritto da 3
Puoi aggiungere un osservatore di proprietà a un'attributo ereditato in una sovrascrittura di proprietà. In questo modo, quando il valore di un attributo ereditato cambia, lo monitorerai.
Attenzione:Non puoi aggiungere un osservatore di proprietà a un'attributo di tipo costante o a un'attributo di calcolo readonly ereditato.
class Cerchio { var raggio = 12.5 变量area: String { ritorna "Il raggio del rettangolo è \(raggio) " } } class Rectangle: Circle { var stampa = 7 覆盖变量area: String { ritorna super.area + " ,ma ora è sovrascritto da \(stampa)" } } let rettangolo = Rettangolo() rettangolo.raggio = 25.0 rettangolo.stampa = 3 stampa("Raggio: \(rettangolo.area)") class Quadrato: Rettangolo { 覆盖变量radius: Double { didSet {}} 打印 = Int(半径/5.0)+1 } } } let sq = Square() sq.radius = 100.0 打印("半径: \(sq.area)")
Raggio: Il raggio del rettangolo è 25.0 , ma ora è sovrascritto da 3 Raggio: Il raggio del rettangolo è 100.0 , ma ora è sovrascritto da 21
Possiamo utilizzare la parola chiave final per prevenire che vengano sovrascritti.
Se sovrascrivi un metodo, proprietà o script di indici finali, verrà generato un errore durante la compilazione.
Puoi aggiungere la proprietà final prima del nome della classe (final class) per etichettare l'intera classe come final, tali classi non possono essere ereditate, altrimenti verrà generato un errore di compilazione.
final class Cerchio { 最终变量半径 = 12.5 变量area: String { ritorna "Il raggio del rettangolo è \(raggio) " } } class Rectangle: Circle { var stampa = 7 覆盖变量area: String { ritorna super.area + " ,ma ora è sovrascritto da \(stampa)" } } let rettangolo = Rettangolo() rettangolo.raggio = 25.0 rettangolo.stampa = 3 stampa("Raggio: \(rettangolo.area)") class Quadrato: Rettangolo { 覆盖变量radius: Double { didSet {}} 打印 = Int(半径/5.0)+1 } } } let sq = Square() sq.radius = 100.0 打印("半径: \(sq.area)")
由于以上示例使用了final关键字不允许重写,所以执行会报错:
错误:var覆盖了'final'var 覆盖变量area: String { ^ 注意:覆盖声明在这里 变量area: String { ^ 错误:var覆盖了'final'var 覆盖变量radius: Double { ^ 注意:覆盖声明在这里 最终变量半径 = 12.5 ^ 错误:从最终类'Circle'继承 class Rectangle: Circle { ^