Menu
CoddyTech

Upcasting

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C di Coddy. Pelajaran 31 dari 61.

Upcasting adalah tindakan memperlakukan tipe tertentu (turunan) sebagai tipe yang lebih umum (basis). Dalam model komposisi C, ini berarti meneruskan pointer ke struct yang menyematkan tipe basis ke fungsi yang mengharapkan tipe basis.

Pertimbangkan struct dasar Vehicle dan Car yang memuatnya:

typedef struct {
    int speed;
} Vehicle;

typedef struct {
    Vehicle vehicle;  // Struktur dasar sebagai anggota pertama
    int doors;
} Car;

Sekarang bayangkan fungsi generik yang bekerja dengan kendaraan apa pun:

void accelerate(Vehicle* v, int amount) {
    v->speed += amount;
}

Berkat aturan anggota pertama, kita bisa meneruskan Car* ke fungsi ini dengan meng-casting-nya menjadi Vehicle*:

Car my_car = {{0}, 4};  // speed=0, doors=4
accelerate((Vehicle*)&my_car, 50);
printf("Speed: %d\n", my_car.vehicle.speed);  // output: 50

Ini disebut upcasting: kita bergerak "ke atas" dari tipe khusus ke tipe yang lebih umum. Fungsi accelerate tidak tahu bahwa fungsi tersebut bekerja dengan Car; fungsi tersebut hanya melihat Vehicle. Ini memungkinkan kamu menulis kode yang dapat digunakan kembali dan beroperasi pada tipe dasar, sekaligus menerima tipe turunan apa pun yang menyematkannya.

challenge icon

Tantangan

Mudah

Mari buat sistem transportasi sederhana yang menunjukkan cara kerja upcasting. Kamu akan membuat tipe dasar Vehicle dan tipe yang lebih spesifik, yaitu Motorcycle, lalu menunjukkan bagaimana fungsi umum dapat bekerja dengan keduanya melalui casting pointer.

Kelebihan upcasting adalah kamu dapat menulis fungsi untuk tipe dasar, dan fungsi tersebut akan bekerja dengan lancar pada tipe turunan apa pun yang menyematkannya. Motorcycle-mu adalah sebuah vehicle, jadi fungsi apa pun yang menerima Vehicle* seharusnya dapat memprosesnya.

Kamu akan mengatur kodemu dalam tiga file:

  • vehicle.h: Definisikan hierarki struct dengan include guard. Buat struct Vehicle dengan dua field: speed (integer untuk kecepatan saat ini) dan max_speed (integer untuk kecepatan maksimum vehicle). Lalu definisikan struct Motorcycle yang menyematkan Vehicle sebagai anggota pertamanya dan menambahkan field has_sidecar (integer, dengan nilai 1 berarti ya dan 0 berarti tidak). Deklarasikan dua fungsi: boost yang menerima Vehicle* dan jumlah untuk menambah kecepatan, serta print_motorcycle yang menerima Motorcycle*.
  • vehicle.c: Implementasikan kedua fungsi. Fungsi boost-mu harus menambah kecepatan vehicle sebesar jumlah yang diberikan, tetapi membatasinya pada max_speed. Jika kecepatan baru melebihi maksimum, tetapkan ke max_speed. Fungsi print_motorcycle-mu harus menampilkan semua informasi motorcycle, termasuk data vehicle yang disematkan di dalamnya.
  • main.c: Buat sebuah Motorcycle dan inisialisasi semua field-nya. Lalu tunjukkan upcasting dengan memanggil fungsi boost: cast Motorcycle*-mu menjadi Vehicle* untuk meneruskannya ke fungsi umum ini. Setelah menambah kecepatan, cetak informasi motorcycle untuk melihat hasilnya.

Kamu akan menerima empat input: kecepatan awal motorcycle, kecepatan maksimum, apakah motorcycle tersebut memiliki sidecar (1 atau 0), dan jumlah penambahan kecepatan.

Output-mu akan terlihat seperti ini:

Speed: 75
Max Speed: 120
Sidecar: Yes

Di sini, 75 adalah kecepatan setelah penambahan (awal 50 + penambahan 25), 120 adalah kecepatan maksimum, dan Yes atau No menunjukkan apakah motorcycle memiliki sidecar. Jika penambahan kecepatan akan membuat kecepatannya melebihi max_speed, kecepatannya harus dibatasi hingga max_speed.

Hal utama yang dipelajari di sini adalah boost tidak mengetahui apa pun tentang motorcycle. Fungsi ini hanya bekerja dengan Vehicle. Namun, melalui upcasting, motorcycle-mu dapat menggunakan fungsi umum ini untuk mengubah data vehicle yang disematkan di dalamnya.

Coba sendiri

#include <stdio.h>
#include "vehicle.h"

int main() {
    int initial_speed, max_speed, has_sidecar, boost_amount;
    
    // Baca input
    scanf("%d", &initial_speed);
    scanf("%d", &max_speed);
    scanf("%d", &has_sidecar);
    scanf("%d", &boost_amount);
    
    // TODO: Buat Motorcycle dan inisialisasi semua field-nya
    // Ingat: Motorcycle menyematkan Vehicle sebagai anggota pertamanya
    
    // TODO: Tunjukkan upcasting dengan memanggil boost
    // Ubah tipe Motorcycle* milikmu menjadi Vehicle* agar bisa diteruskan ke fungsi boost
    
    // TODO: Tampilkan informasi sepeda motor
    
    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler C online