Professional Documents
Culture Documents
Lap-Trinh-Huong-Doi-Tuong - LTHDT - 02m - p2 - (Cuuduongthancong - Com)
Lap-Trinh-Huong-Doi-Tuong - LTHDT - 02m - p2 - (Cuuduongthancong - Com)
struct Fraction
tiếp cận dùng hàm thành phần
{
int numerator, denominator;
om
void reduce();
void print();
.c
void input();
ng
Fraction add(Fraction b);
co
Fraction sub(Fraction b);
an
Fraction mul(Fraction b);
Fraction div(Fraction b);
};
th
o ng
du
if (b == 0) return abs(a);
return gcd(b, a%b);
}
NNL – Khoa Toán Tin ĐHKHTN 57
CuuDuongThanCong.com https://fb.com/tailieudientucntt
void Fraction::reduce() Listing cont…
om
int u = gcd(numerator, denominator);
.c
numerator /= u;
ng
denominator /= u;
co
if (denominator < 0)
an
th
{ ng
numerator = -numerator;
o
du
denominator = -denominator;
u
cu
}
}
NNL – Khoa Toán Tin ĐHKHTN 58
CuuDuongThanCong.com https://fb.com/tailieudientucntt
void Fraction::print() Listing cont…
{
printf("%d", numerator);
om
if (numerator || denominator != 1)
.c
ng
printf("/%d", denominator);
co
}
an
void Fraction::input() th
o ng
{
du
scanf_s("%d%d", &numerator,
u
cu
&denominator);
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Fraction Fraction::add(Fraction b) Listing cont…
{
Fraction c;
c.numerator = numerator*b.denominator +
om
denominator*b.numerator;
.c
c.denominator = denominator*b.denominator;
c.reduce();
ng
return c;
co
}
an
Fraction Fraction::sub(Fraction b)
{
th
ng
Fraction c;
o
c.numerator = numerator*b.denominator -
du
denominator*b.numerator;
u
c.denominator = denominator*b.denominator;
cu
c.reduce();
return c;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Fraction Fraction::mul(Fraction b) Listing cont…
{
Fraction c;
om
c.numerator = numerator*b.numerator;
c.denominator = denominator*b.denominator;
.c
c.reduce();
ng
return c;
co
}
an
Fraction Fraction::div(Fraction b)
{
th
ng
Fraction c;
o
du
c.numerator = numerator*b.denominator;
c.denominator = denominator*b.numerator;
u
cu
c.reduce();
return c;
}
NNL – Khoa Toán Tin ĐHKHTN 61
CuuDuongThanCong.com https://fb.com/tailieudientucntt
int main() Listing cont…
{
Fraction a = { 1,4 }, b = { 1,2 }, c;
om
c = a.add(b);
c.print();
.c
puts("");
ng
c = a.sub(b);
co
c.print();
an
puts("");
c = a.mul(b);
c.print();
th
ng
puts("");
o
du
c = a.div(b);
c.print();
u
cu
puts("");
return 0;
}
NNL – Khoa Toán Tin ĐHKHTN 62
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cài đặt lớp - Ví dụ so sánh
om
• Nhận xét: (Nhắc lại)
.c
• Giải quyết được vấn đề.
ng
• Dữ liệu và các hàm xử lý dữ liệu được gom vào một
co
chỗ bên trong cấu trúc. Do đó dễ theo dõi quản lý, dễ
an
bảo trì nâng cấp.
th
• Các thao tác đều bớt đi một tham số so với cách tiếp
ng
cận cổ điển. Vì vậy việc lập trình gọn hơn. Tư tưởng thể
o
du
hiện ở đây là đối tượng đóng vai trò trọng tâm. Đối
u
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp
om
• Trong cách tiếp cận dùng struct và hàm thành
.c
phần, người sử dụng có toàn quyền truy xuất,
ng
thay đổi các thành phần dữ liệu của đối tượng
co
thuộc cấu trúc.
Stack s;
an
s.Init(10);
s.size = 100; // Nguy hiem
th
ng
for (int i = 0; i < 20; i++) s.Push(i);
o
du
Fraction a;
u
cu
a.numerator = 2;
a.denominator = 0; // Oh dear! 2/0!!!
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp
om
• Vì vậy, ta không có sự an toàn dữ liệu. Lớp là
.c
một phương tiện để khắc phục nhược điểm
ng
trên.
co
• Lớp có được bằng cách thay từ khoá struct
an
th
bằng từ khoá class (C++, Java, C#).
ng
• Trong lớp mọi thành phần mặc nhiên đều là
o
du
liệu.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Từ khoá class thay cho struct
class Stack
{
om
Item *st, *top;
.c
int size;
ng
void init(int sz){ top = st = new
co
Item[size = sz];}
an
void cleanUp(){ delete[] st; }
th
bool empty() { return top <= st; }
o ng
bool full() { return top - st >= size; }
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp
om
• Mọi cố gắng truy xuất các thành phần của lớp
.c
sẽ bị báo lỗi biên dịch.
ng
co
s.size = 100; // Bao sai
an
a.denominator = 0; // Bao sai
th
• Nghĩa là lỗi luận lý được trình biên dịch hỗ trợ
o ng
phát hiện, giúp giảm rất nhiều bug khó tìm.
du
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất
om
• Tuy nhiên lớp như trên trở thành vô dụng vì các hàm
.c
thành phần cũng trở thành riêng tư và không thể được.
Stack s;
ng
s.init(8);
co
// Bao sai
s.push(14); // Bao sai
an
Fraction a;
a.setNumerator(2); th
ng
// Bao sai
o
a.setDenominator(14); // Bao sai
du
• Thuộc tính truy xuất của một thành phần nào của lớp
là phần chương trình có thể nhìn thấy, truy xuất thành
phần đó.
NNL – Khoa Toán Tin ĐHKHTN 68
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất
om
• Thuộc tính private: Chỉ có các phương thức
.c
của lớp được phép truy xuất.
ng
• Thuộc tính public: Có thể được truy xuất từ
co
bất cứ nơi nào trong chương trình nguồn từ
an
th
sau khai báo lớp. ng
• Phần public tạo nên phần giao diện của lớp.
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất
om
• Trong C++, thuộc tính mặc nhiên của lớp
.c
private, thuộc tính của struct là public.
ng
co
• Ta có thể thay đổi thuộc tính truy xuất bằng
an
nhãn private hoặc public. Sự thay đổi có tác
dụng từ sau nhãn. th
o ng
du
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất: Ví dụ
class Stack
{
Item *st, *top; Các thành phần private không
om
được truy xuất từ bên ngoài
int size;
.c
public:
ng
void Init(int sz) { st = top = new
co
Item[size = sz]; }
an
void CleanUp() { if (st) delete[] st; }
th
bool Full()const { return (top - st >=
ng
size); }
o
bool Empty() const { return (top <= st); }
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất: Ví dụ
class Fraction
{
Các thành phần private
int numerator, denominator;
om
không được truy xuất
void reduce(); từ bên ngoài
.c
public:
ng
void print();
co
void input();
an
Fraction add(Fraction b);
Fraction sub(Fraction b);
th
ng
Fraction mul(Fraction b);
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất
om
• Các thành phần private không thể được truy xuất
.c
từ bên ngoài nhưng các thao tác public thì được.
ng
Stack s;
co
s.size = 100; // Error
an
s.init(8); // Ok
th
s.push(14); ng // Ok
Fraction a;
o
du
a.denominator = 0; // Error
u
a.setNumerator(2); // Ok
cu
a.setDenominator(14); // Ok
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Thuộc tính truy xuất
om
• Phạm vi truy xuất được sử dụng đúng sẽ cho
.c
phép ta kết luận: Nhìn vào lớp thấy được mọi
ng
thao tác trên lớp.
co
an
• Người dùng bình thường có thể khai thác hết
th
các chức năng của lớp thông qua phần giao
o ng
diện (public) của lớp.
du
• Người dùng cao cấp có thể thay đổi chi tiết cài
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cài đặt lớp trong Objective C
om
• Cú pháp cài đặt lớp trong Objective C khác với
.c
C++, gần giống với Smalltalk.
ng
• Lớp trong Objective C có hai phần tách biệt,
co
phần giao diện (interface) và phần cài đặt
an
th
(implementation). ng
• Trong Objective C, thuộc tính dữ liệu định
o
du
public.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cài đặt lớp trong Objective C
om
@interface ClassName: ParentClassName
.c
propertyDeclarations;
ng
methodDeclarations;
co
@end
an
th
@implementation ClassName ng
{
o
memberDeclarations;
du
}
u
cu
methodDefinitions;
@end
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
// Fraction.h
#import <Foundation/Foundation.h>
om
@interface Fraction : NSObject
.c
+(int)gcd : (int)a and : (int)b;
ng
-(void)setNumerator: (int)n;
co
-(void)setDenominator: (int)d;
an
-(void)set: (int)n over : (int)d;
-(void)print;
th
ng
-(Fraction *)add: (Fraction *)b;
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
// Fraction.m
#import "Fraction.h"
om
.c
@implementation Fraction
ng
{
co
int numerator, denominator;
an
}
th
ng
+(int)gcd: (int)a and : (int)b {
o
du
if (b == 0)
return a;
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
-(void)setNumerator: (int)n {
numerator = n;
}
om
.c
-(void)setDenominator: (int)d {
denominator = d;
ng
}
co
an
-(void)set: (int)n over: (int)d {
th
int u = [Fraction gcd : n and : d];
numerator = n / u;
ng
denominator = d / u;
o
du
if (denominator < 0) {
numerator = -numerator;
u
cu
denominator = -denominator;
}
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
-(int)numerator {
return numerator;
}
om
.c
-(int)denominator {
ng
return denominator;
co
}
an
-(void)print {
th
ng
if (denominator)
o
du
else
cu
NSLog(@"%i", numerator);
}
NNL – Khoa Toán Tin ĐHKHTN 80
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
-(Fraction *)add: (Fraction *)b {
Fraction *c = [Fraction alloc];
om
c = [c init];
[c set: numerator * b.denominator + denominator *
.c
b.numerator over: denominator * b.denominator];
ng
return c;
co
}
an
-(Fraction *)sub: (Fraction *)b {
Fraction *c = [Fraction alloc];
th
ng
c = [c init];
o
du
return c;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Lớp Phân Số
-(Fraction *)mul: (Fraction *)b {
Fraction *c = [[Fraction alloc] init];
om
[c set: numerator * b.numerator over:
denominator * b.denominator];
.c
return c;
ng
}
co
an
-(Fraction *)div: (Fraction *)b {
th
Fraction *c = [[Fraction alloc] init];
ng
[c set: numerator * b.denominator over:
o
denominator * b.numerator];
du
return c;
u
cu
@end
NNL – Khoa Toán Tin ĐHKHTN 82
CuuDuongThanCong.com https://fb.com/tailieudientucntt
// main.m
Lớp Phân Số
#import <Foundation/Foundation.h>
#import "Fraction.h"
om
int main(int argc, const char * argv[]) {
@autoreleasepool {
.c
Fraction *a = [Fraction alloc];
ng
a = [a init];
[a set: 1 over: 3];
co
Fraction *b = [Fraction alloc];
an
[b set: 5 over: 6];
th
Fraction *c = [a add: b];
[c print];
ng
[[a sub: b] print];
o
[[a mul: b] print];
du
}
cu
return 0;
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
setter và getter
om
• Thiết kế lớp chuẩn thì các thành phần dữ liệu
.c
sẽ có thuộc tính truy xuất là private nên không
ng
thể truy xuất trực tiếp.
co
an
• Để có thể thao tác trên trên các dữ liệu ta
th
dùng các phương thức đưa vào và lấy ra, gọi là
o ng
setter và getter.
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
class Fraction
{
int numerator, denominator;
om
void reduce();
public:
.c
void print();
ng
void input();
co
Fraction add(Fraction b);
Setters và Getters
an
Fraction sub(Fraction b);
Fraction mul(Fraction b);
Fraction div(Fraction b);
th
ng
void setNumerator(int n) { numerator = n; }
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Setters & Getters
om
.c
+(int)gcd : (int)a and : (int)b;
ng
-(void)setNumerator: (int)n;
co
-(void)setDenominator: (int)d; Setters
an
-(void)set: (int)n over : (int)d;
th
-(void)print; ng
-(Fraction *)add: (Fraction *)b;
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
@implementation Fraction
Setters & Getters
//...
-(void)setNumerator: (int)n { Setters
numerator = n;
om
}
.c
-(void)setDenominator : (int)d {
ng
denominator = d;
}
co
an
-(void)set: (int)n over : (int)d {
th
int u = [Fraction gcd : n and : d];
numerator = n / u;
ng
denominator = d / u;
o
if (denominator < 0) {
du
numerator = -numerator;
u
denominator = -denominator;
cu
}
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
@implementation Fraction
Setters & Getters
{
int numerator, denominator;
}
om
-(void)setNumerator: (int)n {
numerator = n;
.c
}
Setters
ng
-(void)setDenominator : (int)d {
co
denominator = d;
}
an
-(void)set: (int)n over : (int)d {
th
int u = [Fraction gcd : n and : d];ng
numerator = n / u;
denominator = d / u;
o
if (denominator < 0) {
du
numerator = -numerator;
denominator = -denominator;
u
cu
}
}
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Setters & Getters
//....
-(int)numerator {
om
return numerator;
.c
}
ng
Getters
co
-(int)denominator {
an
return denominator;
}
th
o ng
du
//...
u
cu
@end
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Tự động phát sinh setters & getters trong
Objective C
om
• Objective C có cơ chế cho phép phát sinh các
.c
phương thức setter(s) và getter(s) một cách tự
ng
động.
co
an
• Ta dùng từ khoá @property trong phần giao
th
diện và từ khoá @synthesize trong phần cài
o ng
đặt.
du
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
setters & getters
@interface Fraction : NSObject
@property int numerator, denominator;
om
Tự động phát
+(int)gcd: (int)a and : (int)b; sinh setters
.c
// -(void) setNumerator: (int) n;
ng
No need
// -(void) setDenominator: (int) d;
co
-(void)set: (int)n over : (int)d;
an
th
-(void)print; ng
-(Fraction *)add: (Fraction *)b;
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
@implementation Fraction
setters & getters
@synthesize numerator,Khởi động và dọn
denominator; dẹp
/* Đồng bộ với
{ @property
om
int numerator, denominator;
}
.c
-(void) setNumerator: (int) n {
ng
numerator = n;
}
co
an
-(void) setDenominator: (int) d {
th
denominator = d;
} No need
ng
-(int) numerator {
o
return numerator;
du
}
u
cu
-(int) denominator {
return denominator;
} */
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Khởi động và dọn dẹp
om
Để đối tượng sẵn sàng ở trạng thái hoạt động, ta
.c
cần bảo đảm:
ng
co
1. Đối tượng được khởi động.
an
2. Đối tượng không bị khởi động dư.
th
3. Tài nguyên cấp cho đối tượng được giải phóng.
o ng
4. Tài nguyên này không bị giải phóng dư.
du
u
dẹp.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Khởi động và dọn dẹp
om
• Ta có thể khởi động và dọn dẹp đối tượng một
.c
cách tự động nhờ phương thức thiết lập và
ng
huỷ bỏ
co
an
• Phương thức thiết lập và huỷ bỏ được xây
th
dựng nhằm mục đích khắc phục lỗi quên khởi
o ng
động đối tượng hoặc khởi động dư. Việc quên
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Khởi động và dọn dẹp
om
• Phương thức thiết lập là hàm thành phần đặc
.c
biệt được tự động gọi đến mỗi khi một đối
ng
tượng thuộc lớp được tạo ra. Người ta thường
co
lợi dụng đặc tính trên để khởi động đối tượng.
an
th
• Trong C++, phương thức thiết lập có tên trùng
ng
với tên lớp để phân biệt nó với các hàm thành
o
du
phần khác.
u
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Khởi động và dọn dẹp
om
• Phương thức huỷ bỏ là hàm thành phần đặc biệt
.c
được tự động gọi đến mỗi khi một đối tượng bị
ng
huỷ đi. Người ta thường lợi dụng đặc tính trên để
co
dọn dẹp đối tượng.
an
• Trong C++, Phương thức huỷ bỏ bắt đầu bằng dấu
th
ngã (~) theo sau bởi tên lớp để phân biệt nó với
o ng
các hàm thành phần khác.
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
class Stack
{
Item *st, *top;
om
int size;
void Init(int sz){
.c
top = st = new Item[size = sz]; }
ng
void CleanUp(){ delete[] st; }
co
public:
an
Tự động khởi động
Stack(int sz = 20) { Init(sz); } nếu quên khởi động
~Stack() { CleanUp(); }
th
ng
bool Empty() { return top <= st; }
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt
void XuatHe16(long n)
{
om
static char hTab[] = "0123456789ABCDEF";
.c
Stack s(8);
ng
int x;
co
do {
an
Qui trình sử
s.Push(n % 16);
th
dụng 1 bước
ng
n /= 16;
o
} while (n);
du
while (s.Pop(&x))
u
cu
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Sử dụng PT Thiết Lập & Huỷ bỏ
om
• Với phương thức huỷ bỏ ta có thể “dạy” trình
.c
biên dịch:
ng
1. Báo lỗi nếu người sử dụng quên khởi động,
co
hoặc
an
2. Khởi động tự động nếu người sử dụng quên
th
khởi động. ng
• Ta cũng có thể bảo đảm đối tượng không bị khởi
o
du
động dư.
u
động.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
class Stack
{
Item *st, *top;
om
int size;
void Init(int sz){
.c
top = st = new Item[size = sz]; }
ng
void CleanUp(){ delete[] st; }
co
public:
an
Báo sai nếu quên
Stack(int sz) { Init(sz); }
th
khởi động
~Stack() { CleanUp(); }
ng
bool Empty() { return top <= st; }
o
du
CuuDuongThanCong.com https://fb.com/tailieudientucntt