Tài liệu hướng dẫn thực hành môn Phương pháp lập trình hướng đối tượng - Tuần 9

Nguyễn Minh Huy  
Phạm Minh Tuấn  
Môn PPLTHĐT  
Hướng dẫn thực hành tuần 9  
Mục đích  
Bài tập áp dụng đa hình trong lập trình hướng đối tượng và một số vấn đề mở rộng.  
Nội dung  
-
-
-
Bài tập áp dụng đa hình  
Kỹ thuật tạo mẫu đối tượng  
Yêu cầu  
Nắm vững lý thuyết về kế thừa, đa hình.  
Bài toán dẫn nhập  
Công ty ABC cần xây dựng một ứng dụng quản lý nhân sự và tính lương cho nhân viên  
trong công tư như sau:  
1. Quản lý thông tin về nhân viên: (Họ tên, ngày sinh, địa chỉ)  
2. Tính lương cho nhân viên  
Hiện công ty có 3 loại nhân viên và cách tính lương tương ứng cho từng loại nhân viên  
như sau:  
a. Nhân viên sản xuất: số sản phẩm x 2000đ  
b. Nhân viên công nhật: số ngày công x 50.000đ  
c. Nhân viên quản lý: lương cơ bản x hệ số lương  
Hãy viết chương trình quản lý và tính tổng lương các nhân viên của công ty ABC.  
Trước tiên ta phác thảo sơ bộ các lớp cần xây dựng như sau:  
NVQuanLy  
NVCongNhat  
NVSanXuat  
HoTen  
NgaySinh  
HoTen  
NgaySinh  
DiaChi  
HoTen  
NgaySinh  
DiaChi  
DiaChi  
LuongCoBan  
HeSoLuong  
SoNgayCong  
SoSanPham  
Nhap  
Xuat  
TinhLuong  
Nhap  
Xuat  
Nhap  
Xuat  
TinhLuong  
TinhLuong  
Ba lớp đối tượng trên có những thuộc tính và phương thức giống nhau. Xây dựng lớp cha  
có tên là NhanVien chứa những phần giống nhau của 3 lớp trên. Ba lớp trên sẽ kế thừa từ  
lớp NhanVien.  
NhanVien  
HoTen  
NgaySinh  
DiaChi  
Nhap  
Xuat  
TinhLuong  
Tuy nhiên do các công việc Nhập, Xuất, và Tính Lương là khác nhau cho từng loại nhân  
viên. Đến đây có 2 hướng giải quyết:  
1. Không sử dụng cơ chế đa hình:  
Ở mỗi lớp con, định nghĩa lại (nạp chồng hàm) 3 phương thức trên.  
class NhanVien  
{
private:  
string m_strHoTen;  
string m_strNgaySinh;  
string m_strDiaChi;  
public:  
};  
void Nhap();  
void Xuat();  
float TinhLuong();  
class NVSanXuat : public NhanVien  
{
private:  
int m_iSoSanPham;  
public:  
void Nhap();  
void Xuat();  
float TinhLuong();  
};  
class NVCongNhat : public NhanVien  
{
private:  
int m_iSoNgayCong;  
public:  
void Nhap();  
void Xuat();  
float TinhLuong();  
};  
class NVQuanLy : public NhanVien  
{
private:  
float m_fHeSoLuong;  
float m_fLuongCoBan;  
public:  
void Nhap();  
void Xuat();  
float TinhLuong();  
};  
Cài đặt theo cách này, chúng ta cần quản lý 3 danh sách  
vector <NVSanXuat> arrNVSX;  
vector <NVCongNhat> arrNVCN;  
vector <NVQuanLy> arrNVQL;  
Trong thao tác nhập liệu cho toàn bộ nhân viên của công ty, tùy vào loại nhân viên sẽ gọi  
phương thức Nhập tương ứng:  
cout<< “Nhap loai nhan vien (1:NVSX, 2:NVCN, 3:NVQL)”;  
cin>> iLoai;  
switch(iLoai)  
{
case 1:  
NVSanXuat nvSX;  
nvSX.Nhap();  
arrNhanVien.push_back(nvSX);  
case 2:  
case 3:  
}
NVCongNhat nvCN;  
nvCN.Nhap();  
arrNhanVien.push_back(nvCN);  
NVQuanLy nvQL;  
nvQL.Nhap();  
arrNhanVien.push_back(nvQL);  
Muốn tính tổng lương của cả danh sách, phải lần lượt tính tổng lương của mỗi danh sách.  
float fTongLuong = 0;  
for (int i = 0; i < arrNVSX.size(); i++)  
fTongLuong += arrNVSX[i].TinhLuong();  
for (int j = 0; j < arrNVCN.size(); j++)  
fTongLuong += arrNVSX[j].TinhLuong();  
for (int k = 0; k < arrNVQL.size(); k++)  
fTongLuong += arrNVQL[k].TinhLuong();  
2. Áp dụng kỹ thuật đa hình  
class NhanVien  
{
private:  
string m_strHoTen;  
string m_strNgaySinh;  
string m_strDiaChi;  
public:  
virtual void Nhap() = 0;  
void Xuat() = 0;  
float TinhLuong() = 0;  
};  
class NVSanXuat : public NhanVien  
{
private:  
int SoSanPham;  
public:  
void Nhap();  
void Xuat();  
float TinhLuong();  
};  
class NVCongNhat : public NhanVien  
{
private:  
int SoNgayCong;  
public:  
void Nhap();  
void Xuat();  
float TinhLuong();  
};  
class NVQuanLy : public NhanVien  
{
private:  
float HeSoLuong;  
float LuongCoBan;  
public:  
void Nhap();  
void Xuat();  
long TinhLuong();  
};  
Lúc này chỉ cần một danh sách nhân viên duy nhất để quản lý toàn bộ nhân viên của công  
ty:  
vector<CNhanVien*> arrNhanVien;  
//Nhập 1 nhân viên mới  
cout << ”Nhap loai nhan vien (1:NVSX, 2:NVCN, 3:NVQL)”;  
cin >> iLoai;  
switch(iLoai)  
{
case 1: arrNhanVien.push_back(new NVSanXuat);  
case 2: arrNhanVien.push_back(new NVCongNhat);  
case 3: arrNhanVien.push_back(new NVQuanLy);  
}
break;  
break;  
break;  
arrNhanVien[arrNhanVien.size() – 1].Nhap();  
//Tính tổng lương nhân viên  
float fTongLuong = 0;  
for (i = 0; i < arrNhanVien.size(); i++)  
fTongLuong += arrNhanVien[i].TinhLuong();  
Cơ chế đa xạ cho phép gọi đúng những phương thức của đối tượng mà không cần biết  
trước kiểu dữ liệu của đối tượng đó nhờ vào một con trỏ ảo (virtual pointer) bên trong đối  
tượng. Con trỏ này giữ địa chỉ của một bảng ảo (virtual table) trong đó chứa thông tin về  
kiểu dữ liệu và địa chỉ các phương thức tương ứng của đối tượng. Đây được xem là điểm  
then chốt của cơ chế đa xạ.  
Khai báo và cài đặt lớp DanhSachNhanVien để xử lý các nghiệp vụ công ty.  
class DanhSachNhanVien  
{
private:  
vector<NhanVien*> arrNhanVien;  
public:  
void NhapDanhSach();  
void XuatDanhSach();  
void XuatBangLuong();  
CNhanVien* TimNhanVienLuongCaoNhat();  
CNhanVien* TimNhanVienLuongThapNhat();  
float TongLuong();  
…………………………………………………..  
};  
Áp dụng kỹ thuật tạo đối tượng mẫu  
Trong cả 2 giải pháp trên, trong thao tác nhập danh sách nhân viên đều dùng đến bảng  
chọn (1:NVSX, 2:NVCN, 3:NVQL) và các câu lệnh switch. Bảng chọn trên là khá cứng  
nhắc, Giả sử có nhu cầu thay đổi thứ tự trên hoặc thêm một loại nhân viên mới, đều phải  
thay đổi bảng chọn này.  
Để giải quyết vấn đề trên, có thể áp dụng kỹ thuật tạo mẫu đối tượng.  
class NhanVien  
{
……………………………………………  
public:  
virtual NhanVien* TaoDoiTuong() = 0;  
…………………………………..  
}
Class NVSanXuat()  
{
……………………………………………  
public:  
NhanVien* TaoDoiTuong()  
{
NhanVien* nv = new NVSanXuat();  
return nv;  
}
string TenLop()  
{
return “NVSanXuat”;  
}
………………………………………….  
}
vector <NhanVien*> arrDoiTuongMau;  
arrDoiTuongMau.push_back(new NVSanXuat);  
arrDoiTuongMau.push_back(new NVCongNhat);  
arrDoiTuongMau.push_back(new NVQuanLy);  
/*  
NhanVien* TaoDoiTuong(int id)  
{
NhanVien* nv = NULL;  
if (id >=0 && id < arrDoiTuongMau.size())  
nv = arrDoiTuongMau[id]->TaoDoiTuong();  
return nv;  
}
*/  
//Nhập 1 nhân viên mới  
for (int i = 0; i < arrDoiTuongMau.size(); i++)  
cout << i + 1 << “:“ << arrDoiTuongMau[i]->TenLop() << endl;  
int iLoai;  
cin >> iLoai;  
arrNhanVien.push_back(arrDoiTuongMau[id-1]->TaoDoiTuong());  
Bài toán mạch điện  
Tính tổng trở của một mạch điện phức hợp gồm nhiều mạch song song, nối tiếp với nhau.  
Gợi ý thiết kế lớp như sau:  
class Circuit  
{
public:  
virtual float Resistance() = 0;  
}
class SimpleCircuit : public Circuit  
{
private:  
float m_fResistance;  
public:  
float Resistance()  
{
return m_fResistance;  
}
}
class CompositeCircuit : Circuit  
{
protected:  
vector <Circuit> arrCircuit;  
public:  
double Resistance()  
{
return 0;  
}
}
public class ParallelCircuit : CompositeCircuit  
{
public:  
double Resistance()  
{
// tính điện trở cho mạch song song  
}
}
class SerialCircuit : CompositeCircuit  
{
Public:  
double Resistance()  
{
// tính điện trở cho mạch nối tiếp  
}
}
pdf 8 trang myanh 21160 Free
Bạn đang xem tài liệu "Tài liệu hướng dẫn thực hành môn Phương pháp lập trình hướng đối tượng - Tuần 9", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdftai_lieu_huong_dan_thuc_hanh_mon_phuong_phap_lap_trinh_huong.pdf