6.3 TRUY NHẬP TỚI CÁC THÀNH PHẦN TRONG KẾ THỪA LỚP
6.3.4 Chuyển đổi kiểu giữa lớp cơ sở và lớp dẫn xuất
Về mặt dữ liệu, một lớp dẫn xuất bao giờ cũng chứa toàn bộ dữ liệu của lớp cơ sở: Ta ln tìm thấy lớp cơ sở trong lớp dẫn xuất, nhưng khơng phải bao giờ cũng tìm thấy lớp dẫn xuất trong lớp cơ sở. Do vậy:
• Có thể gán một đối tượng lớp dẫn xuất cho một đối tượng lớp cơ sở:
<Đối tượng lớp cơ sở> = <Đối tượng lớp dẫn xuất>; // Đúng
• Nhưng không thể gán một đối tượng lớp cơ sở cho một đối tượng lớp dẫn xuất:
<Đối tượng lớp dẫn xuất> = <Đối tượng lớp cơ sở>; // Khơng được
Ví dụ, ta có lớp Bus kế thừa từ lớp Car và:
Car myCar;
khi đó, phép gán:
myCar = myBus; // đúng
thì chấp nhận được, nhưng phép gán:
myBus = myCar; // không được
thì khơng chấp nhận được.
Lưu ý:
• Nguyên tắc chuyển kiểu này cũng đúng với các phép gán con trỏ: một con trỏ đối tượng
lớp cơ sở có thể trỏ đến địa chỉ của một đối tượng lớp dẫn xuất. Nhưng một con trỏ đối
tượng lớp dẫn xuất không thể trỏ đến địa chỉ một đối tượng lớp cơ sở.
• Nguyên tắc chuyển kiểu này cũng đúng với truyền đối số cho hàm: có thể truyền một đối tượng lớp dẫn xuất vào vị trí của tham số có kiểu lớp cơ sở. Nhưng không thể truyền một
đối tượng lớp cơ sở vào vị trí một tham số có kiểu lớp dẫn xuất.
Chương trình 6.5 minh họa việc chuyển kiểu giữa các đối tượng của lớp cơ sở và lớp dẫn xuất.
Chương trình 6.5 #include<stdio.h> #include<conio.h> #include<string.h> /* Định nghĩa lớp Car */ class Car{ private: int speed; // Tốc độ char mark[20]; // Nhãn hiệu float price; // Giá xe public:
int getSpeed(); // Đọc tốc độ xe char[] getMark(); // Đọc nhãn xe float getPrice(); // Đọc giá xe
// Khởi tạo thông tin về xe
Car(int speedIn=0, char markIn[]=””, float priceIn=0); void show(); // Giới thiệu xe
};
/* Khai báo phương thức bên ngoài lớp */
Car::Car(int speedIn, char markIn[], float priceIn){ speed = speedIn;
strcpy(mark, markIn); price = priceIn;
int Car::getSpeed(){ // Đọc tốc độ xe return speed; } char[] Car::getMark(){ // Đọc nhãn xe return mark; }
float Car::getPrice(){ // Đọc giá xe return price;
}
void Car::show(){ // Phương thức giới thiệu xe cout << “This is a ” << mark << “ having a speed of ”
<< speed << “km/h and its price is $” << price << endl; return;
}
/* Định nghĩa lớp Bus kế thừa từ lớp Car */ class Bus: public Car{
int label; // Số hiệu tuyến xe public:
// Khởi tạo đủ tham số
Bus(int sIn=0, char mIn[]=””, float pIn=0, int lIn=0); void show(); // Định nghĩa chồng phương thức };
// Khởi tạo đủ tham số
Bus::Bus(int sIn, char mIn[], float pIn, int lIn):Car(sIn, mIn, pIn){ label = lIn;
}
// Định nghĩa nạp chồng phương thức
void Bus::show(){ // Giới thiệu xe bus
cout << “This is a bus of type ” << getMark() << “, on the line “ << label << “, having a speed of ” << getSpeed()
<< “km/h and its price is $” << getPrice() << endl; return;
}
// Chương trình chính void main(){
clrscr();
Car myCar(100, “Ford”, 3000); // Biến đối tượng lớp Car
cout << “Gioi thieu xe o to lan 1:” << endl; myCar.show();
cout << “Gioi thieu xe o to lan 2:” << endl; myCar = myBus;
myCar.show();
cout << “Gioi thieu xe bus:” << endl; myBus.show();
return; }
Chương trình 6.5 sẽ in ra kết quả thông báo như sau:
Goi thieu xe o to lan 1:
This is a Ford having a speed of 100km/h and its price is $3000 Gioi thieu xe lan o to lan 2:
This is a Mercedes having a speed of 80km/h and its price is $5000 Gioi thieu xe bus:
This is a bus of type Mercedes, on the line 27, having a speed of 80km/h and its price is $5000
Ở thông báo thứ nhất, đối tượng myCar gọi phương thức show() của lớp Car với các dữ liệu được
khởi đầu cho myCar: (100, “Ford”, 3000). Ở thông báo thứ hai, myCar gọi phương thức show() của lớp Car, nhưng với dữ liệu vừa được gán từ đối tượng myBus: (80, “Mercedes”, 5000). Ở
thông báo thứ ba, myBus gọi phương thức show() của lớp Bus với các dữ liệu của myBus: (80, “Mercedes”, 5000, 27).