Desain Interface di C++
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 61 dari 104.
interface dalam C++ adalah abstract class yang setiap fungsi anggotanya—kecuali destructor (virtual)—bersifat pure virtual. Berbeda dengan abstract class yang dapat berisi beberapa implementasi, interface hanya mendefinisikan operasi yang harus ada, yaitu menetapkan kontrak tanpa perilaku apa pun.
class Drawable {
public:
virtual void draw() = 0;
virtual void resize(double factor) = 0;
virtual ~Drawable() = default;
};Interface Drawable ini menjamin bahwa setiap class yang mengimplementasikannya memiliki method draw() dan resize(), tetapi tidak menjelaskan cara kerjanya. Pemisahan ini sangat berguna: kode dapat bergantung pada interface tanpa mengetahui apa pun tentang tipe konkret.
class Circle : public Drawable {
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override { std::cout << "Drawing circle" << std::endl; }
void resize(double factor) override { radius *= factor; }
};
class Button : public Drawable {
std::string label;
public:
Button(std::string l) : label(l) {}
void draw() override { std::cout << "Drawing button: " << label << std::endl; }
void resize(double factor) override { /* ubah ukuran tombol */ }
};Sebuah class dapat mengimplementasikan beberapa interface, sehingga desainnya fleksibel dan object dapat menjalankan peran yang berbeda:
class Clickable {
public:
virtual void onClick() = 0;
virtual ~Clickable() = default;
};
class IconButton : public Drawable, public Clickable {
public:
void draw() override { std::cout << "Drawing icon" << std::endl; }
void resize(double factor) override { }
void onClick() override { std::cout << "Clicked!" << std::endl; }
};Antarmuka mendorong keterikatan yang longgar, kodemu bergantung pada abstraksi, bukan implementasi konkret, sehingga lebih mudah dikembangkan dan diuji.
Tantangan
MudahMari buat sistem pengelolaan perangkat yang menunjukkan cara interface menetapkan kontrak untuk berbagai jenis perangkat. Kamu akan membuat dua interface terpisah yang dapat diimplementasikan oleh perangkat, lalu membuat class perangkat konkret yang memenuhi salah satu atau kedua kontrak tersebut.
Kamu akan menyusun kodemu dalam tiga file:
Interfaces.h: Definisikan dua class abstrak murni (interface) yang mewakili kemampuan perangkat yang berbeda:Powerable: perangkat apa pun yang dapat dinyalakan dan dimatikan:- Method virtual murni
powerOn() - Method virtual murni
powerOff() - Method virtual murni
getPowerStatus()yang mengembalikanstd::string - Destructor virtual
Connectable: perangkat apa pun yang dapat terhubung ke jaringan:- Method virtual murni
connect(const std::string& network) - Method virtual murni
disconnect() - Method virtual murni
getConnectionInfo()yang mengembalikanstd::string - Destructor virtual
- Method virtual murni
Devices.h: Implementasikan class perangkat konkret yang menggunakan interface ini:Lamp: hanya mengimplementasikanPowerable:- Member private
bool isOn(nilai awalnyafalse) - Member private
std::string name - Constructor yang menerima nama lampu
powerOn()mengaturisOnmenjadi true dan mencetak:<name>: Light turned onpowerOff()mengaturisOnmenjadi false dan mencetak:<name>: Light turned offgetPowerStatus()mengembalikan"ON"atau"OFF"berdasarkan statusnya
SmartTV: mengimplementasikanPowerabledanConnectable:- Member private:
bool isOn(nilai awalnya false),std::string brand,std::string currentNetwork(nilai awalnya kosong) - Constructor yang menerima merek TV
powerOn()mengaturisOnmenjadi true dan mencetak:<brand> TV: Powered onpowerOff()mengaturisOnmenjadi false, menghapus jaringan, dan mencetak:<brand> TV: Powered offgetPowerStatus()mengembalikan"ON"atau"OFF"connect()menyimpan nama jaringan dan mencetak:<brand> TV: Connected to <network>disconnect()menghapus jaringan dan mencetak:<brand> TV: DisconnectedgetConnectionInfo()mengembalikan"Connected to <network>"jika terhubung, atau"Not connected"jika kosong
- Member private
main.cpp: Baca tiga input (masing-masing pada baris terpisah):- Nama lampu
- Merek TV
- Nama jaringan
Buat sebuah
Lampdan sebuahSmartTV. Tunjukkan cara menggunakan interface yang sama dengan perangkat yang berbeda:Pertama, gunakan kedua perangkat melalui interface
Powerable. Simpan pointer ke keduanya dalam array berisiPowerable*, lalu lakukan perulangan dan panggilpowerOn()pada masing-masing perangkat, kemudian cetak statusnya dengan format:Status: <powerStatus>Cetak satu baris kosong, lalu gunakan SmartTV melalui interface
Connectable. Buat pointerConnectable*ke SmartTV-mu, panggilconnect()dengan nama jaringan, lalu cetak:Connection: <connectionInfo>Cetak satu baris kosong lagi, lalu matikan kedua perangkat melalui array
Powerabledan tampilkan status akhirnya.
Contohnya, dengan input Desk Lamp, Samsung, dan HomeWiFi:
Desk Lamp: Light turned on
Status: ON
Samsung TV: Powered on
Status: ON
Samsung TV: Connected to HomeWiFi
Connection: Connected to HomeWiFi
Desk Lamp: Light turned off
Status: OFF
Samsung TV: Powered off
Status: OFFPerhatikan bahwa SmartTV dapat diperlakukan sebagai Powerable atau Connectable, bergantung pada pointer interface yang kamu gunakan. Fleksibilitas ini adalah keunggulan mengimplementasikan beberapa interface. Kodemu dapat bekerja dengan perangkat apa pun yang memenuhi kontrak yang dibutuhkan, tanpa mengetahui tipe konkretnya.
Coba sendiri
#include <iostream>
#include <string>
#include "Devices.h"
using namespace std;
int main() {
// Baca input
string lampName;
string tvBrand;
string networkName;
getline(cin, lampName);
getline(cin, tvBrand);
getline(cin, networkName);
// TODO: Buat object Lamp dan SmartTV
// TODO: Buat array pointer Powerable* yang berisi kedua perangkat
// TODO: Ulangi setiap elemen dalam array dan panggil powerOn() pada setiap perangkat
// Setelah setiap pemanggilan powerOn(), cetak: Status: <powerStatus>
// TODO: Cetak baris kosong
// TODO: Buat pointer Connectable* yang menunjuk ke SmartTV
// Panggil connect() dengan nama jaringan
// Cetak: Connection: <connectionInfo>
// TODO: Cetak baris kosong
// TODO: Ulangi setiap elemen dalam array Powerable dan panggil powerOff() pada setiap perangkat
// Setelah setiap pemanggilan powerOff(), cetak: Status: <powerStatus>
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online