Interface #
Interface adalah kontrak yang mendefinisikan kumpulan metode dan properti yang harus diimplementasikan oleh kelas yang menerapkannya. Dalam Dart, konsep interface sedikit berbeda dibandingkan dengan bahasa lain seperti Java atau C#. Dart tidak memiliki kata kunci interface
secara eksplisit, tetapi setiap kelas di Dart dapat bertindak sebagai interface. Dengan kata lain, kelas yang ingin bertindak sebagai interface hanya perlu didefinisikan seperti biasa, dan kelas lain dapat mengimplementasikannya.
Konsep Interface dalam Dart #
Di Dart, interface adalah sebuah kontrak yang mendefinisikan metode dan properti yang harus diimplementasikan oleh kelas lain. Kelas tersebut dapat menjadi blueprint (cetak biru) untuk kelas lain yang ingin memiliki perilaku serupa. Untuk menerapkan interface, sebuah kelas harus mengimplementasikan semua metode dan properti yang didefinisikan dalam interface tersebut.
Contoh Sederhana:
class Kendaraan {
void maju() {
print("Kendaraan bergerak maju.");
}
void mundur() {
print("Kendaraan bergerak mundur.");
}
}
class Mobil implements Kendaraan {
@override
void maju() {
print("Mobil bergerak maju.");
}
@override
void mundur() {
print("Mobil bergerak mundur.");
}
}
void main() {
Mobil avanza = Mobil();
avanza.maju(); // Output: Mobil bergerak maju.
avanza.mundur(); // Output: Mobil bergerak mundur.
}
Dalam contoh di atas:
Kendaraan
adalah kelas yang mendefinisikan metodemaju()
danmundur()
.Mobil
adalah kelas yang mengimplementasikan interfaceKendaraan
, sehinggaMobil
harus menyediakan implementasi untuk kedua metode tersebut.
Menerapkan Beberapa Interface #
Dart memungkinkan kelas untuk mengimplementasikan lebih dari satu interface. Ini dilakukan dengan memisahkan setiap interface dengan tanda koma dalam deklarasi kelas.
Contoh:
class Terbang {
void terbang() {
print("Terbang di udara.");
}
}
class Berenang {
void berenang() {
print("Berenang di air.");
}
}
class Bebek implements Terbang, Berenang {
@override
void terbang() {
print("Bebek terbang.");
}
@override
void berenang() {
print("Bebek berenang.");
}
}
void main() {
Bebek donald = Bebek();
donald.terbang(); // Output: Bebek terbang.
donald.berenang(); // Output: Bebek berenang.
}
Dalam contoh ini:
Bebek
mengimplementasikan dua interface (Terbang
danBerenang
), sehinggaBebek
harus mengimplementasikan metodeterbang()
danberenang()
.
Interface dan Inheritance #
Dart juga memungkinkan Anda untuk menggunakan kelas sebagai interface sambil mewarisi kelas lain. Dalam hal ini, kelas yang mengimplementasikan interface masih harus mengimplementasikan semua metode dari interface tersebut, tetapi juga dapat mewarisi implementasi metode dari kelas lain.
Contoh:
class Kendaraan {
void hidupkanMesin() {
print("Mesin dihidupkan.");
}
}
class Mobil implements Kendaraan {
@override
void hidupkanMesin() {
print("Mesin mobil dihidupkan.");
}
}
class MobilBalap extends Mobil {
void hidupkanTurbo() {
print("Turbo dihidupkan!");
}
}
void main() {
MobilBalap ferrari = MobilBalap();
ferrari.hidupkanMesin(); // Output: Mesin mobil dihidupkan.
ferrari.hidupkanTurbo(); // Output: Turbo dihidupkan!
}
Dalam contoh di atas:
MobilBalap
mewarisi dariMobil
, yang mengimplementasikan interfaceKendaraan
.MobilBalap
memiliki akses ke metodehidupkanMesin()
yang diimplementasikan dalamMobil
, serta metodehidupkanTurbo()
yang didefinisikan dalamMobilBalap
itu sendiri.
Abstract Classes vs. Interface #
Meskipun Dart tidak memiliki kata kunci khusus untuk interface, Dart memiliki kelas abstrak (abstract class
) yang sering digunakan dengan cara yang mirip dengan interface di bahasa lain. Kelas abstrak dapat mendefinisikan metode yang harus diimplementasikan oleh kelas turunannya, tetapi juga dapat menyediakan implementasi metode.
- Kelas Abstrak: Bisa memiliki implementasi metode.
- Interface (melalui implementasi kelas): Tidak boleh memiliki implementasi metode (kecuali metode yang berasal dari kelas induk).
Contoh Kelas Abstrak:
abstract class Kendaraan {
void hidupkanMesin();
void maju() {
print("Kendaraan bergerak maju.");
}
}
class Mobil extends Kendaraan {
@override
void hidupkanMesin() {
print("Mesin mobil dihidupkan.");
}
}
void main() {
Mobil avanza = Mobil();
avanza.hidupkanMesin(); // Output: Mesin mobil dihidupkan.
avanza.maju(); // Output: Kendaraan bergerak maju.
}
Dalam contoh ini:
Kendaraan
adalah kelas abstrak dengan metodehidupkanMesin()
yang harus diimplementasikan oleh kelas turunan.Mobil
mengimplementasikanhidupkanMesin()
dan mewarisi implementasimaju()
dariKendaraan
.
Interface sebagai Kontrak dalam Polimorfisme #
Salah satu kegunaan penting dari interface adalah dalam polimorfisme, di mana objek dari berbagai kelas dapat diperlakukan sebagai objek dari tipe yang sama, selama mereka mengimplementasikan interface yang sama.
Contoh:
class Kendaraan {
void bergerak() {
print("Kendaraan bergerak.");
}
}
class Mobil implements Kendaraan {
@override
void bergerak() {
print("Mobil bergerak.");
}
}
class Pesawat implements Kendaraan {
@override
void bergerak() {
print("Pesawat bergerak.");
}
}
void main() {
List<Kendaraan> kendaraan = [Mobil(), Pesawat()];
for (var k in kendaraan) {
k.bergerak(); // Output: Mobil bergerak. Pesawat bergerak.
}
}
Pada contoh di atas:
Mobil
danPesawat
mengimplementasikan interfaceKendaraan
.- Mereka diperlakukan sebagai objek
Kendaraan
dalam daftarkendaraan
dan masing-masing dapat memanggil metodebergerak()
sesuai dengan implementasinya.
Kesimpulan #
Dalam Dart, meskipun tidak ada kata kunci interface
yang eksplisit, kelas apa pun dapat digunakan sebagai interface. Kelas ini bertindak sebagai kontrak yang mendefinisikan metode dan properti yang harus diimplementasikan oleh kelas lain. Dart juga mendukung pengimplementasian beberapa interface sekaligus, yang memberikan fleksibilitas dalam desain sistem. Kelas abstrak sering digunakan untuk tujuan yang mirip dengan interface, tetapi mereka juga dapat menyediakan implementasi metode. Memahami cara kerja interface dan kelas abstrak dalam Dart sangat penting untuk menulis kode yang modular, dapat diperluas, dan dapat dipelihara dengan baik.