Bài giảng Lập trình hướng đối tượng - Chương 2: Lớp và đối tượng - Phạm Minh Hoàn
Hàm thành phần tĩnh là chung cho toàn bộ lớp và không lệ thuộc vào một đối tượng cụ thể.
Hàm thành phần tồn tại ngay khi lớp chưa có đối tượng nào.
Trong thân hàm thành phần tĩnh chỉ cho phép truy nhập đến dữ liệu thành phần tĩnh.
123 trang |
Chia sẻ: huongthu9 | Lượt xem: 518 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Bài giảng Lập trình hướng đối tượng - Chương 2: Lớp và đối tượng - Phạm Minh Hoàn, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
CHƯƠNG 2: LỚP VÀ ĐỐI TƯỢNGPhạm Minh HoànBộ môn công nghệ thông tin – Đại học Kinh tế Quốc dânEmail: hoanpm@neu.edu.vn Phạm Minh Hoàn - NEUNỘI DUNG CHƯƠNG TRÌNHChương này trình bày những vấn đề sau đây:Định nghĩa lớpTạo lập đối tượngTruy nhập đến các thành phần của lớpCon trỏ đối tượngCon trỏ thisHàm bạnDữ liệu thành phần tĩnh, hàm thành phần tĩnhHàm tạo, hàm hủyHàm tạo sao chépToán tử tải bộiPhạm Minh Hoàn - NEUĐỊNH NGHĨA LỚPLớp là khái niệm trung tâm của lập trình hướng đối tượng, nó là sự mở rộng của các khái niệm cấu trúc (struct) của C. Ngoài các thành phần dữ liệu, lớp còn chứa các thành phần hàm, còn gọi là phương thức (method) hoặc hàm thành viên (member function). Lớp có thể xem như một kiểu dữ liệu các biến, mảng đối tượng. Từ một lớp đã định nghĩa, có thể tạo ra nhiều đối tượng khác nhau, mỗi đối tượng có vùng nhớ riêng. Phạm Minh Hoàn - NEUĐỊNH NGHĨA LỚPCú pháp:class tên_lớp{private:[Khai báo các thuộc tính][Định nghĩa các hàm thành phần (phương thức)]public:[Khai báo các thuộc tính][Định nghĩa các hàm thành phần (phương thức)]} ;Phạm Minh Hoàn - NEUĐỊNH NGHĨA LỚPThuộc tính là dữ liệu của lớp, phương thức là các hàm tác động lên dữ liệu của lớp đó được gọi là hàm của lớp. Dữ liệu và hàm thành viên được gọi chung là các thành phần của lớp.Phạm Minh Hoàn - NEUĐỊNH NGHĨA LỚPCác thành phần của lớp được tổ chức thành hai vùng: vùng sở hữu riêng (private) và vùng dùng chung (public) để quy định phạm vi sử dụng của các thành phần. Những thành phần thuộc vùng sở hữu riêng chỉ được sử dụng trong phạm vi của lớp, còn những thành phần thuộc vùng dùng chung có thể sử dụng cả ở trong và ngoài lớp.Phạm Minh Hoàn - NEUKHAI BÁO DỮ LIỆU THÀNH PHẦNKhai báo các thuộc tính (dữ liệu) được thực hiện như khai báo biến có kiểu chuẩn hoặc kiểu ngoài chuẩn đã được đị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 chính của lớp đó, nhưng có thể là kiểu con trỏ của lớp này.Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNCác hàm thành phần có thể được xây dựng bên trong hoặc bên ngoài định nghĩa lớp.Hàm thành phần đơn giản, có ít dòng lệnh sẽ được viết bên trong định nghĩa lớp như hàm thông thường.Hàm thành phần dài thì viết bên ngoài định nghĩa lớp.Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNCú pháp định nghĩa hàm thành phần ở bên ngoài lớp:Kiểu_trả_về_của_hàm Tên_lớp::Tên_hàm(khai báo các tham số){ //Nội dung hàm}Toán tử :: được gọi là toán tử phân giải miền xác định, được dùng để chỉ ra lớp mà hàm đó thuộc vào.Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNHàm thành phần có thể không có giá trị trả về (kiểu void) hoặc có thể trả về một giá trị có kiểu bất kỳ, kể cả giá trị kiểu đối tượng, con trỏ đối tượng, tham chiếu đối tượng.Tham số của hàm thành phần có thể có kiểu bất kỳ: kiểu chuẩn, kiểu ngoài chuẩn, kiểu đối tượng của chính phương thức, con trỏ hoặc tham chiếu đến kiểu đối tượng này.Trong thân hàm thành phần, có thể sử dụng các thuộc tính của lớp, các hàm thành phần khác và các hàm tự do trong chương trình. Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNChú ý : Các thành phần dữ liệu khai báo là private nhằm bảo đảm nguyên lý che dấu thông tin, 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 hàm thành phần khai báo là public có thể được gọi tới từ các hàm thành phần public khác trong chương trình.Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNVí dụ: Định nghĩa lớp để mô tả và xử lý các điểm trên màn hình đồ họa. 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 của một điểmHiển thị một điểmẨn một điểmPhạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNVí dụ: Xậy dựng lớp DIEM.class DIEM{private:int x,y,m; public:void nhapdl();void hien();void an(){ putpixel(x,y,getbkcolor());}};Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNVí dụ: Xậy dựng lớp DIEM.void DIEM::nhapdl(){cout>x>>y;cout>m;}Phạm Minh Hoàn - NEUKHAI BÁO HÀM THÀNH PHẦNVí dụ: Xậy dựng lớp DIEM.void DIEM::hien(){int mau_ht;mau_ht = getcolor();putpixel(x,y,m);setcolor(mau_ht);}Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGĐối tượng là biến thuộc kiểu lớp. Cú pháp khai báo biến đối tượng: Tên_lớp Danh_sách_biến ; Đối tượng cũng có thể khai báo khi định nghĩa lớp theo cú pháp:class tên_lớp{ ...} ;Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGMỗ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. Không có vùng nhớ riêng để chứa các hàm thành phần cho mỗi đối tượng. Các hàm thành phần sẽ được sử dụng chung cho tất cả các đối tượng cùng lớp. Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGTruy nhập tới các thành phần của đối tượng:Truy nhập đến dữ liệu thành phần: Tên_đối_tượng.Tên_thuộc_tínhChú ý: Dữ liệu thành phần riêng chỉ có thể được truy nhập bởi những hàm thành phần của cùng một lớpĐối tượng của lớp cũng không thể truy nhập.Truy nhập đến hàm thành phần của lớp: Tên_đối_tượng.Tên_hàm (Tham_số_thực_sự);Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGVí dụ:#include #include class DIEM{private: int x,y ;public:void nhapsl( ){cout >x>>y ;}void hienthi( ){ coutmain(){DIEM d1;d1.nhapsl();d1.hienthi ();getch();DIEM d2;d2.x = 10;d2.y = 20;d2.hienthi();getch();}Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGVí dụ: Viết chương trình nhập hai số nguyên, tìm giá trị lớn nhất của hai số nguyên đó.#include #include #include using namespace std;class SN{int m,n;public :void nhap( ){cout>m>>n ;}Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGVí dụ: Viết chương trình nhập hai số nguyên, tìm giá trị lớn nhất của hai số nguyên đó.int max(){ return m>n?m:n;}void hienthi( ){cout#include class sophuc{ float a,b;public:sophuc(float x, float y){a=x; b=y;}sophuc tong(sophuc,sophuc);void hienthi(sophuc);};Phạm Minh Hoàn - NEUTẠO LẬP ĐỐI TƯỢNGVí dụ: Viết chương trình xây dựng lớp số phức. sophuc sophuc::tong(sophuc c1, sophuc c2) {sophuc c3;c3.a=c1.a + c2.a ;c3.b=c1.b + c2.b ;return (c3);}void sophuc::hienthi(){ cout Tên_thuộc_tínhTên_con_trỏ -> Tên_hàm(các tham số thực sự)Nếu con trỏ chứa đầu địa chỉ của mảng, có thể dùng con trỏ như tên mảng.Phạm Minh Hoàn - NEUMẢNG VÀ CON TRỎ ĐỐI TƯỢNGQuy tắc sử dụng thuộc tính của mảng và con trỏ đối tượng:Để truy xuất một thuộc tính của đối tượng sử dụng toán tử . hoặc toán tử ->. 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 viết đi kèm tên đối tượng hoặc tên con trỏ theo các mẫu sau:ten_doi_tuong.ten_thuoc_tinhten_con tro->ten_thuoc_tinhten_mang_doi_tuong[chi_so].ten_thuoc_tinhten_con_tro[chi_so].ten_thuoc_tinhPhạm Minh Hoàn - NEUMẢNG VÀ CON TRỎ ĐỐI TƯỢNGVí dụ: Viết chương trình quản lý mặt hàng gồm mã hàng và đơn giá bằng định nghĩa lớp. #include #include class mhang{int maso;float gia;Phạm Minh Hoàn - NEUMẢNG VÀ CON TRỎ ĐỐI TƯỢNGVí dụ: Viết chương trình quản lý mặt hàng gồm mã hàng và đơn giá bằng định nghĩa lớp. public: void Setdata(int a, float b){ maso = a; gia = b;}void show(){ cout >k;mhang *p = new mhang[k];mhang *d = p;int x,i;float y;cout>x>>y; p -> Setdata(x,y); p++;}Phạm Minh Hoàn - NEUMẢNG VÀ CON TRỎ ĐỐI TƯỢNGVí dụ: Viết chương trình quản lý mặt hàng gồm mã hàng và đơn giá bằng định nghĩa lớp. for (i = 0; i show();d++;}getch();}Phạm Minh Hoàn - NEUTHAM SỐ CỦA HÀM THÀNH PHẦN CON TRỎ THISMỗi hàm thành phần của lớp có một tham số ẩn, đó là con trỏ this. Con trỏ this trỏ đến từng đối tượng cụ thể. void nhapsl( ){cout>this->x>>this->y ;}Phạm Minh Hoàn - NEUTHAM SỐ CỦA HÀM THÀNH PHẦN CON TRỎ THISCon trỏ this là tham số thứ nhất của hàm thành phần. Khi một lời gọi hàm thành phần được phát ra bởi một đối tượng thì tham số truyền cho con trỏ this chính là địa chỉ của đối tượng đó. Ví dụ: Xét một lời gọi tới hàm nhapsl():DIEM d1 ;d1.nhapsl();Trong trường hợp này của d1 thì this =&d1.Do đó: this -> nhapsl() chính là d1.nhapsl()Phạm Minh Hoàn - NEUHÀM BẠNHàm bạn không phải là hàm thành phần của lớp.Việc truy nhập tới hàm bạn được thực hiện như hàm thông thường.Trong thân hàm bạn của một lớp có thể truy nhập tới các thuộc tính của đối tượng thuộc lớp này. Đây là sự khác nhau duy nhất giữa hàm bạn và hàm thông thường. Hàm bạn có thể sử dụng chung cho nhiều lớp.Phạm Minh Hoàn - NEUHÀM BẠNKhai báo hàm bạn:Cách 1: Dùng từ khóa friend để khai báo hàm trong lớp và xây dựng hàm bên ngoài như các hàm thông thường (không dùng từ khóa friend).Cách 2: Dùng từ khóa friend để xây dựng hàm trong định nghĩa lớp.Phạm Minh Hoàn - NEUHÀM BẠNKhai báo hàm bạn (cách 1):class A {private: // Khai báo các thuộc tính public:...// Khai báo các hàm bạn của lớp A friend void f1 (...);friend double f2 (...);...};Phạm Minh Hoàn - NEUHÀM BẠNKhai báo hàm bạn (cách 1):// Xây dựng các hàm f1,f2void f1 (...){ ...} double f2 (...){ ...}Phạm Minh Hoàn - NEUHÀM BẠNKhai báo hàm bạn (cách 2):class A { // Khai báo các hàm bạn của lớp A friend void f1 (...){ ...} friend double f2 (...){ ...}} ;Phạm Minh Hoàn - NEUHÀM BẠNVí dụ: #include #include class sophuc{ float a,b;public:sophuc() {}sophuc(float x, float y){a=x; b=y;}friend sophuc tong(sophuc,sophuc);friend void hienthi(sophuc);};Phạm Minh Hoàn - NEUHÀM BẠNVí dụ: sophuc tong(sophuc c1, sophuc c2){sophuc c3;c3.a=c1.a + c2.a ;c3.b=c1.b + c2.b ;return (c3);}void hienthi(sophuc c){ cout#inlcule class DIEM{private: int x,y;public:void in(){ cout in();getch();}Phạm Minh Hoàn - NEUHÀM TẠOChú ý 2:Khi một đối tượng được khai báo thì hàm tạo của lớp tương ứng sẽ tự động thực hiện và khởi gán giá trị cho các thuộc tính của đối tượng. Dựa vào các tham số trong khai báo mà chương trình dịch sẽ biết cần gọi đến hàm tạo nào.Khi khai báo mảng đối tượng không cho phép dùng các tham số để khởi gán cho các thuộc tính của các đối tượng mảng.Câu lệnh khai báo một biến đối tượng sẽ gọi tới hàm tạo một lần.Câu lệnh khai báo một mảng n đối tượng sẽ gọi tới hàm tạo mặc định n lần.Với các hàm có các tham số kiểu lớp, thì chúng chỉ xem là các tham số hình thức, vì vậy khai báo tham số trong dòng đầu của hàm sẽ không tạo ra đối tượng mới và do đó không gọi tới các hàm tạo.Phạm Minh Hoàn - NEUHÀM TẠOVí dụ:#include #include #include class DIEM{private: int x,y;public: DIEM(){ x = y = 0; }DIEM(int x1, int y1){ x = x1; y = y1; }friend void in(DIEM d){ cout > n;q = new DIEM [n+1]; //n+1 lan goi //ham tao khong doifor (int i=0;i#include class DIEM{private: int x,y;public:DIEM(int x1, int y1){ x=x1; y=y1;}void in(){ cout #include class DIEM{private: int x,y;public:DIEM(int x1=0, int y1=0){ x = x1; y = y1; }void in(){ cout >) và xuất (#include class PS{private: int t,m;public:friend ostream& operator> (istream& is, PS &p){cout >p.t>>p.m;return is;}};Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉP MẶC ĐỊNHVí dụ:main(){PS d;cout >d;cout> (istream& is,DT &d);};Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPBây giờ chúng ta hãy theo dõi xem việc dùng hàm tạo mặc định trong đoạn chương trình sau sẽ dẫn đến sai lầm như thế nào:DT d;cin >> d;/* Nhập đối tượng d gồm: nhập một số nguyên dương và gán cho d.n, cấp phát vùng nhớ cho d.n, nhập các hệ số của đa thức và chứa vào vùng nhớ được cấp phát*/ DT u(d);/* Dùng hàm tạo mặc định để xây dựng đối tượng u theo d. Kết quả: u.n = d.n và u.a = d.a. Như vậy hai con trỏ u.a và d.a cùng trỏ đến một vùng nhớ.*/Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPBây giờ chúng ta hãy theo dõi xem việc dùng hàm tạo mặc định trong đoạn chương trình sau sẽ dẫn đến sai lầm như thế nào:DT d;cin >> d;/* Nhập đối tượng d gồm: nhập một số nguyên dương và gán cho d.n, cấp phát vùng nhớ cho d.n, nhập các hệ số của đa thức và chứa vào vùng nhớ được cấp phát*/ DT u(d);/* Dùng hàm tạo mặc định để xây dựng đối tượng u theo d. Kết quả: u.n = d.n và u.a = d.a. Như vậy hai con trỏ u.a và d.a cùng trỏ đến một vùng nhớ.*/Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPVí dụ:#include #include #include class DT{private: int n; // Bac da thucdouble *a; // Tro toi vung nho chua cac he //so da thuc a0,a1,...Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPVí dụ:public:DT(){this->n=0; this->a=NULL;}DT(int n1){this->n=n1;this->a= new double[n1+1];}Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPVí dụ:friend ostream& operator> (istream& is,DT &d);};Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPVí dụ:ostream& operator> (istream& is,DT &d){if (d.a != NULL) delete d.a;cout >d.n;d.a = new double[d.n+1];cout> d.a[i];}return is;} Phạm Minh Hoàn - NEUHÀM TẠO SAO CHÉPVí dụ:main(){DT d;clrscr();cout> d;DT u(d);cout > d;cout > u;cout class Count{ private:static int counter;int obj_id;public:Count();static void display_total();void display();~Count();};Phạm Minh Hoàn - NEUHÀM HỦYVí dụ:int Count::counter;Count::Count() { counter++; obj_id = counter; } Count::~Count() { counter--; cout yêu cầu hàm toán tử phải là hàm thành phần của lớp, không thể dùng hàm bạn để định nghĩa toán tử tải bội.Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Xây dựng lớp số phức#include #include class sophuc{float a,b;public : sophuc() {}sophuc(float x, float y){a=x; b=y;}Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Xây dựng lớp số phứcfriend sophuc operator +(sophuc c1, sophuc c2){sophuc c3;c3.a= c1.a + c2.a ;c3.b= c1.b + c2.b ;return (c3);}void hienthi(sophuc c){cout#include #include class string{ char s[80];public:string() { *s='\0'; }string(char *p) { strcpy(s,p); }char *get() { return s;}string operator + (string s2);string operator = (string s2);int operator (string s2);int operator == (string s2);};Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Toán tử tải bội trên lớp chuỗi ký tựstring string::operator +(string s2){strcat(s,s2.s);return *this ;}string string::operator =(string s2){strcpy(s,s2.s);return *this;}Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Toán tử tải bội trên lớp chuỗi ký tựint string::operator (string s2){ return strcmp(s,s2.s)>0 ;}Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Toán tử tải bội trên lớp chuỗi ký tựint string::operator ==(string s2){return strcmp(s,s2.s)==0 ;}Phạm Minh Hoàn - NEUTOÁN TỬ TẢI BỘIVí dụ: Toán tử tải bội trên lớp chuỗi ký tựmain(){clrscr();string o1 ("Trung Tam "), o2 (" Tin hoc"), o3;cout o2) cout o2 \n";if (o1 #include class HDBH{private:int shd;char *tenhang;double tienban;static int tshd;static double tstienban;Phạm Minh Hoàn - NEUVÍ DỤ THÀNH PHẦN TĨNHVí dụ (tiếp):public:static void in(){cout <<”\n” <<tshd;cout <<”\n” <<tstienban;}};//Khai báo và khởi gán biến tĩnh tsdhint HDBH::tshd=5;//Khai báo và khởi gán biến tĩnh tstienbandouble HDBH::tstienban=20000.0;Phạm Minh Hoàn - NEUVÍ DỤ THÀNH PHẦN TĨNHVí dụ (tiếp):void main(){HDBH::in();getch();}Phạm Minh Hoàn - NEUBÀI TẬPBài 4: Xây dựng lớp Sinhvien để quản lý họ tên sinh viên, năm sinh, điểm thi 9 môn học của các sinh viên. Cho biết sinh viên nào được làm khóa luận tốt nghiệp, bao nhiêu sinh viên thi tốt nghiệp, bao nhiêu sinh viên thi lại, tên môn thi lại. Tiêu chuẩn để xét như sau:Sinh viên làm khóa luận phải có điểm trung bình từ 7 trở lên, trong đó không có môn nào dưới 5.Sinh viên thi tố nghiệp khi điểm trung bình nhỏ hơn 7 và điểm các môn không dưới 5.Sinh viên thi lại môn dưới 5.Phạm Minh Hoàn - NEUBÀI TẬPViết chương trình thực hiện các yêu cầu sau đây:Nhập dữ liệu cho các hóa đơn (dùng cấu trúc danh sách liên kết đơn), các thông tin của hóa đơn bao gồm: số hóa đơn, tên hàng, tiền bán.Chương trình có sử dụng toán tử new và delete. In ra danh sách hóa đơn có sắp xếp theo thứ tự giảm dần của tiền bán.Cho biết tổng số hóa đơn và tổng số tiền bán.Phạm Minh Hoàn - NEU
Các file đính kèm theo tài liệu này:
- bai_giang_lap_trinh_huong_doi_tuong_chuong_2_lop_va_doi_tuon.ppt