CHƯƠNG 3 CÁCH THỨC XÂY DỰNG LỚP 1 OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu MỤC TIÊU yXây dựng lớp cơ bản dùng C/C++ yPhân biệt được public, private yCách viết chương trình chính sử
Trang 1CHƯƠNG 3 CÁCH THỨC XÂY DỰNG LỚP
1
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
MỤC TIÊU
yXây dựng lớp cơ bản dùng C/C++
yPhân biệt được public, private
yCách viết chương trình chính sử dụng lớp, cách truy cập đến thành viên của lớp
2
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
NỘI DUNG CHI TIẾT
yLỚP (CLASS) VÀ ĐỐI TƯỢNG (OBJECT)
yHIỆN THỰC LỚP TRONG C++
{ KHAI BÁO LỚP
{ HiỆN THỰC HÀNH VI
HOÀN THIỆN LỚP
3
{ HOÀN THIỆN LỚP
ySO VỚI STRUCT TRONG C++
yTHUỘC TÍNH TRUY CẬP
yLOẠI HÀNH VI CỦA LỚP
4 LỚP LÀ GÌ ?
yKhi một số các đối tượng cùng tính chất được nhóm lại, tạo nên lớp
girl
class object
Lan Cúc Trúc Mai
Trang 25 Như vậy,
yLớp được dùng để mô tả tất cả các đối tượng có hành
vi và dữ liệu tương tự nhau
yMột lớp là một mẫu (template) hay một khuôn dạng
(mold) để từ đó có thể tạo ra những đối tượng mới
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
yCó thể xem lớp như một dạng đối tượng (object's
type)
yHay kiểu dữ liệu (data type)
Lớp là sự biểu diễn của một mẫu các đối
tượng và mô tả cách mà những đối tượng này
được cấu tạo bên trong
GV: Võ Hồng Bảo Châu
6 HIỆN THỰC LỚP TRONG C++
class NAME{
//members
};
yNhư vậy, lớp được bao bọc bởi từ khóa class ở bên
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
ngoài
yBên trong là các thành phần, bao gồm dữ liệu và hành vi
GV: Võ Hồng Bảo Châu
7
KHAI BÁO CLASS
class ClassName [: [<public|private>] <FatherClassName,]
{ public :
< data >
<method>
private :
< data >
• Chương này tạm không đề cập đến đặc tính thừa kế
- Có chương riêng về tính thừa kế.
• Các thuộc tính truy cập: public, private , protected :
ầ
< data >
< method>
protected :
< data >
<method>
} ; // có ký tự ‘;’
từ khóa chỉ định đặc tính của từng thành phần ngay sau chỉ thị này Mặc định là private.
• public : cho phép bên ngoài truy cập Æ interface của lớp
• private : các thành phần nội, không cho phép bên ngoài truy cập
• protected : các thành phần dành cho lớp thừa kế truy cập, không cho phép các đối tượng không phải
là con truy cập.
8
HIỆN THỰC HÀNH VI CHO CLASS
y Hiện thực bên trong class – Các hành vi inline
ÆKhông dùng các phát biểu continue , do , for , goto ,
switch , case , break , while.
Cú pháp:
DataType MethodName (Parameters) { <code>
}
y Hiện thực bên ngoài class
DataType ClassName::MethodName (Parameters) { <code>
}
yToán tử :: là toán tử xác định tầm vực của method (scope
resolution operator)
Trang 3VÍ DỤ
OK
Khi hiện thực method bên ngoài class, KHÔNG khai báo lại
access-specifier.
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
10
SO VỚI STRUCT TRONG C/C++
yclass có thêm các hàm chứa bên trong
yCác hàm phải chỉ định thêm thuộc tính truy cập
(access attributes), chẳng hạn
{public
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
{private
{protected
yCác dữ liệu thành viên cũng phải có thuộc tính truy cập
GV: Võ Hồng Bảo Châu
11
SO VỚI STRUCT TRONG C/C++
yChẳng hạn,
struct PERSON{
char name[40];
int birthYear;
};
yTương đương với class PERSON{
public:
char name[40];
int birthYear;
};
Khi đó mới có thể truy cập được name, birthYear
như đã làm trong kiểu struct.
SO VỚI STRUCT TRONG C/C++
12
struct StructName
{
<data>
};
class ClassName
{
<data>
Modifier : Type1 Func1 ()
public private protected
};
Type1 Func1 (StructName stru) { <code>}
Type2 Func2 (StructName stru) {<code>}
các hàm đều toàn cục
Modifier : Type1 Func1 ()
{ <code>}
Modifier : Type2 Func2 ()
{ <code>}
};
Chỉ có method public là toàn cục
Trang 413 HOÀN THIỆN LỚP
yLớp PERSON ở trên mới chỉ mang tính mô tả, chưa sử
dụng được
yĐể hoàn thiện, có 2 cách viết khác nhau
{ Đơn giản
h
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
{ Phức tạp
GV: Võ Hồng Bảo Châu
14 Cách đơn giản
class PERSON{
char name[40];
int birthYear;
public:
void getData(){
cout << "Name: ";
cin.getline(name, 39);
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
g cout << "Year of birth: ";
cin >> birthYear;
} int age(){
cout << name << " is " << 2008 – birthYear
<< " years old\n"
} };
GV: Võ Hồng Bảo Châu
15 Phức tạp và chuyên nghiệp hơn
class PERSON{
char name[40];
int birthYear;
public:
void getData();
int age();
};
void PERSON::getData(){
void PERSON::getData(){
cout << "Name: ";
cin.getline(name, 39);
cout << "Year of birth: ";
cin >> birthYear;
}
int PERSON::age(){
cout << name << " is " << 2008 – birthYear << " years
old\n"
}
16 Lưu ý,
yTrong lớp PERSON cũng có một vài điều nho nhỏ cần quan tâm về việc dùng ngôn ngữ C++
{Do phép toán trích (>>) chỉ nhận chuỗi ký tự không chứa ký tự blank (space, tab, new line), nên phải dùng hàm getline().
{Hàm getline() có trong lớp chứa đối tượng cin.
{Hàm getline() có trong lớp chứa đối tượng cin.
Trang 5Ví dụ
#include <iostream.h>
main() {
char name[4][40];
int n = 0;
cout << "Name of people loved me\n";
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
cout << Name of people loved me\n ;
while(cin.getline(name[n++],40));
n;
cout << "They are as follow\n";
for ( int i = 0; i < n; i++ )
cout << name[i] << "\n"; return 1;
}
GV: Võ Hồng Bảo Châu
18 TẠO ĐỐI TƯỢNG
ySau khi có lớp, có thể tạo đối tượng bằng cách khai báo biến thuộc kiểu lớp
PERSON a, b;
ya, b là 2 đối tượng.
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
yKhi đó a và b có thể coi là 2 instance (là ví dụ, là trường hợp, là cái có thực) của lớp PERSON.
GV: Võ Hồng Bảo Châu
19
yTrong ví dụ trên, có thể tạo các đối tượng như sau:
main(){
PERSON a;
a.getData();g ();
a.age()
}
20 THUỘC TÍNH TRUY CẬP LÀ GÌ ?
yHay còn gọi hình thức truy cập, hay tầm nhìn
yCó 3 thuộc tính, nhằm để quy định khả năng truy cập đến các thành viên của lớp, có "trông thấy" được thành viên nào đó không:
{ private
{ private
{ protected
{ public
Trang 6public
yTừ bất kỳ hàm nào có chứa đối tượng thuộc lớp, đều
truy cập được các thành viên có thuộc tính này
{Vì vậy những thành viên mang thuộc tính public còn được
xem là thành viên có khả năng giao tiếp với môi trường bên
ngoài.
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
g
GV: Võ Hồng Bảo Châu
22
private
yprivate: ngược lại với public, các thành viên mang thuộc tính private chỉ được truy cập từ những hành
vi thuộc lớp và từ những hành vi bè bạn (friend), từ
những lớp là bè bạn của nó
{private là thuộc tính chuẩn của ngôn ngữ C++, để thông báo
ằ
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
rằng đây là những thành viên riêng tư của lớp, nội bộ của lớp mới nhìn thấy, mới nói chuyện được, chúng không giao tiếp với thế giới bên ngoài lớp
GV: Võ Hồng Bảo Châu
23
protected
yprotected: để cho phép các thành viên trong
những lớp hậu duệ được quyền truy cập đến
{ Nói cách khác, ngoài việc nói chuyện với các thành viên của lớp,
những thành viên có thuộc tính truy cập protected còn có
thể giao tiếp với các thành viên trong lớp con cháu g p g p
24 Giả sử có lớp sau đây
#include <iostream.h>
class POINT{
int x, y;
public:
void set( int xx, int yy ){
x = xx;
y = yy;
} int get( int& xx, int& yy ){
xx = x;
yy = y;
return 1;
} };
Trang 7main()
{
POINT p;
p.set( 10, 5 );
Không được
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
cout << p.x << " " << p.y << endl;
return 1;
}
GV: Võ Hồng Bảo Châu
26 Sửa lại
main() { POINT p;
p.set( 10, 5 );
int x y;
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
int x, y;
p.get( x,y );
cout << "Coordinate (" << x
<< "," << y << ")\n";
return 1;
}
GV: Võ Hồng Bảo Châu
27 LOẠI HÀNH VI CỦA LỚP
yTự động thực hiện
yNhận biết và thay đổi giá trị dữ liệu
yPhép toán
yĐặc thù của lớpặ p
Mỗi hành vi có thể có thuộc tính truy cập khác
nhau Những hành vi chỉ phục vụ cho hành vi khác
của lớp sẽ có thuộc tính là private.
28
SỬ DỤNG CLASS
y Sử dụng class trong chương trình là định nghĩa biến đối tượng (biến tĩnh, biến động, mảng tĩnh, mảng động)
y Cú pháp:
ClassName Obj, *pObj = new ClassName;
ClassName ObjArr1[100];
ClassName * ObjArr2;
int MaxCount=100;
ObjArr2= new ClassName[MaxCount];
Truyền thông báo cho 1 đối tượng:
Obj.Method1();
pObj -> Method2();
ObjArr1[20].Method3();
ObjArr2[7].Method4();
Trang 8VÍ DỤ 1
29
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
VÍ DỤ 2:
public access
specifier
30
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
VÍ DỤ 3 protected access specifier 31 VÍ DỤ 3- private access specifier
32
Trang 9Gợi ý về xây dựng chương trình OOP
Xây dựng class
(1) Lấy các khái niệm liên quan đến bài toán ( danh từ chính trong đề bài)
để xây dựng thành class (thí dụ: Sinh viên).
(2) Lấy các danh từ mô tả liên quan đến từng khaí niệm ở bước (1) Đó
chính là các thuộc tính của class ( thí dụ: tên, tuổi, địa chỉ).
(3) Lấy các tác vụ phải xử lý ( động từ trong đề bài) Đó chính là các hành vi
bli ủ l ì hà i ầ đế hú
public của class vì hàm main cần đến chúng.
(4) Tự hỏi: Để có thể thực hiện hành vi public trong bước 3, có cần thêm
các hành vi phụ trợ nào không? Nếu có thì đó là hành vi thêm
(5) Môi trường bên ngoài thực sự chỉ cần các hành vi nào thì đó là các hành
vi public Các hành vi còn lại là các hành vi private hoặc protected
(5) Liệu lớp này có cần được phát triển thêm để giải các bài toán thuộc
nhóm bài toàn này nữa hay không? Nếu có thì một số hành vi cần có
thuộc tính protected
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
34 Kinh nghiệm
Mỗi thuộc tính của class, người ta thường xây dựng 2 hành vi public:
DataType getPropertyName();
void setProperTyName (DataType
newValue);
Với 2 hành vi này, bên ngoài truy xuất được từng thuộc tính của đối tượng Các hành vi khác đều cần đến các hành vi này.
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
35 Thí dụ:
class CIRCLE
{ double x,y,r;
public:
double getR() { return r ; } ể
double getR() { return r ; }
void setR ( double newr )
{ if ( newr >=0 ) r = newr ;
}
};
Có cơ hội kiểm tra dữ liệu đầu vào
36
Sử dụng class trong hàm main
yXác định các biến đối tượng cần có
yTrật tự xử lý của đề bài chính là trật tự truyền thông báo cho các đối tượng
Trang 10BÀI TẬP VÍ DỤ
37
(1) Viết chương trình nhập 1 hệ phương trình bậc
nhất 2 ẩn Xuất nghiệm
(2) Viết chương trình nhập 1 mảng số nguyên,
xuất trị lớn nhất, xuất mảng tăng dần
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
38
Thí dụ:Viết chương trình nhập 1 hệ phương trình bậc nhất 2
ẩn.Xuất nghiệm.
Phân tích:
yKhái niệm liên quan: Hệ phương trình bậc nhất 2
ẩn Æ ax+by = c Î class HPTB1 dx+ey = f
Tá (hà h i ủ lớ ) Nhậ X ấ hiệ
yTác vụ (hành vi của lớp): Nhập, Xuất nghiệm
Îclass HPTB1 data: double a,b,c,d,e,f methods: Nhap() , XuatNghiem()
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
39
#include <conio.h>
#include <iostream.h>
class HPTB1
{ double a,b,c,d,e,f ; // private , default
public : // các hành vi bên ngoài cần để tương tác
void Nhap() // Hiện thực method bên trong khai báo class
{ cout << "Nhap 3 he so a,b,c cua phuong trinh 1 ax+by=c :";
cin>>a>>b>>c;
cout << "Nhap 3 he so d,e,f cua phuong trinh 2 dx+ey=f :";
cin>>d>>e>>f;
}
void XuatNghiem(); // chỉ prototype, để hiện thực bên ngoài khi báo class
};
void PTB1::XuatNghiem() // Hiện thực method bên ngoài khai báo class
{ double D=a*e-b*d;;
if (D==0) cout<< "Vo nghiem";
else cout<< "Nghiem x=" << (c*e-b*f)/D << “ Nghiem y=" << (a*f-c*d)/D
<<'\n';
}
void main()
{ HPTB1 p; // định nghĩa 1 hệ phương trình bậc nhất p
clrscr();
p.Nhap(); // Truyền thông báo nhập cho p
p.XuatNghiem(); // Truyền thông báo xuất nghiệm cho p
getch();
}
40
Thí dụ: Viết chương trình nhập 1 mảng số nguyên int, xuất trị lớn nhất, xuất mảng tăng dần.
Phân tích
Khái niệm liên quan : mảng
số int , mô tả bằng int* a, n
Tác vụ : Input (nhập),
GetMax (lấy trị lớn nhất), AscSort (sắp xếp tăng), Output (xuất) Tất cả đều
#include <iostream.h>
#include <conio.h>
class MangInt { private: int* a, n;
public:
void Input(); int GetMax();
void AscSort(); void Output();
}
Phải hiện thực bên ngoài lớp vì có dùng phát biểu lặp
Output (xuất) Tất cả đều cần cho bên ngoài truy xuất vì hàm main cần sử dụng các tác vụ này.
Giải bài toán :
Cần 1 mảng (tên m).
Trật tự truyền thông báo:
m.Input();
cout << m.GetMax();
m.AscSort(); m.Output ;
};
void MangInt:: Input() { do
{ cout<< “ Number of element:”;
cin>> n;
} while (n<=0);
a= new int[n]; // cấp bộ nhớ for (int i=0; i<n;i++)
{ cout << “a[“ << i << “]=“; cin>>a[i]; } }
Trang 11int MangInt:: getMax()
{ int t=a[0];
for (int i=1; i<n;i++)
if (t < a[i]) t=a[i];
return t;
}
void MangInt:: AscSort()
{ for (int i=0; i<n-1;++i)
for (int j= n-1; j>i ; j )
if (a[j] < a[j-1])
// Sử dụng lớp void main() { MangInt m;
Viết chương trình nhập 1 mảng số nguyên int, xuất trị lớn nhất, xuất mảng tăng dần.
{ int t=a[j];
a[j]=a[j-1];
a[j-1]=t;
}
}
void MangInt::Output()
{ for (int i=0; i<n;i++)
cout << a[i] << ‘ ‘ ;
}
{ MangInt m;
m.Input();
cout <<“ Max val:” << m.GetMax()
<<‘\n’;
m.AscSort();
cout << “Sorted array\n”;
m.Output();
getch();
}
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
42
Tóm tắt
y Lập trình OOP cũng tương tự như lập trình POP nhưng mô tả bài toán dưới dạng các class, các tác vụ xử lý dữ liệu thành các hành vi của class.
y Khai báo class cũng tương tự như khai báo struct nhưng có khác struct ở chỗ đưa các tác vụ thao tác lên struct vào trong class và gọi chúng là các methods của lớp.
struct StructName class ClassName public
{
<data>
};
Type1 Func1 (StructName stru) { <code>}
Type2 Func2 (StructName stru) {<code>}
các hàm đều toàn cục
{
<data>
Modifier : Type1 Func1 ()
{ <code>}
Modifier : Type2 Func2 ()
{ <code>}
};
Chỉ có method public là toàn cục
public private protected
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
43
Tóm tắt (tt)
yThiết kế class
Làm việc với cái gì Î Tên class
Mô tả nó bằng gì ? Î Properties
Thao tác gì lên nó Î Behavior
ế
ySử dụng lớp là định nghĩa biến (đơn, mảng, pointer)
thuộc lớp theo cú pháp định nghĩa biến của C
yNhập dữ liệu cơ bản: cin >> SimpleVar;
yXuất dữ liệu cơ bản : cout << SimpleData;
BÀI TẬP TẠI LỚP
44
yXây dựng lớp PhanSo
{Thuộc tính: tử số, mẫu số (số nguyên)
{Hành vi: Nhập, Xuất (dạng tử số/mẫu số).
Trang 12BÀI TẬP TẠI LỚP
yXây dựng lớp SinhVien
{Thuộc tính:
Ù Mã SV (chuỗi kí tự)
Ù Họ tên (chuỗi kí tự).
Ù Năm sinh(số nguyên)
45
Ù Năm sinh(số nguyên).
Ù Lớp (chuỗi kí tự).
Ù ĐCB (điểm cơ bản:số thực).
Ù ĐCN (điểm chuyên ngành: số thực).
{Hành vi:
Ù Nhập, Xuất.
Ù Tính tuổi (in ra màn hình tuổi, không cần trả về kết quả).
Ù Tính ĐTB (ĐTB=(ĐCB+ĐCN)/2, kết quả trả về là 1 số thực).
OOP-CHƯƠNG 3-XÂY DỰNG LỚP GV: Võ Hồng Bảo Châu
46
THANH YOU
OOP-CHƯƠNG 3-XÂY DỰNG LỚP
THANH YOU
GV: Võ Hồng Bảo Châu