Masukkan Password
46 Use of this in Dart | this keyword in Dart | Dart Tutorials #46
Materi ini membahas keyword this di Dart, dan ini sangat penting karena nanti ketika masuk ke Flutter, this akan sering muncul di class, constructor, getter/setter, dan berbagai pola OOP.
Ada dua bentuk this yang perlu kita bedakan:
this
dan:
this(...)
Keduanya terlihat mirip, tetapi fungsinya sangat berbeda.
1. Gambaran besar
Secara sederhana:
| Bentuk | Fungsi |
|---|---|
this | Mengacu ke object saat ini |
this.namaField | Mengakses field milik object saat ini |
this.method() | Memanggil method pada object saat ini |
return this | Mengembalikan object saat ini |
method(this) | Mengirim object saat ini sebagai argument |
this(...) | Mengalihkan constructor ke constructor lain dalam class yang sama |
Jadi jangan sampai tertukar:
this
berarti:
“object yang sedang digunakan sekarang”
Sedangkan:
this(...)
berarti:
“gunakan constructor lain dari class yang sama.”
2. Apa sebenarnya this?
Misalkan kita mempunyai class:
class Person {
String name = "Budi";
void show() {
print(this);
}
}
Kemudian:
void main() {
Person p1 = Person();
p1.show();
}
Ketika kita menjalankan:
p1.show();
object yang memanggil show() adalah:
p1
Maka di dalam show():
this
mengacu ke object p1.
Secara sederhana:
p1
β
βββββββ> Person object
β
β
this
Jadi:
thisadalah referensi ke instance/object yang sedang menjalankan instance method atau constructor tersebut.
3. Kenapa disebut implicit reference?
Misalnya kita membuat:
Person p1 = Person();
p1 adalah reference yang kita buat sendiri.
Kemudian:
p1.show();
Kita secara eksplisit menulis:
p1
Itulah sebabnya video menyebutnya sebagai explicit reference.
Sedangkan:
this
tidak kita buat sendiri.
Dart menyediakan this di context yang memang mempunyai current instance.
Jadi bisa dibayangkan:
Reference yang kita buat:
p1
p2
Reference khusus dari Dart:
this
Tetapi ada satu koreksi kecil terhadap penjelasan video:
this sebaiknya jangan dibayangkan sebagai sekadar “alamat memori object”. Lebih aman memahami this sebagai referensi ke instance saat ini. Detail representasi memori merupakan urusan implementasi Dart.
4. this berubah tergantung object yang memanggil method
Ini konsep yang sangat penting.
Misalnya:
class Person {
void show() {
print(this);
}
}
Kemudian:
void main() {
Person p1 = Person();
Person p2 = Person();
p1.show();
p2.show();
}
Ketika:
p1.show();
yang menjadi current object adalah:
p1
Sehingga:
this β p1
Kemudian ketika:
p2.show();
current object berubah:
this β p2
Jadi:
p1.show()
β
this = p1
p2.show()
β
this = p2
this tidak selalu menunjuk object yang sama.
Ia bergantung pada object mana yang sedang menjalankan instance member tersebut.
5. Contoh dengan field
Misalnya:
class Person {
String name;
Person(this.name);
void show() {
print(this.name);
}
}
Kemudian:
void main() {
Person p1 = Person("Budi");
Person p2 = Person("Andi");
p1.show();
p2.show();
}
Hasil:
Budi
Andi
Ketika:
p1.show();
maka:
this β p1
this.name β p1.name β "Budi"
Ketika:
p2.show();
maka:
this β p2
this.name β p2.name β "Andi"
6. Di mana this boleh digunakan?
Secara konsep dasar, this tersedia pada instance context, terutama:
1. Instance method
class Test {
void demo() {
print(this);
}
}
2. Generative constructor
class Test {
Test() {
print(this);
}
}
Sedangkan pada static method:
class Test {
static void demo() {
print(this); // β
}
}
tidak boleh.
Dan factory constructor juga tidak mempunyai this instance:
class Test {
factory Test.create() {
print(this); // β
return Test();
}
}
Kenapa?
Karena static dan factory tidak berjalan sebagai instance context seperti instance method/generative constructor.
7. Kenapa static method tidak mempunyai this?
Perhatikan:
class Test {
int x = 10;
static void show() {
print(x); // β
}
}
Masalahnya:
x
adalah instance field.
Misalnya ada:
Test t1 = Test();
Test t2 = Test();
Maka ada:
t1.x
t2.x
Pertanyaannya:
Test.show();
show() harus mengambil x milik siapa?
t1.x?
t2.x?
Tidak ada object tertentu.
Karena itu static method tidak mempunyai this.
Instance method
β
punya current object
β
punya this
Static method
β
tidak punya current object
β
tidak punya this
8. Penggunaan paling umum: mengatasi name conflict
Ini salah satu penggunaan this yang paling sering kamu temui.
Misalnya:
class Test {
int x = 10;
void show() {
int x = 20;
print(x);
print(this.x);
}
}
Ada dua x.
Yang pertama:
int x = 10;
adalah instance field.
Yang kedua:
int x = 20;
adalah local variable di dalam show().
9. Apa yang terjadi ketika menulis x?
Di dalam method:
void show() {
int x = 20;
print(x);
}
Dart akan menggunakan variable x yang paling dekat dengan scope tersebut.
Jadi:
print(x);
menghasilkan:
20
Karena x lokal menutupi field x.
10. Bagaimana mengakses field x?
Gunakan:
this.x
Jadi:
void show() {
int x = 20;
print(x);
print(this.x);
}
Output:
20
10
Karena:
x
β
local variable
β
20
Sedangkan:
this.x
β
field milik current object
β
10
11. Ini sangat sering muncul di constructor
Misalnya:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Perhatikan:
String name;
adalah field.
Kemudian:
Person(String name, int age)
memiliki parameter dengan nama yang sama.
Jadi:
this.name = name;
berarti:
this.name
β
field milik object
name
β
parameter constructor
Secara manusia:
“Masukkan nilai parameter
nameke fieldnamemilik object ini.”
Begitu juga:
this.age = age;
12. Cara modern yang lebih singkat
Dart menyediakan initializing formal parameter.
Jadi:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
bisa ditulis:
class Person {
String name;
int age;
Person(this.name, this.age);
}
Ini sangat umum dalam Dart.
Maknanya tetap:
this.name β parameter name
this.age β parameter age
13. this juga bisa digunakan untuk memanggil method object saat ini
Misalnya:
class Test {
void hello() {
print("Hello");
}
void demo() {
this.hello();
}
}
Ketika:
final t = Test();
t.demo();
di dalam demo():
this.hello();
berarti:
Panggil
hello()milik object yang sedang menjalankandemo().
Dalam banyak kasus kita bahkan bisa menulis lebih singkat:
hello();
Jadi:
this.hello();
dan:
hello();
dalam konteks instance biasanya mengarah ke method instance yang sama.
14. this bisa dikirim sebagai argument
Ini penggunaan yang cukup menarik.
Misalnya kita punya:
class Test {
void demo() {
Helper.doSomething(this);
}
}
Kemudian:
class Helper {
static void doSomething(Test obj) {
print("Object diterima");
}
}
Ketika:
final t = Test();
t.demo();
yang terjadi secara konsep:
t.demo()
β
this = t
β
Helper.doSomething(this)
β
Helper.doSomething(t)
Jadi this berarti:
“Kirim object yang sedang menjalankan method ini.”
15. Contoh lebih jelas
class Test {
String name;
Test(this.name);
void sendToHelper() {
Helper.show(this);
}
}
class Helper {
static void show(Test obj) {
print(obj.name);
}
}
void main() {
Test t = Test("Budi");
t.sendToHelper();
}
Output:
Budi
Alurnya:
t.sendToHelper()
β
this = t
β
Helper.show(this)
β
Helper.show(t)
β
obj = t
β
obj.name
β
"Budi"
16. this juga bisa dikembalikan
Misalnya:
class Test {
Test getObject() {
return this;
}
}
return this berarti:
Kembalikan object yang sedang menjalankan method ini.
Contoh:
void main() {
Test t1 = Test();
Test t2 = t1.getObject();
print(identical(t1, t2));
}
Hasil:
true
Karena getObject() mengembalikan object yang sama.
Bukan membuat object baru.
17. Gambaran return this
Misalnya:
t1
β
βΌ
Test object
β
β menjalankan getObject()
β
βΌ
return this
β
βΌ
object yang sama
Sehingga:
Test t2 = t1.getObject();
membuat:
t1 βββ
ββββ object Test yang sama
t2 βββ
Ini juga menjadi dasar untuk beberapa pola seperti method chaining.
18. Sekarang kita masuk ke this(...)
Ini bagian kedua dari video.
Perhatikan:
this(...)
Ini bukan this biasa.
Ini disebut redirecting constructor invocation atau constructor redirection.
Tujuannya:
Mengarahkan constructor yang sedang dipanggil ke constructor lain dalam class yang sama.
19. Contoh sederhana
class Test {
Test() {
print("Default constructor");
}
Test.callMe() : this();
}
Kemudian:
void main() {
Test.callMe();
}
Apa yang terjadi?
Kita memanggil:
Test.callMe();
Tetapi callMe() mengatakan:
: this()
Artinya:
“Untuk membuat object ini, lanjutkan ke constructor
Test().”
Jadi:
Test.callMe()
β
this()
β
Test()
β
"Default constructor"
Output:
Default constructor
20. Kenapa disebut redirecting constructor?
Karena constructor:
Test.callMe()
tidak melakukan proses initialization sendiri.
Dia hanya mengarahkan ke:
Test()
Secara sederhana:
callMe()
β
β redirect
βΌ
Test()
Sehingga kita tidak perlu menulis ulang logic constructor.
21. Contoh dengan named constructor
Misalnya:
class Test {
Test() {
print("Default");
}
Test.demo() {
print("Demo");
}
Test.callMe() : this.demo();
}
Sekarang:
Test.callMe();
akan diarahkan ke:
Test.demo();
Alurnya:
Test.callMe()
β
this.demo()
β
Test.demo()
β
"Demo"
Output:
Demo
22. Bisa meneruskan parameter
Misalnya:
class Test {
Test(int x, int y) {
print("x = $x");
print("y = $y");
}
Test.callMe(int x, int y) : this(x, y);
}
Kemudian:
void main() {
Test.callMe(10, 20);
}
Alurnya:
Test.callMe(10, 20)
β
this(10, 20)
β
Test(10, 20)
Output:
x = 10
y = 20
Jadi parameter dari constructor pertama diteruskan ke constructor tujuan.
23. this vs this(...)
Ini wajib dibedakan.
this
this.name
Artinya:
field
namemilik object saat ini.
Atau:
return this;
Artinya:
kembalikan object saat ini.
this(...)
Test.callMe() : this();
Artinya:
redirect ke constructor lain dalam class yang sama.
Jadi tanda () sangat penting.
24. this(...) hanya digunakan dalam constructor
Misalnya kita mencoba:
class Test {
void demo() {
this(); // β
}
}
Tidak boleh.
Karena:
this()
bukan cara untuk “memanggil object”.
this(...) mempunyai makna khusus dalam constructor redirection.
Tempat yang benar:
class Test {
Test() {}
Test.demo() : this();
}
25. this(...) berbeda dengan super(...)
Kamu juga akan sering menemukan:
super(...)
Bedanya:
this(...)
Memanggil/redirect ke constructor class yang sama.
Test.demo() : this();
Artinya:
Test.demo()
β
Test()
super(...)
Memanggil constructor superclass/parent.
Contoh:
class Parent {
Parent(int x) {
print(x);
}
}
class Child extends Parent {
Child() : super(10);
}
Alurnya:
Child()
β
super(10)
β
Parent(10)
Jadi:
this(...) β constructor sendiri
super(...) β constructor parent
26. this tidak bisa diubah
Video juga menjelaskan bahwa kita tidak bisa melakukan:
this = sesuatu;
Misalnya:
class Test {
void demo() {
this = null; // β
}
}
Tidak diperbolehkan.
Kenapa?
Karena this bukan variable biasa yang bisa kita assign ulang.
Kita tidak bisa mengatakan:
“Mulai sekarang object saat ini diganti menjadi object lain.”
this selalu mengacu ke current instance pada context tersebut.
Jadi:
this = null;
tidak valid.
27. Jangan salah memahami this sebagai “alamat”
Video menggunakan istilah “address”.
Untuk pemula, lebih baik gunakan pemahaman:
thisadalah referensi ke object/instance yang sedang aktif menjalankan instance member.
Jangan membuat kesimpulan:
this = memory address
karena itu terlalu menyederhanakan cara Dart mengelola object.
Yang perlu kamu pahami:
this
β object saat ini.
28. Hubungan dengan constructor yang sudah kita pelajari
Sebelumnya kita belajar:
class Person {
String name;
int age;
Person(this.name, this.age);
}
Sekarang kamu sudah bisa memahami this.name dengan lebih dalam.
Pada:
Person(this.name, this.age);
this.name berarti:
field
namemilik object yang sedang dibuat.
Dan:
this.age
berarti:
field
agemilik object yang sedang dibuat.
Ini disebut initializing formal parameter.
29. Contoh lengkap semua konsep
Perhatikan:
class Person {
String name;
int age;
Person(this.name, this.age);
Person.guest() : this("Guest", 0);
void show() {
print("Name: ${this.name}");
print("Age: ${this.age}");
}
Person getCurrentObject() {
return this;
}
}
Kemudian:
void main() {
Person p1 = Person("Budi", 20);
p1.show();
Person p2 = p1.getCurrentObject();
print(identical(p1, p2));
Person p3 = Person.guest();
p3.show();
}
Hasil:
Name: Budi
Age: 20
true
Name: Guest
Age: 0
Mari kita lihat satu-satu.
this.name
print(this.name);
Mengakses field name milik object saat ini.
return this
return this;
Mengembalikan object saat ini.
Karena p1.getCurrentObject() mengembalikan object p1, maka:
identical(p1, p2)
menghasilkan:
true
this(...)
Person.guest() : this("Guest", 0);
Constructor guest() melakukan redirect ke:
Person("Guest", 0);
Jadi tidak perlu menulis ulang initialization.
30. Hubungannya dengan encapsulation
this juga sering muncul bersama private field dan getter/setter.
Misalnya:
class User {
String _name;
User(this._name);
String get name {
return this._name;
}
set name(String value) {
this._name = value;
}
}
Walaupun dalam contoh ini this sebenarnya bisa dihilangkan:
String get name => _name;
set name(String value) {
_name = value;
}
this tetap berguna untuk memperjelas:
“Saya sedang mengakses field milik object ini.”
31. Ringkasan fungsi this
Ada beberapa pola yang harus kamu kenali.
1. Mengakses field
this.name
Artinya:
namemilik current object.
2. Memanggil method
this.show();
Artinya:
panggil
show()milik current object.
3. Mengatasi konflik nama
class Person {
String name;
Person(String name) {
this.name = name;
}
}
Kiri:
this.name
= field.
Kanan:
name
= parameter.
4. Mengirim current object
Helper.process(this);
Artinya:
kirim object saat ini ke
process().
5. Mengembalikan current object
return this;
Artinya:
kembalikan object saat ini.
6. Constructor redirection
Person.guest() : this("Guest", 0);
Artinya:
arahkan constructor ini ke constructor lain dalam class yang sama.
32. this vs this(...) β tabel paling penting
| Kode | Makna |
|---|---|
this | current object |
this.name | field name milik current object |
this.show() | method show() milik current object |
return this | mengembalikan current object |
someMethod(this) | mengirim current object |
this(...) | constructor redirection |
super(...) | memanggil constructor superclass |
33. Cara mudah mengingatnya
Bayangkan setiap object bisa berkata:
“Saya sendiri.”
Dalam Dart, cara object mengatakan “saya sendiri” adalah:
this
Misalnya:
this.name
berarti:
“name saya.”
this.show()
berarti:
“jalankan method show saya.”
return this
berarti:
“kembalikan saya.”
Tetapi kalau:
this(...)
maknanya berubah menjadi:
“Untuk constructor ini, lanjutkan proses pembuatannya melalui constructor lain di class yang sama.”
34. Kesimpulan besar
Ada dua this yang harus kamu kuasai:
this
Digunakan untuk merujuk ke current instance/object.
Contoh:
this.name
this.show()
return this
someFunction(this)
Biasanya muncul pada:
- instance method
- generative constructor
Dan tidak tersedia sebagai instance reference pada static method maupun factory constructor.
this(...)
Digunakan untuk constructor redirection.
Contoh:
class Person {
Person(this.name);
Person.guest() : this("Guest");
String name;
}
Ketika:
Person.guest();
yang terjadi:
Person.guest()
β
this("Guest")
β
Person("Guest")
π§ Hafalan paling sederhana
this= object saya saat ini.
this.field= field milik object saya.
return this= kembalikan object saya.
this(...)= redirect ke constructor saya yang lain.
super(...)= panggil constructor parent saya.
Kalau konsep ini sudah kamu pahami, nanti saat melihat kode Flutter seperti:
class MyWidget extends StatelessWidget {
final String title;
const MyWidget({
super.key,
required this.title,
});
@override
Widget build(BuildContext context) {
return Text(this.title);
}
}
kamu tidak lagi melihat this.title sebagai sesuatu yang misterius. Kamu tahu bahwa this.title berarti field title milik object MyWidget yang sedang dibuat/digunakan.