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
}
}
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:
tai_lieu_huong_dan_thuc_hanh_mon_phuong_phap_lap_trinh_huong.pdf

