• Một lớp là một thiết kế blueprint hay mẫu prototype cho các đối tượng cùng kiểu – Ví dụ: lớp XeDap là một thiết kế chung cho nhiều đối tượng xe đạp được tạo ra • Một đối tượng là một
Trang 1Lập trình hướng đối tượng C+
+
Trang 2Tổng quan
Trang 3– Phương pháp viết chương trình chặt chẽ
– Rõ ràng, dễ thử nghiệm và sửa lỗi, dễ thay đổi
– Khi chương trình lớn hơn khó quản lý
– Dữ liệu đóng vai trò quan trọng
• Khi thêm 1 dữ liệu kiểu mới, phải thay đổi tất cả các công việc
và các hàm liên quan đến dữ liệu đó
• Không thể phân chia các phần cần che dấu thông tin trong chương trình.
Trang 4• Object oriented programming (OOP)
– Chia bài toán thành các nhóm nhỏ có liên hệ với nhau gọi là đối tượng.
Lập trình hướng đối tượng
Trang 5Đối Tượng (Object)
hướng đối tượng,
mọi thứ đều là đối
tượng
Viết một chương trình hướng đối tượng nghĩa là đang tạo một mô hình của một vài bộ phận trong thế giới thực
Trang 6Accounts
What is the salary of Jack?
What is the salary of Jack?
– Thông tin truyền giữa các phần khác nhau gọi là các
thông điệp giữa các đối tượng
– Các thông điệp này
có thể được chuyển thành lời gọi hàm trong chương trình.
Đối tượng (Object)
Trang 7thuộc tính thể hiện Một đối tượng cụ thể được gọi là một thể hiện
Trang 8Đối Tượng Thế Giới Thực
Trang 9Đối Tượng Phần Mềm
(Software Object)
Trang 10Lớp (Class)
• Nhóm các đối tượng có cùng thuộc tính, hành vi và mối quan hệ chung.
• Lớp là viết tắt của “lớp của đối tượng”.
• Một lớp là một thiết kế (blueprint) hay mẫu (prototype) cho các đối tượng cùng kiểu
– Ví dụ: lớp XeDap là một thiết kế chung cho nhiều đối tượng xe đạp được tạo ra
• Một đối tượng là một thể hiện cụ thể của một lớp.
– Ví dụ: mỗi đối tượng xe đạp là một thể hiện của lớp XeDap
• Mỗi thể hiện có thể có những thuộc tính thể hiện khác nhau
– Ví dụ: một cây mai có hoa 6 cánh, trong khi một cây khác có hoa đến 12 cánh.
Trang 11Số cạnh Màu viền Màu nền
Phương thức (methode):
Vẽ Xóa
Di chuyển
Đối tượng đa giác
Trang 12Thuộc Tính Lớp
& Phương Thức Lớp
• Thuộc tính lớp (class attribute): đặc trưng yêu cầu của đối tượng hoặc thực thể được biểu diễn trong một lớp
• Thuộc tính lớp được định nghĩa bên trong định nghĩa lớp
và được chia sẻ bởi tất cả các thể hiện của lớp.
– Ví dụ: Lớp đa giác gồm các thuộc tính như: số cạnh, màu viền, màu chữ…
• Phương thức lớp (class method): phương thức (hành động) yêu cầu của đối tượng hoặc thực thể được biểu diễn trong một lớp
• Tất cả các phương thức lớp ảnh hưởng đến toàn bộ lớp chứ không ảnh hưởng đến một lớp riêng rẽ nào.
– Ví dụ: Lớp đa giác gồm các phương thức như: vẽ, xóa, di chuyển…
Trang 13Thông Điệp
& Truyền Thông Điệp
một hoạt động Gồm có:
– Đối tượng nhận thông điệp
– Tên của phương thức thực hiện
– Các tham số mà phương thức cần
gọi một hay nhiều phương thức của đối tượng khác để yêu cầu thông tin.
Trang 14Đặc Điểm Quan Trọng
• Nhấn mạnh trên dữ liệu hơn là thủ tục
• Các chương trình được chia thành các đối tượng
• Dữ liệu được che giấu và không thể được truy xuất từ các hàm bên ngoài
• Các đối tượng có thể giao tiếp với nhau
thông qua các hàm
• Dữ liệu hay các hàm mới có thể được
thêm vào khi cần
• Theo tiếp cận từ dưới lên
Trang 15Thuận Lợi
• So với các tiếp cận cổ điển thì OOP có
những thuận lợi sau:
– OOP cung cấp một cấu trúc module rõ ràng
• Giao diện được định nghĩa tốt
• Những chi tiết cài đặt được ẩn – OOP giúp lập trình viên duy trì mã và sửa đổi mã tồn tại dễ dàng (các đối tượng được tạo ra với những khác nhau nhỏ so với những đối tượng tồn tại).
– OOP cung cấp một cơ chế tốt với các thư viện mã
mà các thành phần có thể được chọn và sửa đổi bởi lập trình viên
Trang 16Trừu Tượng Hóa
(Abstraction)
• Trừu tượng hóa
– Tiến trình xem xét các khía cạnh nào đó của bài toán.
– Biểu diễn những đặc tính, bỏ qua những chi tiết vụn vặt hoặc những giải thích
• Các kỹ thuật trừu tượng
– Đóng gói (encapsulation)
– Ẩn thông tin (information hiding)
– Thừa kế (inheritance)
– Đa hình (polymorphism)
Trang 17Tính đóng gói (Encapsulation)
– Cho phép truy cập đối tượng chỉ qua thông điệp của nó trong khi giữ kín các chi tiết riêng
tư gọi là ẩn thông tin.
– Là tiến trình che giấu việc thực thi chi tiết của một đối tượng
Trang 18Ẩn thông tin (Information Hiding)
• Đóng gói Thuộc tính được lưu trữ
hay phương thức được cài đặt như thế nào được che giấu đi từ các đối
tượng khác
Việc che giấu những chi tiết thiết kế và cài đặt từ những đối tượng khác
được gọi là ẩn thông tin
Trang 19Tính Thừa Kế (Inheritance)
• Hệ thống hướng đối tượng cho phép các lớp được định nghĩa kế thừa từ các lớp
khác
– Ví dụ, lớp xe đạp leo núi và xe đạp đua là
những lớp con (subclass) của lớp xe đạp
thuộc tính được định nghĩa trong một lớp
có thể được thừa kế hoặc được sử dụng lại bởi lớp khác
Trang 20Tính Đa Hình (Polymorphism)
Vẽ
Trang 21Lớp
Trang 22Khái niệm lớp
• Lớp: khái niệm trung tâm của OOP
• Định nghĩa: Lớp là nhóm của những đối tượng (objects) có cùng chung thuộc tính (properties) và có những mối quan hệ
chung
• Đối tượng: thể hiện một thực thể trong thế giới thực.
Trang 23Khái niệm lớp
TÊN LỚP
Dữ liệu thành viên
Hàm thành viên
class TÊNLỚP TÊNLỚP
[ : < Quyền truy xuất > LỚPCHA ] LỚPCHA
{ < Quyền truy xuất > :
Trang 24Lớp đơn giản
• Ví dụ:
class Point Point {
int xVal, yVal;
public:
void SetPt (int, int);
void OffsetPt (int, int);
xVal += x;
yVal += y;
}
void main() { Point pt;
pt.SetPt(10,20);
Gọi hàm trên đối tượng
Tạo ra đối tượng thuộc lớp Point
Trang 25Cơ bản về lớp
• Lớp gồm các thành viên:
– Dữ liệu thành viên (Member Data):
• Một đặc trưng của đối tượng
• Có thể là kiểu đã được định nghĩa hoặc tự định nghĩa
• Dữ liệu thành viên của lớp không thể có kiểu của lớp đó, nhưng có thể là con trỏ kiểu lớp đó.
– Hàm thành viên (Member Function) hay phương thức (Method)
• Một hoạt động, hành vi của đối tượng
• Đối tượng là “hộp đen” nhận và gửi thông điệp (message)
Trang 26Cơ bản về lớp
• Đối tượng của lớp
– Đối tượng là một thể hiện cụ thể của một lớp
– Khai báo sau định nghĩa lớp
• Khai báo đối tượng hoặc mảng, con trỏ, tham chiếu đến đối tượng
Trang 27Cơ bản về lớp
Trang 28• Dữ liệu thành viên:
– Nên được khai báo với từ khoá private.
– Không được khởi tạo giá trị của dữ liệu thành phần trong định nghĩa lớp.
class Employee // khai báo tên lớp
{
private: // từ khóa cho biết không thể truy nhập từ ngoài lớp
unsigned int EmpID =1; // sai
Trang 29Kiểutrảvề Tênlớp::Tênhàmthànhviên( ) { …
}
– Không phụ thuộc vào hàm public hay private
• Các hàm thành viên định nghĩa bên trong lớp
– Không cần toán tử :: và tên lớp
– Trình biên dịch sẽ cố thực hiện inline
• Ở ngoài lớp, ta chỉ định inline với từ khoá inline
Trang 30Hàm thành viên nội tuyến
– Cải thiện tốc độ thực thi
– Tốn bộ nhớ (dành cho mã lệnh) khi thực thi.
class Point Point {
int xVal, yVal;
public:
void SetPt (int, int);
void OffsetPt (int, int);
class Point Point {
int xVal, yVal;
Trang 31– public
• Bất kỳ hàm nào trong chương trình xử lý đối tượng đó cũng
có thể truy cập được
– protected
• Sẽ được học sau Hiện tại giống với private
• Dữ liệu mặc định là private để đảm bảo giấu kín
• Hàm mặc định là public để có thể dùng mọi nơi
Trang 32Các hàm truy cập và các hàm hữu dụng
– Hỗ trợ hoạt động của các hàm thành phần public
– Không dành cho người dùng trực tiếp
Trang 33Sự đóng gói (encapsulation)
• Sự truy xuất đến đối tượng thông qua các thông điệp
(message) mà vẫn giữ các thuộc tính private dưới
dạng thông tin ẩn
• Làm cho việc truy xuất đến dữ liệu của các lớp từ bên ngoài lớp bị giới hạn, trở nên không cần thiết hoặc
không thể thực hiện được
• Người dùng không cần quan tâm đến cấu trúc và hoạt động bên trong của lớp, chỉ quan tâm giải quyết vấn đề lớn hơn
• Mục tiêu:
– tạo bức tường không thể thâm nhập được để bảo vệ, tránh những hư hại vô tình hoặc cố ý do những lỗi chúng ta mắc phải – Dễ dàng cô lập lỗi ⇒ dễ dàng tìm kiếm và sữa chữa
Trang 34Hàm tạo
• Dùng để định nghĩa và khởi tạo định nghĩa khởi tạo đối tượng cùng 1 lúc.
• Có tên trùng với tên lớp, không có kiểu trả về.
• Không gọi trực tiếp, sẽ được tự động gọi khi khởi tạo đt.
• Gán giá trị, cấp vùng nhớ cho các dữ liệu thành viên. dữ liệu thành viên
class Point Point {
int xVal, yVal;
Trang 35Hàm tạo
class Point Point {
int xVal, yVal;
Point (float len, float angle) {
xVal = (int) (len * cos(angle));
yVal = (int) (len * sin(angle));
Set(const int size) {
elems = new int[size];
maxCard = size;
card = 0;
} ………
};
void main() { Set s1(100);
Set s2(20);
Set s3(1000); …}
Mềm dẻo hơn
Không cần phải nhớ gọi hàm
EmptySet()
khi khởi tạo
Trang 36Hàm tạo
• Hàm tạo sao chép khởi tạo đối tượng dựa trên một đối tượng khác thuộc cùng lớp.
• Mỗi lớp có một hàm tạo sao chép mặc định – hàm này
có một tham số là đối tượng cùng lớp.
• Ta có thể định nghĩa lại hàm tạo sao chép.
Trang 37• Thu hồi vùng nhớ cho các dữ liệu thành viên là dữ liệu thành viên con trỏ. con trỏ
class Set Set {
Set(const int size) { …… }
~Set() { delete[] elems; }
…
};
Set TestFunct1(Set s1) { Set *s = new Set(50);
return *s;
}
void main() { Set s1(40), s2(50);
s2 = TestFunct1(s1);
}
Tổng cộng
có bao nhiêu lần
hàm hủy được gọi ?
4
Trang 38Hàm tạo và hàm hủy mặc định
• Hàm tạo mặc định:
– Thường tạo hàm tạo và hàm hủy khi lớp có thành phần cấp phát động
– Nếu lớp không có hàm tạo thì trình biên dịch
sẽ cung cấp 1 hàm tạo mặc định không đối Hàm này chỉ cấp phát bộ nhớ, không khởi tạo
Trang 39Đối số mặc định
class Point Point {
int xVal, yVal;
Point (int x = 0, int y = 0);
Point (float x=0, float y=0);
Trang 40Đối số thành viên ẩn
• Con trỏ *this: Con trỏ *this
– Là 1 thành viên ẩn, có thuộc tính là private – Trỏ tới chính bản thân đối tượng.
void Point ::OffsetPt (int x, int y) {
• Có những trường hợp sử dụng *this là dư thừa (Ví dụ trên)
• Tuy nhiên, có những trường hợp phải sử dụng con trỏ *this *this
Trang 41Sử dụng con trỏ this
• Các lời gọi hàm thành phần liên tiếp
– Nhiều hàm được gọi trong cùng 1 lệnh
– Hàm trả về 1 tham chiếu đến cùng đối tượng đó
{ return *this; }
– Các hàm khác hoạt động trên con trỏ này
– Hàm không trả về tham chiếu phải được gọi sau cùng
Trang 425 Time( int = 0, int = 0, int = 0 ); // default constructor
6 Time &setTime(int,int,int); // set hour,minute,second
7 Time &setHour( int ); // set hour
8 Time &setMinute( int ); // set minute
9 Time &setSecond( int ); // set second
10 int getHour() const; // return hour
11 int getMinute() const; // return minute
12 int getSecond() const; // return second
13 void printUniversal() const; // print universal time
14 void printStandard() const; // print standard time
15 }; // end class Time
Trang 4316 Time::Time( int hr, int min, int sec )
17 { setTime( hr, min, sec );
18 } // end Time constructor
19 Time &Time::setTime( int h, int m, int s )
20 { setHour( h ); setMinute( m ); setSecond( s );
21 return *this; // enables cascading
22 } // end function setTime
23 Time &Time::setHour( int h )
24 { hour = ( h >= 0 && h < 24 ) ? h : 0;
25 return *this; // enables cascading
26 } // end function setHour
27 Time &Time::setMinute( int m )
28 { minute = ( m >= 0 && m < 60 ) ? m : 0;
29 return *this; // enables cascading
30 } // end function setMinute
Trang 4431 Time &Time::setSecond( int s )
32 { second = ( s >= 0 && s < 60 ) ? s : 0;
33 return *this; // enables cascading
34 } // end function setSecond
35 int Time::getHour() const
36 { return hour;
37 } // end function getHour
38 int Time::getMinute() const
39 { return minute;
40 } // end function getMinute
41 int Time::getSecond() const
42 { return second;
43 } // end function getSecond
44 void Time::printUniversal() const
45 { cout << hour << ":“ << minute << ":“ << second;
46 } // end function printUniversal
Trang 4547 void Time::printStandard() const
48 { cout << ((hour == 0 || hour == 12 ) ? 12 : hour % 12 )
54 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 );
55 cout << "Universal time: ";
Trang 46Làm thế nào
để thực hiện được việc truy
xuất đến thành viên
Private ?
Trang 47Hàm bạn (Friend)
IntSet là bạn ( bạn friend) của lớp friend RealSet.
class IntSet IntSet { public:
Thêm dòng khai báo
Friend cho hàm thành viên
SetToReal
Trang 48Hàm bạn (Friend)
• Cách 2:
– Chuyển hàm SetToReal ra ngoài ( độc lập) độc lập
– Khai báo hàm đó là bạn của cả 2 lớp
class IntSet IntSet {
rSet.card = iSet.card;
for (int i = 0; i < iSet.card; ++i) rSet.elems[i] =
(float) iSet.elems[i];}
Hàm độc lập
là bạn(friend) của cả 2 lớp
Trang 49class IntSet IntSet { ……… }
class RealSet RealSet { // ………
friend class IntSet;
};
Các hàm thành viên của lớp A đều là bạn của lớp B
Trang 51temp.r = r+ s2.r ; temp.i = i+ s2.i ; return temp;
} };
Cách dùng:
SP s, s1, s2;
s=s1.cong(s2);
class SP { double r;
} };
Cách dùng:
SP s, s1, s2;
s=cong(s1,s2);
Trang 521 // Use a friend function.
2 #include <iostream>
3 const int IDLE=0;
4 const int INUSE=1;
5 class C2; // note : forward declaration
6 class C1
7 { int status; // IDLE if off, INUSE if on screen
9 public:
10 void set_status(int state);
11 friend int idle(C1 a, C2 b);
17 void set_status(int state);
18 friend int idle(C1 a, C2 b);
19 };
Trang 5320.void C1::set_status(int state) { status = state; }
21.void C2::set_status(int state) { status = state; }
22.// idle( ) is a friend of C1 and C2.
30 if(idle(x, y)) cout << "Screen Can Be Used.\n";
31 else cout << "Pop-up In Use.\n";
32 x.set_status(INUSE);
33 if(idle(x, y)) cout << "Screen Can Be Used.\n";
34 else cout << "Pop-up In Use.\n";
35 }
Trang 54• Chú ý: Hàm bạn không có con trỏ this
– Các thành phần của 2 lớp (hoặc nhiều hơn)
có liên quan đến phần khác của chương trình
• Ví dụ: Hàm print cần xuất thông tin của 2 đối tượng thuộc 2 lớp khác nhau
Hàm bạn và lớp bạn
Trang 55– Khi 1 hàm là hàm bạn của 1 lớp, nó có thể truy cập
dữ liệu của lớp đó Người lập trình cần biết mã nguồn
⇒ hạn chế thay đổi lớp đó đến mức có thể.
– Không lạm dụng friend
Trang 56• Gọi hàm tạo mặc định cho đối tượng
• Trả về con trỏ kiểu Time
• Cung cấp bộ khởi tạo
double *ptr = new double( 3.14159 );
Time *timePtr = new Time( 12, 0, 0 );
• Cấp phát mảng
int *gradesArray = new int[ 10 ];
Trang 57Toán tử delete
• Giải phóng vùng nhớ được cấp phát động cho đối tượng
– Gọi hàm hủy cho đối tượng
– Giải phóng vùng nhớ dành cho đối tượng
• Vùng nhớ đó có thể dùng để cấp phát lại cho các đối tượng khác
– Giải phóng mảng
• delete [] gradesArray;
• Giải phóng mảng gradesArray đang trỏ tới
• Nếu là mảng đối tượng
• Đầu tiên gọi hàm hủy cho từng đối tượng
• Sau đó giải phóng vùng nhớ
• Ví dụ
delete timePtr;
Trang 58• Cần thiết trong một số trường hợp:
– Cách gọi hàm trong thừa kế.
– Tên thành viên bị che bởi biến cục bộ.
Ví dụ: Point(int xVal, int yVal) {
Point::xVal = xVal;
Point::yVal = yVal;
}
Trang 59Danh sách khởi tạo thành viên
• Tương đương việc gán giá trị dữ liệu thành viên.
class Image Image { public:
Image(const int w, const int h);
class Point Point {
int xVal, yVal;
Trang 60const int width; const int
const int height; const int
class Image Image {
const int width = 256;
const int height = 168;