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: 50Ini 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.
Tantangan
MudahMari 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 structVehicledengan dua field:speed(integer untuk kecepatan saat ini) danmax_speed(integer untuk kecepatan maksimum vehicle). Lalu definisikan structMotorcycleyang menyematkanVehiclesebagai anggota pertamanya dan menambahkan fieldhas_sidecar(integer, dengan nilai 1 berarti ya dan 0 berarti tidak). Deklarasikan dua fungsi:boostyang menerimaVehicle*dan jumlah untuk menambah kecepatan, sertaprint_motorcycleyang menerimaMotorcycle*.vehicle.c: Implementasikan kedua fungsi. Fungsiboost-mu harus menambah kecepatan vehicle sebesar jumlah yang diberikan, tetapi membatasinya padamax_speed. Jika kecepatan baru melebihi maksimum, tetapkan kemax_speed. Fungsiprint_motorcycle-mu harus menampilkan semua informasi motorcycle, termasuk data vehicle yang disematkan di dalamnya.main.c: Buat sebuahMotorcycledan inisialisasi semua field-nya. Lalu tunjukkan upcasting dengan memanggil fungsiboost: castMotorcycle*-mu menjadiVehicle*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: YesDi 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;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar Pemrograman Modular
file headerProteksi includefile sumberFungsi StatisRingkasan: Kalkulator Modular4Enkapsulasi
Konsep Opaque PointerMendefinisikan Opaque StructGetter dan SetterValidasi pada SetterUlasan: Kotak Rahasia2Object dan method
Struct sebagai objectPointer 'self'Konsistensi constPointer vs nilaiMethod pembantuRangkuman: Pengelola Point5Proyek: Akun Bank Sederhana
Penyiapan ProyekImplementasi Akun3Siklus Hidup object
Pola KonstruktorPola DestruktorInisialisasi StackSalinan MendalamRangkuman: Pembungkus string6Pewarisan melalui Komposisi
Penyematan StructAturan Anggota PertamaMengakses Anggota ParentUpcastingRekap: Hierarki Bentuk9Proyek: Penggambar Bentuk
Ringkasan ProyekImplementasi LingkaranImplementasi Persegi PanjangPenggunaan PolimorfismeWadah BentukLatihan sendiri: Compiler C online