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: 50Ini 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.
Tantangan
MudahMari 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 structVehicledengan dua field:speed(bilangan bulat untuk kecepatan saat ini) danmax_speed(bilangan bulat untuk kecepatan maksimum kendaraan). Lalu definisikan structMotorcycleyang menyematkanVehiclesebagai anggota pertamanya dan menambahkan fieldhas_sidecar(bilangan bulat, dengan 1 berarti ya dan 0 berarti tidak). Deklarasikan dua fungsi:boostyang menerimaVehicle*dan jumlah untuk meningkatkan kecepatan, sertaprint_motorcycleyang menerimaMotorcycle*.vehicle.c: Implementasikan kedua fungsi. Fungsiboost-mu harus meningkatkan kecepatan kendaraan sebesar jumlah yang diberikan, tetapi membatasinya hinggamax_speed. Jika kecepatan baru akan melebihi batas maksimum, tetapkan kemax_speed. Fungsiprint_motorcycle-mu harus menampilkan semua informasi sepeda motor, termasuk data kendaraan yang disematkan.main.c: BuatMotorcycledan inisialisasi semua field-nya. Lalu tunjukkan upcasting dengan memanggil fungsiboost: konversikanMotorcycle*-mu menjadiVehicle*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: YesDi 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;
}
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