Menu
CoddyTech

Upcasting

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

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

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 dapat meneruskan Car* ke fungsi ini dengan mengubah tipenya 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 adalah upcasting: kita bergerak "naik" dari tipe yang spesifik 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, yang beroperasi pada tipe dasar sambil menerima tipe turunan apa pun yang menyematkannya.

challenge icon

Tantangan

Mudah

Mari kita buat sistem transportasi sederhana untuk menunjukkan cara kerja upcasting. Kamu akan membuat tipe dasar Vehicle dan tipe yang lebih spesifik, Motorcycle, lalu menunjukkan cara fungsi umum bekerja dengan keduanya melalui konversi 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. Sepedamu "is a" vehicle, jadi fungsi apa pun yang mengharapkan Vehicle* seharusnya dapat memprosesnya.

Kamu akan mengatur kodemu dalam tiga file:

  • vehicle.h: Definisikan hierarki struct-mu dengan penjaga include. Buat struct Vehicle dengan dua field: speed (bilangan bulat untuk kecepatan saat ini) dan max_speed (bilangan bulat untuk kecepatan maksimum kendaraan). Lalu definisikan struct Motorcycle yang menyematkan Vehicle sebagai anggota pertamanya dan menambahkan field has_sidecar (bilangan bulat, dengan 1 berarti ya dan 0 berarti tidak). Deklarasikan dua fungsi: boost yang menerima Vehicle* dan jumlah untuk meningkatkan kecepatan, serta print_motorcycle yang menerima Motorcycle*.
  • vehicle.c: Implementasikan kedua fungsi. Fungsi boost-mu harus meningkatkan kecepatan kendaraan sebesar jumlah yang diberikan, tetapi membatasinya hingga max_speed. Jika kecepatan baru akan melebihi batas maksimum, tetapkan ke max_speed. Fungsi print_motorcycle-mu harus menampilkan semua informasi sepeda motor, termasuk data kendaraan yang disematkan.
  • main.c: Buat Motorcycle dan inisialisasi semua field-nya. Lalu tunjukkan upcasting dengan memanggil fungsi boost: konversikan Motorcycle*-mu menjadi Vehicle* untuk meneruskannya ke fungsi umum ini. Setelah meningkatkan kecepatannya, tampilkan informasi sepeda motor untuk melihat hasilnya.

Kamu akan menerima empat input: kecepatan awal sepeda motor, kecepatan maksimum, apakah sepeda motor memiliki sespan (1 atau 0), dan jumlah peningkatan kecepatan.

Output-mu seharusnya terlihat seperti ini:

Speed: 75
Max Speed: 120
Sidecar: Yes

Di sini, 75 adalah kecepatan setelah ditingkatkan (awal 50 + peningkatan 25), 120 adalah kecepatan maksimum, dan Yes atau No menunjukkan apakah sepeda motor memiliki sespan. Jika peningkatan kecepatan akan membuat kecepatan melampaui max_speed, kecepatannya harus dibatasi hingga max_speed.

Hal penting yang dipelajari di sini adalah bahwa boost tidak mengetahui apa pun tentang sepeda motor. Fungsi itu hanya bekerja dengan Vehicle. Namun, melalui upcasting, sepeda motormu dapat menggunakan fungsi umum ini untuk mengubah data kendaraan yang disematkan.

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* untuk meneruskannya 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