Lớp và đối tượng

37 311 0
Lớp và đối tượng

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

53 CHƯƠNG 3 LỚP ðỐI TƯỢNG Lớp (class) là khái niệm trung tâm trong lập trình hướng ñối tượng, nó là sự mở rộng của khái niệm cấu trúc (struct) của C. Ngoài các thành phần dữ liệu (giống như cấu trúc), lớp còn chứa các thành phần hàm, còn gọi là phương thức (method) hay hàm thành viên (member function). Cũng giống như cấu trúc, lớp có thể ñược xem như một kiểu dữ liệu. Vì vậy lớp còn ñược gọi là kiểu ñối tượng do ñó có thể dùng ñể khai báo các biến, mảng ñối tượng (như thể dùng kiểu int ñể khai báo các biến mảng nguyên). Như vậy từ một lớp có thể tạo ra (bằng cách khai báo) nhiều ñối tượng (object) khác nhau. Mỗi ñối tượng có vùng nhớ riêng của mình. Chương này sẽ trình bầy cách ñịnh nghĩa lớp, cách xây dựng các phương thức, giải thích về phạm vi truy nhập, sử dụng các thành phần của lớp, cách khai báo biến, mảng cấu trúc, lời gọi tới các phương thức, … § 1. ðỊNH NGHĨA LỚP 1.1. ðịnh nghĩa lớp Lớp ñược ñịnh nghĩa theo mẫu: class tên_lớp { // Khai báo các thành phần dữ liệu (thuộc tính) // Khai báo các phương thức } ; // ðịnh nghĩa (xây dựng) các phương thức Chú ý: Thuộc tính của lớp có thể là các biến, mảng, con trỏ có kiểu chuẩn (int, float, char, char*, long, .) hoặc kiểu ngoài chuẩn ñã ñịnh nghĩa trước (cấu trúc, hợp, lớp, .) . Thuộc tính của lớp không thể có kiểu của chính lớp ñó, nhưng có thể là kiểu con trỏ lớp này, ví dụ: class A { A x ; // Không cho phép, vì x có kiểu lớp A A *p ; // Cho phép , vì p là con trỏ kiểu lớp A . }; 1.2. Các thành phần của lớp Khi báo các thành phần của lớp (thuộc tính phương thức) có thể dùng các từ khoá private public ñể quy ñịnh phạm vi sử dụng của các thành phần. Nếu không 54 quy ñịnh cụ thể (không dùng các từ khoá private hay public) thì C ++ mặc ñịnh hiểu ñó là private. Các thành phần private (riêng) chỉ ñược sử dụng bên trong lớp (trong thân của các phương thức của lớp). Các hàm không phải là phương thức của lớp không ñược phép sử dụng các thành phần này. Các thành phần public (chung) ñược phép sử dụng ở cả bên trong bên ngoài lớp. Các thành phần dữ liệu thường khai báo là private (nhưng không bắt buộc) ñể bảo ñảm tính giấu kín, bảo vệ an toàn dữ liệu của lớp, không cho phép các hàm bên ngoài xâm nhập vào dữ liệu của lớp. Các phương thức thường khai báo là public ñể chúng có thể ñược gọi tới (sử dụng) từ các hàm khác trong chương trình. Các phương thức có thể ñược xây dựng bên ngoài hoặc bên trong ñịnh nghĩa lớp. Thông thường, các phương thức ngắn ñược viết bên trong ñịnh nghĩa lớp, còn các phương thức dài thì viết bên ngoài ñịnh nghĩa lớp. Trong thân phương thức của một lớp (giả sử lớp A) có thể sử dụng: + Các thuộc tính của lớp A + Các phương thức của lớp A + Các hàm tự lập trong chương trình. Vì phạm vi sử dụng của hàm là toàn chương trình. Giá trị trả về của phương thức có thể có kiểu bất kỳ (chuẩn ngoài chuẩn) Ví dụ sau sẽ minh hoạ các ñiều nói trên. Chúng ta sẽ ñịnh nghĩa lớp ñể mô tả xử lý các ñiểm trên màn hình ñồ hoạ. Lớp ñược ñặt tên là DIEM. + Các thuộc tính của lớp gồm: int x ; // hoành ñộ (cột) int y ; // tung ñộ (hàng) int m ; // mầu + Các phương thức: Nhập dữ liệu một ñiểm Hiển thị một ñiểm Ẩn một ñiểm Lớp ñiểm ñược xây dựng như sau: class DIEM { int x, y, m ; public: void nhapsl() ; void hien() ; void an() { 55 putpixel(x, y, getbkcolor()); } } ; void DIEM::nhap() { cout << “\nNhập hoành ñộ (cột) tung ñộ (hàng) của ñiểm: “ cin >> x >> y ; cout << “\nNhập mã mầu của ñiểm: “ cin >> m ; } void DIEM::hien() { int mau_ht ; mau_ht = getcolor(); putpixel(x, y, m); setcolor(mau_ht); } Qua ví dụ trên có thể rút ra một số ñiều cần nhớ sau: + Trong cả ba phương thức (dù viết trong hay viết ngoài ñịnh nghĩa lớp) ñều ñược phép truy nhập ñến các thuộc tính x, y m của lớp. + Các phương thức viết bên trong ñịnh nghĩa lớp (như phương thức an) ñược viết như một hàm thông thường. + Khi xây dựng các phương thức bên ngoài lớp (như các phương thức nhap, hien) cần dùng thêm tên lớp toán tử phạm vi :: ñặt ngay trước tên phương thức ñể quy ñịnh rõ ñây là phương thức của lớp nào. § 2. BIẾN, MẢNG ðỐI TƯỢNG 2.1. Khai báo biến, mảng ñối tượng Một lớp (sau khi ñịnh nghĩa) có thể xem như một kiểu ñối tượng có thể dùng ñể khai báo các biến, mảng ñối tượng. Cách khai báo biến, mảng ñối tượng cũng giống như khai báo biến, mảng các kiểu khác (như int, float, cấu trúc, hợp, .), theo mẫu sau: Tên_lớp danh sách ñối ; Tên_lớp danh sách mảng ; Ví dụ sử dụng lớp DIEM ở § 1, có thể khai báo các biến, mảng DIEM như sau: 56 DIEM d1, d2, d3 ; // Khai báo 3 biến ñối tượng d1, d2, d3 DIEM d[20] ; // Khai báo mảng ñối tượng d gồm 20 phần tử Mỗi ñối tượng sau khi khai báo sẽ ñược cấp phát một vùng nhớ riêng ñể chứa các thuộc tính của chúng. Chú ý rằng sẽ không có vùng nhớ riêng ñể chứa các phương thức cho mỗi ñối tượng. Các phương thức sẽ ñược sử dụng chung cho tất cả các ñối tượng cùng lớp. Như vậy về bộ nhớ ñược cấp phát thì ñối tượng giống cấu trúc. Trong trường hợp này: sizeof(d1) = sizeof(d2) = sizeof(d3) = 3*sizeof(int) = 6 sizeof(d) = 20*6 = 120 2.2. Thuộc tính của ñối tượng Trong ví dụ trên, mỗi ñối tượng d1, d2, d3 mỗi phần tử d[i] ñều có ba thuộc tính là x, y, m. Mỗi thuộc tính ñều thuộc về một ñối tượng, vì vậy không thể viết tên thuộc một cách riêng rẽ mà bao giờ cũng phải có tên ñối tượng ñi kèm, giống như cách viết trong cấu trúc của C. Nói cách khác, cách viết thuộc tính của ñối tượng như sau: Tên_ñối_tượng.Tên_thuộc_tính Với các ñối tượng d1, d2, d3 mảng d, có thể viết như sau: d1.x // Thuộc tính x của ñối tượng d1 d2.x // Thuộc tính x của ñối tượng d2 d3.y // Thuộc tính y của ñối tượng d3 d[2].m // Thuộc tính m của phần tử d[2] d1.x = 100 ; // Gán 100 cho d1.x d2.y = d1.x; // Gán d1.x cho d2.y 2.3. Sử dụng các phương thức Cũng giống như hàm, một phương thức ñược sử dụng thông qua lời gọi. Tuy nhiên trong lời gọi phương thức bao giờ cũng phải có tên ñối tượng ñể chỉ rõ phương thức thực hiện trên các thuộc tính của ñối tượng nào. Ví dụ lời gọi: d1.nhapsl(); sẽ thực hiện nhập số liệu vào các thành phần d1.x, d1.y d1.m Câu lệnh: d[3].nhapsl() ; sẽ thực hiện nhập số liệu vào các thành phần d[3].x, d[3].y d[3].m Chúng ta sẽ minh hoạ các ñiều nói trên bằng một chương trình ñơn giản sử dụng lớp DIEM ñể nhập ba ñiểm, hiện rồi ẩn các ñiểm vừa nhập. #include <conio.h> #include <iostream.h> #include <graphics.h> 57 class DIEM { int x, y, m ; public: void nhapsl(); void an() { putpixel(x,y,getbkcolor()); } void hien(); }; void DIEM::nhapsl() { cout << "\nNhap hoanh do (cot) va tung do (hang) cua diem: " ; cin >> x >> y ; cout << " \nNhap ma mau cua diem: " ; cin >> m ; } void DIEM::hien() { int mau_ht; mau_ht = getcolor() ; putpixel(x,y,m); setcolor(mau_ht); } void kd_do_hoa() // Khởi ñộng ñồ họa { int mh, mode ; mh=mode=0; initgraph(&mh, &mode, ""); } void main() { DIEM d1, d2, d3 ; d1.nhapsl(); d2.nhapsl(); 58 d3.nhapsl(); kd_do_hoa(); setbkcolor(BLACK); d1.hien(); d2.hien(); d3.hien(); getch(); d1.an(); d2.an(); d3.an(); getch(); closegraph(); } § 3. CON TRỎ ðỐI TƯỢNG Con trỏ ñối tượng dùng ñể chứa ñịa chỉ của biến, mảng ñối tượng. Nó ñược khai báo như sau: Tên_lớp *Tên_con_trỏ ; Ví dụ dùng lớp DIEM có thể khai báo: DIEM *p1 , *p2, *p3 ; // Khai báo 3 con trỏ p1, p2, p3 DIEM d1, d2 ; // Khai báo 2 ñối tượng d1, d2 DIEM d[20] ; // Khai báo mảng ñối tượng có thể thực hiện các câu lệnh: p1 = &d2 ; // p1 chứa ñịa chỉ của d2 , hay p1 trỏ tới d2 p2 = d ; // p2 trỏ tới ñầu mảng d p3 = new DIEM // Tạo một ñối tượng chứa ñịa chỉ của nó vào p3 ðể sử dụng thuộc tính của ñối tượng thông qua con trỏ, ta viết như sau: Tên_con_trỏ->Tên_thuộc_tính Chú ý: Nếu con trỏ chứa ñịa chỉ ñầu của mảng, có thể dùng con trỏ như tên mảng. Như vậy sau khi thực hiện các câu lệnh trên thì: p1->x d2.x là như nhau p2[i].y d[i].y là như nhau Quy tắc sử dụng thuộc tính: ðể sử dụng một thuộc tính của ñối tượng ta phải dùng phép . hoặc phép -> . Trong chương trình, không cho phép viết tên thuộc tính một cách ñơn ñộc mà phải ñi kèm tên ñối tượng hoặc tên con trỏ theo các mẫu sau: 59 Tên_ñối_tượng.Tên_thuộc_tính Tên_con_trỏ->Tên_thuộc_tính Tên_mảng_ñối_tượng[chỉ_số].Tên_thuộc_tính Tên_con_trỏ[chỉ_số].Tên_thuộc_tính Chương trình dưới ñây cũng sử dụng lớp DIEM ñể nhập một dẫy ñiểm, hiển thị ẩn các ñiểm vừa nhập. Chương trình dùng một con trỏ kiểu DIEM dùng toán tử new ñể tạo ra một dẫy ñối tượng. #include <conio.h> #include <iostream.h> #include <graphics.h> class DIEM { int x, y, m ; public: void nhapsl(); void an() { putpixel(x,y,getbkcolor()); } void hien(); }; void DIEM::nhapsl() { cout <<"\nNhap hoanh do (cot) va tung do (hang) cua diem:" ; cin >> x >> y ; cout << " \nNhap ma mau cua diem: " ; cin >> m ; } void DIEM::hien() { int mau_ht; mau_ht = getcolor() ; putpixel(x,y,m); setcolor(mau_ht); } 60 void kd_do_hoa() { int mh, mode ; mh=mode=0; initgraph(&mh, &mode, ""); } void main() { DIEM *p; int i, n; cout << "So diem: " ; cin >> n; p = new DIEM[n+1]; for (i=1; i<=n; ++i) p[i].nhapsl(); kd_do_hoa(); for (i=1; i<=n; ++i) p[i].hien(); for (i=1; i<=n; ++i) p[i].an(); getch(); closegraph(); } § 4. ðỐI CỦA PHƯƠNG THỨC, CON TRỎ THIS 4.1. Con trỏ this là ñối thứ nhất của phương thức Chúng ta hãy xem lại phương thức nhapsl của lớp DIEM void DIEM::nhapsl() { cout <<"\nNhap hoanh do (cot) va tung do (hang) cua diem:" ; cin >> x >> y ; cout << " \nNhap ma mau cua diem: " ; cin >> m ; } Rõ ràng trong phương thức này chúng ta sử dụng tên các thuộc tính x, y m một cách ñơn ñộc. ðiều này có vẻ như mâu thuẫn với quy tắc sử dụng thuộc tính nêu 61 trong mục trước. Song sự thể là: C ++ sử dụng con trỏ ñặc biệt this trong các phương thức. Các thuộc tính viết trong phương thức ñược hiểu là thuộc một ñối tượng do con trỏ this trỏ tới. Phương thức nhapsl có thể viết một cách tường minh như sau: void DIEM::nhapsl() { cout << "\nNhap hoanh do (cot) va tung do (hang) cua diem:" ; cin >> this->x >> this->y ; cout << " \nNhap ma mau cua diem: " ; cin >> this->m ; } Từ góc ñộ hàm số có thể kết luận rằng: Phương thức của lớp bao giờ cũng có ít nhất một ñối là con trỏ this nó luôn luôn là ñối ñầu tiên của phương thức. 4.2. Tham số ứng với ñối con trỏ this Xét một lời gọi tới phương thức nhapsl: DIEM d1; d1.nhapsl() ; Trong trường hợp này tham số truyền cho con trỏ this chính là ñịa chỉ của d1: this = &d1 Do ñó: this->x chính là d1.x this->y chính là d1.y this->m chính là d1.m *this chính là d1 Như vậy câu lệnh: d1.nhapsl() ; sẽ nhập dữ liệu cho các thuộc tính của ñối tượng d1. Từ ñó có thể rút ra kết luận: Tham số truyền cho ñối con trỏ this chính là ñịa chỉ của ñối tượng ñi kèm với phương thức trong lời gọi phương thức. 4.3. Các ñối khác của phương thức Ngoài ñối ñặc biệt this (ñối này không xuất hiện một cách tường minh), phương thức còn có các ñối khác ñược khai báo như trong các hàm. ðối của phương thức có thể có kiểu bất kỳ (chuẩn ngoài chuẩn). Ví dụ ñể xây dựng phương thức vẽ ñường thẳng qua 2 ñiểm ta cần ñưa vào 3 ñối: Hai ñối là 2 biến kiểu DIEM, ñối thứ ba kiểu nguyên xác ñịnh mã mầu. Vì ñã có ñối ngầm ñịnh this là ñối thứ nhất, nên chỉ cần khai báo thêm 2 ñối. Phương thức có thể viết như sau: 62 void DIEM::doan_thang(DIEM d2, int mau) { int mau_ht; mau_ht = getcolor(); setcolor(mau); line(this->x, this->y, d2.x, d2.y); setcolor(mau_ht); } Chương trình sau minh hoạ các phương thức có nhiều ñối. Ta vẫn dùng lớp DIEM nhưng có một số thay ñổi: + Bỏ thuộc tính m (mầu) + Bỏ các phương thức hien an + ðưa vào bốn phương thức mới: ve_ doan_thang (Vẽ ñoạn thẳng qua 2 ñiểm) ve_tam_giac (Vẽ tam giác qua 3 ñiểm) do_dai (Tính ñộ dài của ñoạn thẳng qua 2 ñiểm) chu_vi (Tính chu vi tam giác qua 3 ñiểm) Chương trình còn minh hoạ: + Việc phương thức này sử dụng phương thức khác (phương thức ve_tam_giac sử dụng phương thức ve_doan_thang, phương thức chu_vi sử dụng phương thức do_dai) + Sử dụng con trỏ this trong thân các phương thức ve_tam_giac chu_vi Nội dung chương trình là nhập ba ñiểm, vẽ tam giác có ñỉnh là ba ñiểm vừa nhập sau ñó tính chu vi tam giác. #include <conio.h> #include <iostream.h> #include <graphics.h> #include <math.h> #include <stdio.h> class DIEM { int x, y ; public: void nhapsl(); void ve_doan_thang(DIEM d2, int mau) ; void ve_tam_giac(DIEM d2, DIEM d3,int mau) ; double do_dai(DIEM d2) { [...]... l p khác ñã ñ nh nghĩa bên trên + Phương th c có giá tr tr v ki u ñ i tư ng con tr ñ i tư ng N i dung chương trình là nh p m t d y hình ch nh t, sau ñó tìm hình ch nh t có di n tích l n nh t hình ch nh t có chu vi l n nh t Chương trình ñư c t ch c thành hai l p: + L p HINH_CN g m: - Các thu c tính: d r (chi u dài chi u r ng) - Các phương th c void nhapsl() ; // Nh p chi u dài, r ng 65 int... ñây minh ho cách dùng hàm b n (b n c a m t l p b n c a nhi u l p) Chương trình ñưa vào hai l p VT (véc tơ), MT (ma tr n) ba hàm b n ñ th c hi n các thao tác trên hai l p này: 78 // Hàm b n v i l p VT dùng ñ in m t véc tơ friend void in(const VT &x); // Hàm b n v i l p MT dùng ñ in m t ma tr n friend void in(const MT &a); // Hàm b n v i c hai l p MT VT dùng ñ nhân ma tr n v i véc tơ friend VT... khác nhau duy nh t gi a hàm b n hàm thông thư ng Chú ý r ng hàm b n không ph i là phương th c c a l p Phương th c c a l p có m t ñ i n ( ng v i con tr this) l i g i c a phương th c ph i g n v i m t ñ i tư ng nào ñó (ñ a ch ñ i tư ng này ñư c truy n cho con tr this) L i g i c a hàm b n gi ng như l i g i c a hàm thông thư ng Ví d sau s so sánh gi a phương th c c a l p hàm b n Xét l p SP (s ph c)... d2 c nh 2 ñi qua d2 d3 64 c nh 3 ñi qua d3 *this Các c nh trên ñư c v nh s d ng phương th c ve_doan_thang: V c nh 1 dùng l nh: (*this).ve_doan_thang(d2,mau) ; V c nh 2 dùng l nh: d2.ve_doan_thang(d3,mau); V c nh 3 dùng l nh: d3.ve_doan_thang(*this,mau); Trong trư ng này rõ ràng vai trò c a this r t quan tr ng N u không dùng nó thì công vi c tr nên khó khăn, dài dòng khó hi u hơn Chúng ta... A là b n c a B B là b n c a A Gi s có hai l p A B ð khai báo l p này là b n c a l p kia, ta vi t theo m u sau: // Khai báo trư c các l p class A; class B ; // ð nh nghĩa các l p 81 class A { friend class B ; // L p B là b n c a A }; class B { friend class A ; // L p A là b n c a B }; Ví d chương trình dư i ñây có hai l p: MT (ma tr n vuông) VT (véc tơ) L p MT là b n c a VT l p VT là b... max trong 2 tam giác *this t2 TAM_GIAC maxdt(TAM_GIAC t2); 68 + Các v n ñ ñáng chú ý trong chương trình là: - Phương thưc tĩnh tao_tg (s gi i thích bên dư i) - Phương thưc maxdt + Thu t toán là: - Duy t qua các t h p 3 ñi m - Dùng phương th c tao_tg ñ l p tam giác t 3 ñi m - Dùng phương th c maxdt ñ ch n tam giác có di n tích l n hơn trong hai tam giác: tam giác v a t o tam giác có di n tích max... maxdt(TAM_GIAC t2); }; TAM_GIAC tao_tg(DIEM e1, DIEM e2, DIEM e3) { TAM_GIAC t; t.d1=e1; t.d2 = e2; t.d3=e3; return t; } § 5 HÀM B N L P B N 5.1 Hàm b n (friend function) ð m t hàm tr thành b n c a m t l p, có hai cách vi t: Cách 1: Dùng t khoá friend ñ khai báo hàm trong l p xây d ng hàm bên ngoài như các hàm thông thư ng (không dùng t khoá friend) M u vi t (ví d v i m t l p A có ba hàm b n) như sau:... closegraph(); } 4.4 M t s nh n xét v ñ i c a phương th c l i g i phương th c Quan sát nguyên m u phương th c: void ve_doan_thang(DIEM d2, int mau) ; Nh n th y phương th c có ba ñ i: ð i th nhât là m t ñ i tư ng DIEM do this tr t i ð i th hai là ñ i tư ng DIEM d2 ð i th ba là bi n nguyên (mau) N i dung phương th c là v m t ño n th ng ñi qua các ñi m *this d2 theo mã m u mau Xem thân c a phương th c s... c ñưa vào ch c t làm rõ ñ i th nh t Trong thân phương th c có th b t khoá this v n ñư c Vai trò c a this tr nên quan tr ng trong phương th c ve_tam_giac: void ve_tam_giac(DIEM d2, DIEM d3,int mau) ; Phương th c này có b n ñ i là: this tr t i m t ñ i tư ng ki u DIEM d2 m t ñ i tư ng ki u DIEM d3 m t ñ i tư ng ki u DIEM mau m t bi n nguyên N i dung phương th c là v 3 c nh: c nh 1 ñi qua *this d2 c... n tích) có ñ nh là các ñi m v a nh p Chương trình ñư c t ch c thành 2 l p: + L p DIEM g m: - Các thu c tính: x y (to ñ c a ñi m) - Các phương th c void nhapsl() ; // Nh p x, y void in() ; // In to ñ double do_dai(DIEM d2); // Tính ñ dài ño n th ng qua 2 ñi m // (ñi m n xác ñ nh b i this ñi m d2) + L p TAM_GIAC g m: - Các thu c tính: DIEM d1,d2,d3; // 3 ñ nh c a tam giác - Các phương th c: void . TƯỢNG 2.1. Khai báo biến, mảng ñối tượng Một lớp (sau khi ñịnh nghĩa) có thể xem như một kiểu ñối tượng và có thể dùng ñể khai báo các biến, mảng ñối tượng. . phần dữ liệu) của lớp có thể là ñối tượng của lớp khác ñã ñịnh nghĩa bên trên. + Phương thức có giá trị trả về kiểu ñối tượng và con trỏ ñối tượng. Nội dung

Ngày đăng: 10/10/2013, 09:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan