Kotlin este un limbaj de programare modern care se compilează la Java bytecode. Este gratuit și open source, și promite să facă codificarea pentru Android chiar mai distractiv.
În articolul precedent, ați aflat mai multe despre proprietățile Kotlin, cum ar fi proprietăți de întârziere, extensie și inline. Nu numai că ați învățat despre cursuri avansate, cum ar fi date, enum, imbricate și clase sigilate în Kotlin.
În acest post, veți continua să învățați despre programarea orientată pe obiecte în Kotlin, învățând despre clase abstracte, interfețe și moștenire. Pentru un bonus, veți afla, de asemenea, despre aliasurile de tip.
Kotlin susține clasele abstracte - la fel ca Java, acestea sunt clase pe care niciodată nu intenționați să le creați. O clasă abstractă este incompletă sau inutilă fără niște subclase concrete (ne-abstracte), de la care puteți instanțiza obiecte. O subclasă concretă a unei clase abstracte implementează toate metodele și proprietățile definite în clasa abstractă - altfel subclasa este, de asemenea, o clasă abstractă!
Creați o clasă abstractă cu abstract
modificator (similar cu Java).
clasa abstractă Angajat (val firstName: String, val lastName: String) câștig distractiv abstract (): Double
Rețineți că nu toți membrii trebuie să fie abstracți. Cu alte cuvinte, putem avea implementarea implicită a metodei într-o clasă abstractă.
clasa abstractă Angajat (val firstName: String, val lastName: String) // ... distracție fullName (): String return lastName + "" + firstName;
Aici am creat funcția non-abstractă Numele complet()
într-o clasă abstractă Angajat
. Clasele concrete (subclasele din clasa abstractă) pot înlocui implementarea implicită a metodei abstracte - dar numai dacă metoda are deschis
modificator specificat (veți afla mai multe despre acest lucru în scurt timp).
De asemenea, putem stoca statul în clase abstracte.
clasa abstractă Angajat (val firstName: String, val lastName: String) // ... val propFoo: String = "bla bla"
Chiar dacă clasa abstractă nu definește nici o metodă, trebuie să creăm o subclasă înainte de a o instanțiate, ca în exemplul de mai jos.
programator de clasă (firstName: String, lastName: String): Angajat (firstName, lastName) câștiguri de distracție (): dublu // calculați câștigurile
Al nostru Programator
clasa extinde Angajat
clasă abstractă. În Kotlin folosim un singur caracter de colon (:
) în loc de Java extinde
cuvinte cheie pentru a extinde o clasă sau a implementa o interfață.
Putem apoi crea un obiect de tip Programator
și metodele de apel pe ea - fie în propria sa clasă, fie în superclasa (clasa de bază).
val programmer = programator ("Chike", "Mgbemena") println (programmer.fullName ()) // "Mgbemena Chike"
Un lucru care te-ar putea surprinde este că avem abilitatea de a suprascrie Val
(imuabil) cu var
(mutabil).
open class BaseA (open val baseProp: String) clasa DerivedA: BaseA ("") private var derivatProp: String = "" suprascrie var baseProp: String get () = derivatProp set (valoare) derivedProp = value
Asigurați-vă că utilizați această funcție cu înțelepciune! Fiți conștienți de faptul că nu putem face schimbarea inversă a var
proprietate cu Val
.
O interfață este pur și simplu o colecție de metode asociate care de obicei vă permit să spuneți obiectelor ce trebuie să faceți și, de asemenea, cum să le faceți în mod implicit. (Metodele implicite în interfețe sunt o nouă caracteristică adăugată la Java 8.) Cu alte cuvinte, o interfață este un contract pe care clasele de implementare trebuie să le respecte.
O interfață este definită folosind interfață
cuvânt cheie în Kotlin (similar cu Java).
clasa de rezultate Clasa de rezultate StudentRepository fun getById (id: Long): Student distracție getResultsById (id: Long): Listă
În codul de mai sus, am declarat a StudentRepository
interfață. Această interfață conține două metode abstracte: getById ()
și getResultsById ()
. Rețineți că inclusiv abstract
cuvântul cheie este redundant într-o metodă de interfață, deoarece este deja implicit abstract.
O interfață este inutilă fără unul sau mai mulți implementatori - așa că să creăm o clasă care va implementa această interfață.
class StudentLocalDataSource: StudentRepository suprascrie distracție getResults (id: Long): Listă// punerea în aplicare suprascrie distracție getById (id: Long): Student // face implementare
Aici am creat o clasă StudentLocalDataSource
care implementează StudentRepository
interfață.
Noi folosim trece peste
modificator pentru a eticheta metodele și proprietățile pe care vrem să le redefinem din interfață sau superclasă - aceasta este similară cu @Trece peste
adnotare în Java.
Rețineți următoarele reguli suplimentare de interfețe în Kotlin:
trece peste
modificatorul este obligatoriu în Kotlin - spre deosebire de Java. Să vedem un exemplu de metodă de interfață cu o implementare implicită.
interfață StudentRepository // ... fun delete (student: student) // face implementare
În codul precedent, am adăugat o nouă metodă șterge()
cu o implementare implicită (deși nu am adăugat codul de implementare real pentru demonstrații).
De asemenea, avem libertatea de a suprascrie implementarea implicită dacă vrem.
class StudentLocalDataSource: StudentRepository // ... suprascrie distracție ștergere (student: Student) // face implementare
După cum sa menționat, o interfață Kotlin poate avea proprietăți - dar rețineți că nu poate menține statul. (Cu toate acestea, amintiți clasele abstracte pot menține statul.) Deci, următoarea definiție a interfeței cu o declarație de proprietate va funcționa.
interfață StudentRepository val propFoo: Boolean // va funcționa // ...
Dar dacă încercăm să adăugăm o anumită stare la interfață atribuind o valoare proprietății, nu va funcționa.
interfață StudentRepository val propFoo: Boolean = true // Eroare: inițializatorii proprietăților nu sunt permise în interfețe // ...
Cu toate acestea, o proprietate de interfață în Kotlin poate avea metode getter și setter (deși numai ultima dacă proprietatea este mutable). Rețineți, de asemenea, că proprietatea într-o interfață nu poate avea un câmp de asistență.
interfață StudentRepository var propFoo: Boolean get () = adevărat set (valoare) if (valoare) // face ceva // ...
De asemenea, putem suprascrie o proprietate a interfeței dacă doriți, pentru ao redefini.
class StudentLocalDataSource: StudentRepository // ... suprascrie var propFoo: Boolean get () = set false (valoare) if (value)
Să examinăm un caz în care avem o clasă care implementează mai multe interfețe cu aceeași semnătură de metodă. Cum determină clasa ce metodă de interfață trebuie apelată?
interfața InterfaceA fun funD () interfață InterfaceB fun funD ()
Aici avem două interfețe care au o metodă cu aceeași semnătură fond()
. Să creăm o clasă care implementează aceste două interfețe și suprascrie fond()
metodă.
Clasa classA: InterfaceA, InterfaceB override fun funD () super.funD () // Eroare: Multe supertipuri disponibile, vă rugăm să precizați una dintre ele în paranteze unghiulare, de ex. 'super'
Compilatorul este confuz cu privire la apelarea super.funD ()
pentru că cele două interfețe pe care le implementează clasa au aceeași semnătură de metodă.
Pentru a rezolva această problemă, vom împacheta numele interfeței pentru care dorim să numim metoda în paranteze unghiulare
. (IntelliJ IDEA sau Android Studio vă va oferi un indiciu despre rezolvarea acestei probleme când se cultivă.)
clasa classA: InterfaceA, InterfaceB override fun funD () super.funD ()
Aici o vom numi fond()
Metodă de InterfaceA
. Problema rezolvata!
O nouă clasă (subclasa) este creată prin achiziționarea unui membru al clasei existente (superclass) și, probabil, redefinirea implementării implicite. Acest mecanism este cunoscut sub numele de moştenire în programarea orientată pe obiecte (OOP). Unul dintre lucrurile care îl fac pe Kotlin atât de minunat este că acesta cuprinde atât OOP, cât și paradigme de programare funcțională - toate într-o singură limbă.
Clasa de bază pentru toate clasele din Kotlin este Orice
.
persoană clasă: orice
Orice
tip este echivalent cu Obiect
tipul pe care îl avem în Java.
public open class Orice public open operator distractiv egal (alt: Any?): Boolean public open distracție hashCode (): Int public deschis distracție toString (): String
Orice
tip conține următorii membri: este egal cu ()
, hashCode ()
, Si deasemenea toString ()
metode (similare cu Java).
Clasele noastre nu trebuie să extindă în mod explicit acest tip. Dacă nu specificați în mod explicit ce clasă se extinde, clasa se extinde Orice
implicit. Din acest motiv, de obicei nu trebuie să includeți : Orice
în codul dvs. - facem acest lucru în codul de mai sus pentru demonstrații.
Să ne gândim acum la crearea de clase în Kotlin cu moștenire în minte.
clasa Student clasa Student absolvent: Student ()
În codul de mai sus, Absolvent
clasa extinde superclama Student
. Dar acest cod nu se va compila. De ce? Deoarece sunt clase și metode final
implicit în Kotlin. Cu alte cuvinte, ele nu pot fi prelungite în mod prestabilit - spre deosebire de Java unde clasele și metodele sunt deschise implicit.
Cele mai bune practici de inginerie software vă recomandă să începeți să faceți clasele și metodele final
în mod prestabilit, adică dacă nu sunt destinate în mod specific să fie redefinite sau înlocuite în subclase. Echipa Kotlin (JetBrains) a aplicat această filozofie de codificare și multe alte bune practici de dezvoltare în dezvoltarea acestui limbaj modern.
Pentru a permite ca subclasele să fie create dintr-o superclasă, trebuie să marcați în mod explicit superclaza cu deschis
modificator. Acest modificator se aplică și în cazul oricăror proprietăți sau metode superclass care ar trebui să fie suprascrise de subclase.
curs deschis student
Am pus pur și simplu deschis
modificator înainte de clasă
cuvinte cheie. Am instruit acum compilatorul să ne permită Student
clasa să fie deschisă pentru extindere.
După cum sa afirmat mai devreme, membrii unei clase Kotlin sunt, de asemenea, definitivi în mod implicit.
clase deschise Student open fun schoolFees (): BigDecimal // face implementare
În codul precedent, am marcat Taxe școlare
funcție ca deschis
-astfel încât subclasele să o înlocuiască.
open class Student () override distracție schoolFees (): BigDecimal return super.schoolFees () + calculateSchoolFees () distracție privată calculateSchoolFees (): BigDecimal // calcula și returnează taxele de școală
Aici, deschis Taxe școlare
funcția de la superclaj Student
este suprascris de Absolvent
clasă - prin adăugarea trece peste
modificator înainte de distracţie
cuvinte cheie. Rețineți că dacă înlocuiți un membru al unei superclase sau al unei interfețe, membrul suprem va fi de asemenea deschis
în mod implicit, ca în exemplul de mai jos:
clasa ComputerScienceStudent: GraduateStudent () override distracție schoolFees (): BigDecimal return super.schoolFees () + calculateSchoolFess () distracție privată calculateSchoolFess (): BigDecimal // calcula și returnează taxele de școală
Chiar dacă nu l-am marcat Taxe școlare()
metodă în Absolvent
clasa cu deschis
modificator, îl putem suprascrie - așa cum am făcut în ComputerScienceStudent
clasă. Pentru a preveni acest lucru, trebuie să marcăm membrul suprem final
.
Amintiți-vă că putem adăuga noi funcționalități unei clase - chiar dacă este finală - prin utilizarea funcțiilor de extensie în Kotlin. Pentru o reîmprospătare a funcțiilor de extensie, verificați funcțiile avansate ale postului meu de la Kotlin. De asemenea, dacă aveți nevoie de o reîmprospătare a modului de a da chiar și unei proprietăți noi clasa finală fără a moșteni de la ea, citiți secțiunea privind extensia Proprietăți în postul meu de proprietăți avansate și clase.
Dacă superclajul nostru are un constructor primar în felul următor:
clasa open class Student (val primul nume: String, val lastName: String) // ...
Apoi orice subclasă trebuie să apeleze constructorul primar al superclasei.
clasă deschisă AbsolventăStudent (numeName: String, NumeNumăuie: String): Student (FirstName, lastName) // ...
Putem crea pur și simplu un obiect al Absolvent
clasă ca de obicei:
val absolventStudent = student absolvent ("Jon", "zăpadă") println (absolventStudent.firstName) // Jon
Dacă subclasa dorește să apeleze constructorul superclass de la constructorul său secundar, vom folosi super
cuvânt cheie (similar cu modul în care constructorii superclass sunt invocați în Java).
open class Student: Student // ... teză privată var: String = "" constructor (numeName: String, lastName: String, teză: String): super (FirstName, lastName) this.thesis = teza
Dacă aveți nevoie de un curs de perfecționare pentru constructorii de clasă din Kotlin, vizitați-mi postul de Clase și Obiecte.
Un alt lucru minunat pe care îl putem face în Kotlin este să dăm un tip un pseudonim.
Să vedem un exemplu.
clasa de date Persoana (val name: String, val lastName: String, val age: Int)
În clasa de mai sus, putem aloca Şir
și Int
tipuri pentru Persoană
aliasuri de proprietăți utilizând typealias
modificator în Kotlin. Acest modificator este folosit pentru a crea un alias de orice tip în Kotlin - inclusiv cele pe care le-ați creat.
typealias Nume = String typealias Vârsta = Int clasa de date Persoană (val firstName: Nume, val lastName: Nume, val: Age)
După cum puteți vedea, am creat un pseudonim Nume
și Vârstă
pentru ambele Şir
și Int
tipuri. Am înlocuit acum Nume
și numele de familie
tipul de proprietate în aliasul nostru Nume
-Si deasemenea Int
tip la Vârstă
alias. Rețineți că nu am creat noi tipuri - am creat un alias pentru tipuri.
Acestea pot fi la îndemână atunci când doriți să oferiți un înțeles mai bun sau semantic la tipurile în codbasele dumneavoastră Kotlin. Deci foloseste-le cu intelepciune!
În acest tutorial, ați aflat mai multe despre programarea orientată pe obiecte în Kotlin. Am abordat următoarele:
Dacă ați învățat Kotlin prin seria noastră Kotlin From Scratch, asigurați-vă că ați tastat codul pe care îl vedeți și îl rulați pe IDE. Un sfat excelent pentru a înțelege cu adevărat un nou limbaj de programare (sau orice concept de programare) pe care îl învățați este să vă asigurați că nu doar citiți resursele sau ghidul de învățare, ci și tastați codul real și executați-l!
În următorul tutorial din seria Kotlin From Scratch, veți fi prezentat în tratarea excepțiilor de la Kotlin. Ne vedem în curând!
Pentru a afla mai multe despre limba Kotlin, vă recomand să vizitați documentația Kotlin. Sau verificați câteva dintre celelalte postări pentru dezvoltarea aplicațiilor Android aici pe Envato Tuts!