Els objectes emmagatzemen dades mitjançant propietats (vals i vars) i efectuen operacions amb aquestes dades mitjançant funcions.
Introducció
Considera la classe IntRange
de Kotlin.
La classe IntRange
defineix propietats i funcions per al que és essencialment un tipus de dada nou.
Pots crear un objecte IntRange
(o una “instància”) utilitzant el constructor d’IntRange
.
fun main() {
val range = IntRange(1, 10)
Això crea un objecte IntRange
que representa el rang d’enters de l’1 al 10.
Hi ha nombroses operacions disponibles per a un objecte IntRange
.
Algunes són directes, com sum()
.
Per cridar una funció membre d’un objecte, comença amb l’identificador de l’objecte, després un punt i després el nom de l’operació:
fun main() {
val range = IntRange(1, 10)
require(range.sum() == 55)
}
Un IntRange
és un tipus d’objecte, i una característica definidora d’un objecte és que hi efectues operacions. En lloc de “efectuar una operació”, diem cridar una funció membre.
Com que sum()
és una funció membre definida per a IntRange
, la crides amb range.sum()
. Això suma tots els nombres dins d’aquest IntRange
i en retorna el resultat.
Les classes poden tenir moltes operacions (funcions membre). És fàcil explorar les classes amb Idea, que inclou una funcionalitat anomenada autocompleció de codi.
Si després del punt .
prems les tecles Ctrl + Space, l’IDE mostra les opcions disponibles.
Per exemple, si escrius .s
després de l’identificador d’un objecte, et mostrarà tots els membres d’aquell objecte que comencen per s
.
A més, per aprendre sobre una funció membre concreta, la pots consultar a la documentació oficial: Kotlin Lang - IntRange
En aquest enllaç està la documentació de la classe IntRange
. Pots estudiar totes les funcions membre — la interfície de programació d’aplicacions (API) — de la classe.
Encara que ara no n’entenguis la major part, és útil acostumar-se a consultar la documentació de Kotlin
Tot són objectes
En kotlin tot són objectes.
Per exemple, 2
és un objecte:
fun main() {
val number = 2
require(number.minus(2) == 0) { "number is not zero" }
}
A ??? veurem que -
és un alias de la funció minus()
de Int
.
Creating classes
No només pots utilitzar tipus predefinits com IntRange
i Int
, també pots crear els teus propis tipus d’objectes definint classes.
Kotlin utilitza la paraula clau class
per crear un tipus d’objecte nou:
class Rectangle
class Triangle
fun main() {
val r = Rectangle()
val t1 = Triangle()
val t2 = Triangle()
}
Per definir una classe, comença amb la paraula clau class
, seguida per un identificador per a la teva nova classe.
El nom de la classe ha de començar amb una lletra (A-Z, majúscula o minúscula), però pot incloure números i guions baixos. Seguint la convenció, capitalitzem la primera lletra d’un nom de classe.
main.kt
starts by defining two new classes, then creates three objects (also called instances) of those classes.
Com que no són data classes, si fas un “print” de l’objecte …
fun main() {
val t1 = Triangle()
val t2 = Triangle()
print(t1)
print(t2)
}
La part abans de la @
és el nom de la classe i el número després de la @
és l’adreça on es troba l’objecte a la memòria del teu ordinador (notació hexadecimal)
Triangle@5caf905d
Triangle@27716f4
Pots veure que “t1” i “t2” són objectes diferents: cada objecte del teu programa té la seva adreça única.
Les classes definides aquí (Rectangle
i Triangle
) són tan simples com es pot: tota la definició de la classe és una sola línia.
Les classes més complexes utilitzen claus ({
i }
) per crear un cos de classe que conté les característiques i els comportaments per a aquella classe.
Propietats
A diferència d’un data class
, que és un conjunt de val
s (és immutable), un objecte està format per un conjunt de propietats.
Una propietat és una var
o val
que forma part d’una classe.
class Circle {
val pi = 3.14159265359
var radius: Int = 0
}
fun main() {
val c = Circle()
c.radius = 10
require (c.radius == 10)
require(c.pi > 3.14)
}
La var
o val
passa a formar part d’aquella classe, i t’hi has de referir especificant el seu objecte mitjançant la notació de punt, posant un punt entre l’objecte i el nom de la propietat.
La propietat radius
representa l’estat del Circle
corresponent.
fun main() {
val c1 = Circle()
val c2 = Circle()
require(c1.radius == c2.radius)
c2.radius = 10
require(c1.radius != c2.radius)
}
c1.radius
and c2.radius
contain different values, showing that each object has its own storage.
c1.radius
i c2.radius
contenen valors diferents, mostrant que cada objecte té el seu propi emmagatzematge.
Funcions membre
Here, area()
belongs to the Circle
class:
class Circle {
val pi = 3.14159265359
var radius: Int = 0
fun area(): Double = pi * radius * radius
}
Les funcions membres d’una classe es criden (invocan) amb una referència a un “instància” d’aquella classe, seguit d’un punt .
i, a continuació, el nom de la funció i la llista de paràmetres:
fun main() {
val c = Circle()
c.radius = 10
require(c.area().toInt() == 314)
}
Una funció membre actua sobre una instància concreta d’una classe. Quan crides area()
, l’has de cridar amb un objecte.
Durant la crida, area()
pot accedir a altres membres d’aquell objecte:
```kt
class Circle {
val pi = 3.14159265359
var radius: Int = 0
fun area(): Double = pi * radius * radius
}
Les funcions membre tenen accés especial a altres elements dins d’una classe, simplement fent referència a aquests elements pel seu nom, perquè Kotlin fa un seguiment de l’objecte d’interès passant silenciosament una referència a aquell objecte.
Aquesta referència és disponible dins de la funció membre mitjançant la paraula clau this
.
També pots qualificar explícitament l’accés a aquests elements utilitzant this
:
class Circle {
val pi = 3.14159265359
var radius: Int = 0
fun area(): Double = this.pi * this.radius * this.radius
}
Constructors
Un constructor és com una funció membre especial que inicialitza un objecte nou.
La forma més simple d’un constructor és una definició de classe d’una sola línia:
class Rectangle
fun main() {
val r = Rectangle()
}
A main()
, cridar Rectangle()
crea un objecte Rectangle
.
Pots passar informació a un constructor utilitzant una llista de paràmetres, igual que en una funció.
Aquí, el constructor de Rectangle
rep dos arguments, _width
i _height
, que s’utilitzen per inicialitzar les propietats width
i height
:
class Rectangle(_width: Int, _height: Int) {
var width: Int = _width
var height: Int = _height
fun area(): Int = width * height
}
fun main() {
val r = Rectangle(10, 20)
require(r.area() == 200)
}
Crear un objecte Rectangle
requereix els arguments (prova-ho sense cap argument).
Si vols que un paràmetre del constructor esdevingui una propietat de la classe, el pots definir com a var
o val
a la llista de paràmetres:
class Rectangle(var width: Int, _height: Int) {
var height: Int = _height
fun area(): Int = width * height
}
fun main() {
val r = Rectangle(10, 20)
require(r.area() == 200)
}
Quan width
es defineix com a var
o val
, esdevé una propietat i, per tant, és accessible fora del constructor.
Els paràmetres del constructor declarats com a val
no es poden canviar, mentre que els declarats com a var
són mutables.
class Rectangle(var width: Int, var height: Int) {
fun area(): Int = width * height
}
fun main() {
val r = Rectangle(10, 20)
require(r.area() == 200)
}