Getter/setter
Quy tắc đóng kín
Truy xuất thông qua getter: int ĐồngHồ::hiệnGiờ()
Truy nhập thông qua setter: void ĐồngHồ::đặtGiờ(int h)
Các loại thuộc tính:
Thuộc tính nội bộ không có get/setter.
Thuộc tính chỉ đọc chỉ có getter
Thuộc tính ảo có getter (setter), nhưng không có thực
trong bộ nhớ. Thường là công thức tương đương với
những thuộc tính thực khác. VD: (giờ, phút, giây) ~
i_giây
Thuộc tính công cộng có cả getter và setter nhưng mọi
truy cập đến thuộc tính đều được kiểm soát.
VD: PhânSố::đặtMẫu(float ≠ 0)
43 trang |
Chia sẻ: thanhle95 | Lượt xem: 671 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Bài giảng Phương pháp lập trình hướng đối tượng - Tuần 3: Lớp và đối tượng (Tiếp theo) - Phạm Tú San, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Tuần 03:
Lớp và đối tượng (tt)
Nhắc lại - Lớp và đối tượng
Lập trình hướng đối tượng là phương pháp lập
trình dựa trên kiến trúc lớp (class) và đối
tượng (object)
Mỗi đối tượng bao gồm 2 thành phần: thuộc
tính (attributes) và hành động (methods)
Kiểu dữ liệu lớp đối tượng: class
Đóng gói: chứa đựng dữ liệu và các hàm/thủ tục
liên quan
Che giấu dữ liệu: các thực thể phần mềm khác
không can thiệp trực tiếp vào dữ liệu bên trong
ñược mà phải thông qua các phương thức cho
phép
Tách thành phần khai báo và cài đặt
File header (interface): .h
Chứa các thông tin về khai báo của lớp.
File xử lý (implementation): .cpp
Chứa các cài đặt về xử lý của lớp.
CON TRỎ THIS
Con trỏ this
Xét đoạn code sau
Đoạn code này có đúng không? Về cú pháp và ngữ
nghĩa?
class PhanSo
{
private:
int mTuSo;
int mMauSo;
Public:
void GanTuSo(int mTuSo)
{
mTuSo = mTuSo;
}
};
void main()
{
PhanSo a;
a.GanTuSo (2);
PhanSo b;
b.GanTuSo(5);
}
Con trỏ this (tt)
Làm sao trong phần cài đặt, chúng ta biết được
mTuSo nào đang được dùng?
a
+ mTuSo
+ mMauSo
b
+ mTuSo
+ mMauSo
c
+ mTuSo
+ mMauSo
void PhanSo::LayTuSo()
{
return mTuSo;
}
Con trỏ this
Trong C++, trình biên dịch tự động thêm
vào trong các đối số của hàm 1 con trỏ this
Con trỏ this trỏ tới đối tượng tương ứng
hiện tại.
void PhanSo::LayTuSo( PhanSo* const this )
{
return this->mTuSo;
}
void main()
{
PhanSo a;
int t = a.LayTuSo();
}
void main()
{
PhanSo a;
int t = a.LayTuSo(&a);
}
Con trỏ this
Đoạn code đầu tiên:
Tuy nhiên, trong trường hợp này do các đối số bị trùng
tên với thành phần dữ liệu nên mới xảy ra vấn đề vừa
nêu. Nếu không, hàm sẽ tự động ngầm hiểu con trỏ this
cho các biến có tên thuộc lớp đối tượng tương ứng
class PhanSo
{
private:
int mTuSo;
int mMauSo;
Public:
void GanTuSo(int mTuSo)
{
this->mTuSo = mTuSo;
}
};
Con trỏ this
Trong các hàm, con trỏ this (trỏ tới đối tượng
được khởi tạo tương ứng) được truyền vào
hàm 1 cách không tường minh.
Các đối số khác được khai báo bình thường
trong hàm.
float Diem::tinhKhoangCach(Diem d)
{
return sqrt( (this->x – d.x)*(this->x – d.x)
+(this->y – d.y)*(this->y – d.y) );
}
NẠP CHỒNG HÀM
Nạp chồng hàm
Mỗi hàm đều có 1 “chữ ký hàm”
Phân biệt giữa các hàm.
Đặt trưng của một hàm:
Tên hàm.
Danh sách tham số (số lượng, kiểu)
Chương trình có thể có
nhiều hàm trùng tên
(nhưng khác tham số)
Nạp chồng hàm
Lớp phân số có thể có nhiều hàm cộng
Trình biên dịch sẽ căn cứ vào danh sách các đối
số truyền vào và so sánh chúng với tham số trong
nguyên mẫu hàm để xác định đúng phương án
thực hiện.
Nạp chồng hàm
Lưu ý: kiểu trả về không thuộc chữ kí hàm
PhanSo PhanSo::Cong(PhanSo );
float PhanSo::Cong(PhanSo );
Getter/Setter
Qui tắc đóng gói kín
Đóng gói hở: Mở một số
thuộc tính ra “public” cho
mọi người sử dụng trực
tiếp nguy hiểm!
Đóng gói kín: Mọi thuộc
tính đều “private”, muốn
đọc giá trị của nó cũng phải
thông qua phương thức!
Đối tượng kiểm soát được
mọi tác động đến thuộc
tính của mình.
học tập
làm
việc
ăn chơi khoe
tiền
kiến thức
tiền
Kỹ_sư_CNTT a
Đạo_tặc b
cướp
ngân hàng
trộm cắp
ăn chơi buôn lậu
tiền
a.tiền = 0;
cout<<“Tên này có ”<<a.khoeTiền()<<“ đô”
<<“ mà ta không lấy được!”;
Getter/setter
Quy tắc đóng kín
Truy xuất thông qua getter: int ĐồngHồ::hiệnGiờ()
Truy nhập thông qua setter: void ĐồngHồ::đặtGiờ(int h)
Các loại thuộc tính:
Thuộc tính nội bộ không có get/setter.
Thuộc tính chỉ đọc chỉ có getter
Thuộc tính ảo có getter (setter), nhưng không có thực
trong bộ nhớ. Thường là công thức tương đương với
những thuộc tính thực khác. VD: (giờ, phút, giây) ~
i_giây
Thuộc tính công cộng có cả getter và setter nhưng mọi
truy cập đến thuộc tính đều được kiểm soát.
VD: PhânSố::đặtMẫu(float ≠ 0)
Getter/Setter
Các thuộc tính của lớp SinhVien
Thuộc tính Get Set PThức khác Ghi chú
MSSV x thiLT(), thiTH(), làmNhóm() Định danh
Tên x thiLT(), thiTH(), làmNhóm() Định danh
MS Nhóm x x làmNhóm()
điểm LT (x) thiLT()
điểm TH (x) thiTH()
điểm Cộng (x) làmNhóm()
điểm TK x Xác định bởi đ. LT, đ.
TH, đ. Cộng
HÀM DỰNG(CONSTRUCTOR)
Tại sao cần hàm dựng?
Khi đối tượng vừa được tạo:
Giá trị các thuộc tính bằng bao nhiêu?
Một số đối tượng cần có thông tin ban đầu.
PhanSo
Tử số??
Mẫu số??
Khởi tạo
HocSinh
Họ tên??
Điểm văn??
Điểm toán??
Khởi tạo
void main()
{
PhanSo a;
a.Xuat();
HocSinh b;
b.Xuat();
} Giải pháp:
Xây dựng phương thức khởi tạo.
Người dùng quên gọi?!
Tính chất hàm dựng
Tính chất hàm dựng (constructor):
Tự động thực hiện khi đối tượng được tạo.
Có thể nạp chồng nhiều hàm dựng.
Trong C++, hàm dựng có tên trùng tên lớp
Không có kiểu trả về
class PhanSo
{
private:
int m_iTuSo;
int m_iMauSo;
public:
PhanSo(int iTuSo, int iMauSo);
PhanSo(int iGiaTri);
};
void main()
{
PhanSo p1(1, 2);
PhanSo *p2 = new PhanSo(5);
}
Các loại hàm dựng
Hàm dựng mặc định
Hàm dựng sao chép
Hàm dựng với tham số đầy đủ
Các hàm dựng khác
Hàm dựng mặc định
Khi lớp đối tượng không có hàm dựng nào thì
hàm dựng mặc định (default constructor) sẽ
được tự động thêm vào
Tính chất:
Không tham số.
Khởi tạo mặc định các thuộc tính.
Ví dụ hàm dựng mặc định
class PhanSo
{
private:
int mTuSo;
int mMauSo;
public:
PhanSo()
{
this->mTuSo = 0;
this->mMauSo = 1;
}
};
}
void main()
{
PhanSo p1;
p1.Xuat();
Lưu ý: hàm dựng mặc định
Hàm dựng mặc định chỉ được thêm vào nếu lớp
đối tượng không có 1 hàm dựng nào cả.
class Ngay
{
public:
Ngay(int ngMoi)
{ng = ngMoi;}
private:
int ng, th, nm;
};
int main()
{
Ngay homnay;
return 0;
}
Báo lỗi
int main()
{
PhanSo a;
PhanSo b(a); // gọi copy constructor
PhanSo c = a.Cong(b); // copy constructor
//ñược gọikhi b là tham trị
}
Hàm dựng sao chép mặc định
Mỗi lớp, nếu không định nghĩa 1 hàm dựng sao chép
thì trình biên dịch sẽ cung cấp 1 hàm dựng sao chép
mặc định. Hàm này giúp khởi tạo 1 đối tượng thuộc
lớp này bằng 1 đối tượng khác thuộc cùng lớp.
26
Hàm dựng sao chép
Hàm dựng sao chép (copy constructor):
Có tham số là đối tượng cùng lớp.
Dùng khởi tạo từ đối tượng cùng loại.
class PhanSo
{
private:
int m_iTuSo;
int m_iMauSo;
public:
PhanSo(const PhanSo &p);
};
void main()
{
PhanSo p1(1, 2);
PhanSo p2(p1);
PhanSo p3 = p2;
}
Hàm dựng sao chép mặc định
Hàm dựng sao chép mặc định chỉ sao chép
từng bit (bitwise copy) của các thành phần
trong đối tượng nguồn sang đối tượng
đích
Đối tượng nguồn Đối tượng đích
b b
a a
ptr ptr
Hàm dựng sao chép
Do tính chất sao chép từng bit (bitwise copy)
của hàm dựng mặc định, nếu đối tượng có
chứa con trỏ và nó đang trỏ tới 1 vùng nhớ nào
đó thì việc sao chép sẽ gây ra vấn đề nghiêm
trọng.
Cụ thể, khi đó 2 biến con trỏ của 2 đối tượng khác
nhau cùng trỏ tới 1 vùng nhớ.
Hàm dựng sao chép
Cần lưu ý vào đặc thù của lớp đối tượng mà có
nên xây dựng hàm dựng sao chép hay không.
Cụ thể: khi đối tượng có thành phần dữ liệu là con
trỏ
HocSinh:: HocSinh(const HocSinh & h)
{
int size = h.HoTen.length();
this->HoTen= new char[size];
strcpy(this->HoTen, h.HoTen);
}
30
Hàm dựng
Một lớp nên có tối thiểu 3 hàm dựng sau:
Hàm dựng mặc định.
Hàm dựng có đầy đủ tham số.
Hàm dựng sao chép.
class PhanSo
{ private:
int m_iTuSo;
int m_iMauSo;
public:
PhanSo();
PhanSo(int iTuSo, int iMauSo);
PhanSo(const PhanSo &p);
};
PHƯƠNG THỨC HỦY
(DESTRUCTOR)
32
Hàm hủy
Vấn đề rò rỉ bộ nhớ (memory leak):
Khi hoạt động, đối tượng có cấp phát bộ nhớ.
Khi hủy đi, bộ nhớ có được thu hồi?
Làm cách nào để thu hồi?
Xây dựng phương thức thu hồi.
Người dùng quên gọi?!
HocSinh
Họ tên
Điểm văn
Điểm toán
Thu hồi
Rò rỉ bộ nhớ!!
Hàm hủy vào cuộc!!
33
Hàm hủy
Tính chất hàm hủy (destructor):
Tự động thực hiện khi đối tượng bị hủy.
Mỗi lớp có duy nhất một hàm hủy.
Không có giá trị trả về và tham số
Trong C++, hàm hủy có tên ~
class HocSinh
{
private:
char *HoTen;
float DiemVan;
float DiemToan;
public:
~HocSinh() { delete HoTen; }
};
void main()
{
HocSinh h;
HocSinh *p = new HocSinh;
delete p;
}
BÀI TẬP
Bài tập – 3.1
Khai báo và cài đặt lớp phân số với các hàm sau
Nhập, xuất
Getter/setter
Cộng, trừ, nhân, chia 1 phân số với 1 số thực
Cộng trừ nhân chia phân số với số thực
Rút gọn, nghịch đảo phân số
So sánh 2 phân số
Xét dấu phân số (nhỏ hơn 0, bằng 0, lớn hơn 0)
Kiểm tra phân số có tối giản hay không?
Kiểm tra phân số có nhỏ hơn 0 hay không?
Bài 3.1 (tt)
Bổ sung vào lớp phân số những phương thức sau:
(Nhóm tạo hủy)
Khởi tạo mặc định phân số = 0.
Khởi tạo với tử và mẫu cho trước.
Khởi tạo với giá trị phân số cho trước.
Khởi tạo từ một phân số khác.
Bài tập – 3.1 (tt)
Viết chương trình cho phép
Nhập vào một mảng các phân số
Xuất ra phân số nhỏ nhất/ lớn nhất
Sắp xếp theo thứ tự tăng dần/ giảm dần
Tạo mảng phân số mới từ các phân số có tử là số
nguyên tố
Xóa các phân số có tử là 0
Cứ mỗi 2 phân số, chèn vào một phân số bằng tổng
của 2 phân số trước đó
Bài tập – 3.2
Khai báo và cài đặt lớp điểm trong không gian
Oxy với các hàm sau:
Nhập, xuất điểm
Getter/setter
Tìm khoảng cách giữa 2 điểm
Tìm điểm đối xứng qua trục Ox, Oy, gốc tọa độ Oxy
Bài tập – 3.3
Khai báo và cài đặt lớp tam giác với các hàm sau
Nhập, xuất tam giác
Getter/setter đỉnh A
Tính chu vi, diện tích
Tìm tọa độ trọng tâm
Tính tổng khoảng cách từ điểm P đến 3 đỉnh
Bài tập – 3.4
Thông tin một sinh viên bao gồm:
MSSV
Họ tên
Ngày tháng năm sinh
Năm nhập học
Điểm trung bình tích lũy
Viết chương trình cho phép thực hiện các thao tác trên kiểu sinh
viên:
Nhập, xuất thông tin sinh viên.
Xét tốt nghiệp cho sinh viên – các sinh viên từ khóa 08
trở về trước, có điểm trung bình tích lũy trên 5.0 thì được
tốt nghiệp
41
Bài tập – 3.4
Bổ sung vào lớp sinh viên những phương thức sau:
(Nhóm tạo hủy)
Khởi tạo với MSSV
Khởi tạo với các thông tin đầy đủ
Khởi tạo từ một sinh viên khác.
Bài tập – 3.4
Viết chương trình cho phép
Nhập vào
Tham khảo
Bài giảng môn PPLTHĐT của
Thầy Đinh Bá Tiến
Thầy Nguyễn Minh Huy
Thầy Lê Xuân Định