6: Hàm - Class

iThanh
2/7/2013 14:45Phản hồi: 43
6: Hàm - Class
Bài 6: Hàm - Class
Chào các bạn.
Phần này rất quan trọng, sẽ ứng dụng rất nhiều trong quá trình bạn viết ứng dụng sau này.
Bạn cần phải thực hành nhiều hơn kể từ phần này trở đi.
Chúng ta không bàn đến những phương thức xây dựng hàm cũ, ở đây mình dùng Xcode mới nhất, nên cách tạo hàm cũ, mình không giới thiệu. Bạn nào muốn tìm hiểu thì có thể tự tìm hiểu với bác zai của mình: Google.

1. Hàm, cách khởi tạo, cách sử dụng:
Hàm trong Objective-C cũng tương tự như hàm ở các ngôn ngữ khác về tác dụng.
Hàm được dùng để thực hiện một loạt các công việc định sẵn mà các công việc này được dùng nhiều lần trong toàn bộ chương trình.
Ví dụ: Ở một lớp học, mỗi lần họp phụ huynh là cần phải chuẩn bị nhiều thứ: giấy mời, khăn trải bàn, bình hoa, chỗ để xe, đón tiếp phụ huynh học sinh, ... Nhưng một năm, họp phụ huynh rất nhiều lần, cho nên việc chuẩn bị cũng được thực hiện nhiều lần. Để dễ dàng, giáo viên chủ nhiệm lập ra 1 tổ, phân công công việc cụ thể cho từng tổ viên, cứ đúng đến lúc chuẩn bị họp phụ huynh là tổ đó có trách nhiệm chuẩn bị chu đáo cho buổi họp. Tổ đó cũng tương tự như 1 hàm.

Hoặc ví dụ: Một ứng dụng chơi đánh cờ. Cứ mỗi con cờ được đi, ứng dụng tự động phát 1 đoạn nhạc. Mà trong 1 ván cờ có rất nhiều nước cờ được đi, cho nên việc phát nhạc được thực hiện nhiều lần, lúc đó, người ta viết 1 Hàm có nhiệm vụ phát nhạc. Và cứ đến khi thấy có con bài nào được đánh ra thì ngay lập tức gọi Hàm phát nhạc.

Cách tạo Hàm (Hàm thực thi):
Hàm thực thi là Hàm chỉ thực hiện các lệnh bên trong hàm đó. Đây là dạng cơ bản nhất của Hàm trong Objective-C.

Code:
-(void)HamGhiChu {
    // Các lệnh được đặt trong này
    NSLog(@"Ghi ghi chú ra cửa sổ Logs");
}

// Dấu trừ là bắt buộc. Nó chỉ cho trình biên dịch biết rằng đây là hàm thực thi.
// void nghĩa là Hàm chỉ thực thi và không trả về giá trị nào cả
// HamGhiChu nghĩa là tên của Hàm. Quy tắc đặt tên Hàm cũng tương tự với Quy tắc đặt tên biến.


Cách tạo Hàm thực thi có tham số:
Code:
-(void)HamGhiChu😔NSString *)CauGhiChu {
    NSLog(@"Ghi chú: %@", CauGhiChu);
}

// Tương tự như Hàm thực thi không có tham số.
// Dấu Hai chấm ( : ) là bắt buộc.
// Tham số ở đây là một chuỗi, nghĩa là khi gọi và chạy Hàm này, bạn phải truyền vào Hàm 1 chuỗi nào đó.

Quảng cáo


Cách tạo Hàm thực thi có tham số và trả về kết quả:
Code:
-(NSString *)KetQuaXepLoai:(int)DiemTongKet {
    if (DiemTongKet > 8) {
        return @"Được học sinh Giỏi!";
    } else {
        return @"Không được học sinh Giỏi.";
    }
}
// Hàm này trả về mỗi chuỗi hoặc là @"Được học sinh Gii." hoặc là @"Không được học sinh Gii!" dựa vào việc kiểm tra tham số đã truyền vào Hàm.
// return là bắt buộc đối với Hàm này.
// Khi truyền tham số vào hàm, các tham số có kiểu là Đối tượng (thông thường có NS ở trước tên) thì phải có dấu sa8 (*)


Cách gọi hàm:
Đối với các Hàm chỉ thực thi mà không có tham số, ta chỉ cần gọi đơn giản như bên dưới:
[selfHamGhiChu];
Còn đối với các Hàm thực thi có tham số, dĩ nhiên bạn phải truyền tham số vào các Hàm. Đối với các Hàm loại này, bạn chỉ cần gõ self cách ra 1 cái và gõ tên hàm, các gọi ý sẽ giúp bạn tìm được hàm bạn muốn gọi, sau đó chỉ việc ENTER là chèn vào.
[selfKetQuaXepLoai:2];

Quảng cáo



2. Class (Lớp - Đối tượng):
Bạn nháy phải chuổt vào Project bên tay trái, chọn "New File"
Trong cửa sổ hiện ra, chọn Cocoa -> Objective-C Class -> Next
Đặt tên Class là Class_Bai6. Chọn Subclass of là NSObject -> Next -> Create.
Vậy là bạn đã tạo xong 1 class có tên là Class_Bai6.


Lúc này, Xcode sẽ tạo ra 2 file, Class_Bai6.h và Class_Bai6.m
- Class_Bai6.h là file Header. Dùng để khai báo biến, khai báo các Hàm tuỳ chọn.
- Class_Bai6.m là file Main. Dùng để triển khai nội dung Các Hàm.
Bài toán ví dụ: Viết chương trình nhập vào 1 số nguyên lớn hơn 0 và xem số đó có chia hết cho 2 hay không.
Bấm vào File Class_Bai6.h, khai báo một Hàm dùng để kiểm tra.

Code:
@interface Class_Bai6 : NSObject
 
- (BOOL)KiemTraChiaHetCho2:(int)SoNhapVao;
// Hàm này trả về kiểu boolen (đúng - sai)
// Tên Hàm: KiemTraChiHetCho2 (Kiểm tra chia hết cho 2)
// Tham số có kiểu là int (integer - số nguyên), có tên biến là SoNhapVao
 
end

Bấm vào File Class_Bai6.m để triển khai nội dung Hàm.
Triển khai nội dung Hàm kiểm tra chia hết cho 2 như sau:
Code:
- (BOOL)KiemTraChiaHetCho2:(int)SoNhapVao {
    if (SoNhapVao != 0) { // Kiểm tra số nhập vào có khác không hay không.
    // Trường hợp số nhập vào khác 0
        if ((SoNhapVao % 2) == 0) { // Kiểm tra xem số nhập vào có chia hết cho 2 hay không
            return TRUE;
        } else {
            return FALSE;
        }
    } else {
    // Trường hợp số nhập vào là 0 (bằng 0)
        return FALSE;
    }
}


Bạn hãy thử bấm Run xem.
Lúc này Class của bạn vẫn chưa chạy vì nó chưa được triệu gọi.
Để triệu gọi Class vừa tạo, bạn bấm vào file main.m
Bên dưới dòng #import <Foundation/Foundation.h>
Bạn gõ vào #import "Class_Bai6.h", Đây là dòng lệnh nhập Class Class_Bai6 vào.
Trong Hàm main, viết đoạn code để cấp phát bộ nhớ cho Hàm được tạo bằng Class Class_Bai6 và tiến hành làm công việc giải bài toán ví dụ.

Code:
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class_Bai6 *KiemTra = [[Class_Bai6 alloc] init];
 
        // Kiểm tra xem 10 có chia hết cho 2 hay không
        [KiemTra KiemTraChiaHetCho2:10] ? NSLog(@"Chia hết cho 2.") : NSLog(@"Không chia hết cho 2.");
 
        // Kiểm tra xem 13 có chia hết cho 2 hay không
        int So = 13;
        [KiemTra KiemTraChiaHetCho2:So] ? NSLog(@"%i chia hết cho 2.", So) : NSLog(@"%i không chia hết cho 2.", So);
    }
    return 0;
}


Và bây giờ là chạy thử xem kết quả thế nào nhé.
Vậy là trên đây bạn đã hiểu về Hàm là như thế nào và Class là như thế nào. Hiểu sơ qua thôi, bây giờ làm bài tập giải mỏi nhé.

3. Bài tập:
Yêu cầu dùng Class và Hàm để giải các bài tập bên dưới.
Giải xong, bạn đăng các Hàm của bạn viết ra lên đây cho mọi người cùng tham khảo và góp ý nhé.

1. Viết ứng dụng xuất ra cửa sổ Log các số nguyên lớn hơn 0 chia hết cho 3 và nhỏ hơn số n. Với n là số bạn tự chọn.
2. Viết ứng dụng tính Tổng và Tích các số từ n đến m (n và m tự chọn sao cho n < m) và xuất ra cửa sổ Log.
3. Viết ứng dụng in ra cửa sổ Log 100 chữ cái bất kỳ (với chữ cái bất kỳ cho bạn tự chọn).
4. Viết ứng dụng giải phương trình bậc 1 với các tham số của phương trình do bạn tự chọn.
ax + b = 0
5. Viết ứng dụng giải phương trình bậc 2 với các tham số như sau: (ax^2 + bx + c = 0)
a = 5, b = -6, c = +1

Chúc các bạn vui.

Project mình đã nén lại và đính kèm cho các bạn tiện theo dõi.
Link: http://www.mediafire.com/folder/jjwb8z0gglzb3/Bài_6

Chuẩn bị tinh thần để sắp tới bắt tay vào làm Apps iOS, bạn nhé.
43 bình luận
Chia sẻ

Xu hướng

Nhiều bác xem mà ít bác nào like để ủng hộ tinh thần cho bác chủ quá.
Only87xx
ĐẠI BÀNG
11 năm
Rất ủng hộ và cám ơn tinh thần của bác iThanh, những bài viết này rất hay và có ý nghĩa với những người đang bập bõm muốn học lập trình iOS. 😃

Chỉ góp ý với bác 1 số điểm nhỏ sau thôi ah:

1. Bác nên đưa chuẩn code convention vào trong example của bác luôn. Dù là ví dụ cho người mới học,nhưng nếu ngay từ đầu đã làm quen luôn với code convention thì sẽ hình thành thói quen, rất tốt về sau. VD:

Code:
-(void)HamGhiChu {
    // Các lệnh được đặt trong này
    NSLog(@"Ghi ghi chú ra cửa sổ Logs");
}
thì viết luôn theo chuẩn:

Code:
-(void)hamGhiChu {
    // Các lệnh được đặt trong này, bắt đầu nên hàm
    NSLog(@"Ghi ghi chú ra cửa sổ Logs");
}
"Method names do not have a prefix, and should start with a lowercase letter; camel case is used again for multiple words" nguồn: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
Documentation Archive
developer.apple.com


2. Theo mình thì có thể giới thiệu luôn về Model - View - Controller, từ đó có thể tạo luôn giao diện UI, bởi ngay khi tạo project thì mặc định xCode đã tạo sẵn 1 viewController (nếu chọn template là single view) rồi từ đó mình code, hiển thị kết quả lên trên Simulator sẽ trực quan hơn là hiển thị giao diện log.

Đấy chỉ là những góp ý nhỏ nhỏ của mình thôi.
Mong bạn tiếp tục phát huy tinh thần chia sẻ! 😃
Only87xx
ĐẠI BÀNG
11 năm
"Chuẩn bị tinh thần để sắp tới bắt tay vào làm Apps iOS, bạn nhé."

Những bài này có lẽ đặt ở box lập trình cho di động (http://www.tinhte.vn/forums/lap-trinh-cho-di-dong.270/) thì chuẩn hơn bác ạ. 😁

Khác

Các nội dung khác
tinhte.vn
@Only87xx để cả 2 vẫn chuẩn bác à, vì ngôn ngữ dùng chung. Bác chủ vừa chỉ cái cơ bản rồi dần chỉ lập trình Mac, IOS
iThanh
ĐẠI BÀNG
11 năm
Cảm ơn các bạn.
Mình giới thiệu theo cách cơ bản nhất, để tất cả mọi người mới nhập môn đều tiếp thu được (trên terminal).

Điều này rất tiện cho các bạn test hàm. (Mình nghĩ như vậy)

Khi tiến hành lập trình iOS lúc đó sẽ biết thêm được ViewController, và có cơ sở từ những bài trên sẽ dễ dàng hơn.

Mong các bạn góp ý nhiệt tình.
Cảm ơn tất cả các bạn.
vi_tieu_bao
ĐẠI BÀNG
11 năm
ze
chờ bài của a.
😁 khi nào có bài tiếp theo nữa bác ui :D
vi_tieu_bao
ĐẠI BÀNG
11 năm
đang làm bài tập, đợi bài mới của iThanh ^^
vi_tieu_bao
ĐẠI BÀNG
11 năm
Code:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Class_Bai6 *KiemTra = [[Class_Bai6 alloc] init];

// Kiểm tra xem 10 có chia hết cho 2 hay không
[KiemTra KiemTraChiaHetCho2:10] ? NSLog(@"Chia hết cho 2.") : NSLog(@"Không chia hết cho 2.");

// Kiểm tra xem 13 có chia hết cho 2 hay không
int So = 13;
[KiemTra KiemTraChiaHetCho2:So] ? NSLog(@"%i chia hết cho 2.", So) : NSLog(@"%i không chia hết cho 2.", So);
}
return 0;

iThanh có thể nói rõ hơn về cái chỗ mình highlight chữ cam hông?
thanks
vi_tieu_bao
ĐẠI BÀNG
11 năm
Với mình có thêm 1 ý kiến nhỏ là từ bài này chắc khó hơn rùi nên iThanh có thể giải mẫu 1 bài trong 5 bài tập rùi còn 4 bài còn lại mọi người tự làm được hông?
Thanks.
vi_tieu_bao
ĐẠI BÀNG
11 năm
iThanh có thể sửa dùm bài 1 của mình ko? mình làm nó báo build thành công nhưng chỉ hiện kết quả là lldb.

File Main.m


#import <Foundation/Foundation.h>
#import "Class_bt61.h"


int main(int argc, constchar * argv[])
{

@autoreleasepool {

Class_bt61 *KiemTra = [[Class_bt61alloc] init];

int n = 1;
while (n <=30) {
n++;
if ([KiemTra KiemTraChiHetCho3:n]) {
NSLog(@"%i",n);
}
}


}
return 0;
}

File Class_bt61.h

#import <Foundation/Foundation.h>

@interface Class_bt61 : NSObject



- (BOOL)KiemTraChiHetCho3: (int) SoNhapVao;

end
File Class_bt61.m

#import "Class_bt61.h"

@implementation Class_bt61

-(BOOL)KiemTraChiHetCho3: (int)SoNhapVao {
if (SoNhapVao != 0){
if (SoNhapVao % 3 ==0) {
returnTRUE ;
} else {
returnFALSE;
}
} else{
returnFALSE;
}
}

end
iThanh
ĐẠI BÀNG
11 năm
Bạn thử kiểm tra lại xem cú pháp bạn ghi đã đúng chưa.
Rồi "returnTRUE" -> "return TRUE"
vi_tieu_bao
ĐẠI BÀNG
11 năm
@iThanh mình vẫn chưa hiểu lắm. iThanh có thể sửa trực tiếp dùm bài của mình để nó chạy được trên xcode ko?
thanks
iThanh
ĐẠI BÀNG
11 năm
@vi_tieu_bao Bạn phải viết đúng cú pháp.
return -- cách 1 cái -- rồi mới đến TRUE.
Mình chạy trên Xcode thì bình thường, nếu không chạy được, bạn có thể nhắn tin cho mình qua iMessage: ithanh@me.com
Mình sẽ teamview qua xem cho bạn.
vi_tieu_bao
ĐẠI BÀNG
11 năm
@iThanh tại copy zô cái nó bị vậy đó chứ lúc chạy vẫn cách ra mà. hix
vậy có ji tối nhờ bạn chỉnh lại nhé.

thanks
iThanh
ĐẠI BÀNG
11 năm
Class_Bai6 *KiemTra = [[Class_Bai6 alloc] init];

KiemTra: là tên biến. Có dấu sao vì nó được khai báo thông qua một lớp (class) hoặc một đối tượng cũng thế.

alloc, init: Cấp phát vùng nhớ và con trỏ cụ thể cho đối tượng KiemTra (biến này là một đối tượng, bạn xem lại các bài trước đã có nói).
vi_tieu_bao
ĐẠI BÀNG
11 năm
Bài 2:
file Class_bt62.h
Code:
#import <Foundation/Foundation.h>
 
@interface Class_bt62 : NSObject
 
-(void) TongTuSoMDenN : (int)m : (int)n;
 
-(void) TichTuSoADenB : (int)a : (int)b;
 
@ end
file Class_bt62.h
Code:
#import "Class_bt62.h"
 
@implementation Class_bt62
 
int Tong = 0;
 
 
-(void) TongTuSoMDenN😔int)m :(int)n {
    if (n > m){
        for (int x = m ; x < n ; x++) {
     
            Tong = Tong + x;
        }
    }
    NSLog(@"Tong tu so m den n la %i", Tong);
}
 
int Tich = 1;
 
-(void) TichTuSoADenB: (int)a :(int)b {
    if (b > a) {
        for (int y = a; y < b; y++) {
            Tich = Tich * y;
        }
    }
    NSLog(@"Tich tu so a den b la %i", Tich);
}
 
@ end 
file main.m

Code:
#import <Foundation/Foundation.h>
#import "Class_bt62.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
 
        Class_bt62 *TinhTong = [[Class_bt62 alloc] init];
 
        [TinhTong TongTuSoMDenN:2 :5];
 
        Class_bt62 *TinhTich = [[Class_bt62 alloc] init];
 
        [TinhTich TichTuSoADenB:2 :5];
 
            }
    return 0;
}
nhờ iThanh chấm bài với nhe
vi_tieu_bao
ĐẠI BÀNG
11 năm
hix cái chỗ end
end mà sao nó cứ chuyển thành vậy hoài ta hix
@vi_tieu_bao bác xài hackintosh hay mac
vi_tieu_bao
ĐẠI BÀNG
11 năm
@allstreet mình xài mac bạn ơi. sao zay? có liên quan tới vụ này hả?
vi_tieu_bao
ĐẠI BÀNG
11 năm
bài 3:

bài này làm hoài vẫn chưa ra, iThanh chỉ dùm với T_T

hehe đã nắm được bài này.

đã fix lại chạy ok rùi nhờ iThanh check lại dùm lần nữa nhe

file Class_bt63.h

Code:
#import <Foundation/Foundation.h>
 
@interface Class_bt63 : NSObject
 
-(void) In100LanChuCai: (NSString *) a ;
 
@ end 
file Class_bt63.m

Code:
#import "Class_bt63.h"
 
@implementation Class_bt63
 
-(void) In100LanChuCai: (NSString *) a {
    NSLog(@"In 100 lan chu cai %@", a);
    for (int x = 1; x <=100 ; x++) {
        NSLog(@"%@", a);
    }
}
@ end 
file main.m

Code:
#import <Foundation/Foundation.h>
#import "Class_bt63.h"
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
 
        NSString *h = @"h";
        Class_bt63 *InChuCai = [[Class_bt63 alloc] init];
 
        [InChuCai In100LanChuCai: h ];
 
    }
    return 0;
}
vi_tieu_bao
ĐẠI BÀNG
11 năm
bài 4:

file Class bt64.h
Code:
#import <Foundation/Foundation.h>
 
@interface Class_bt64 : NSObject
 
-(void) GiaiPhuongTrinhBacNhat: (int)a 😔int)b;
 
@ end
file Class bt64.m
Code:
#import "Class bt64.h"
 
@implementation Class_bt64
 
-(void) GiaiPhuongTrinhBacNhat:(int)a :(int)b  {
    if (a != 0) {
        int x;
        x = -b / a;
   
        NSLog(@"Dap an: X bang %i", x);
    }
}
 
@ end
main.m
Code:
#import <Foundation/Foundation.h>
#import "Class bt64.h"
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
       
        Class_bt64 *GiaiPhuongTrinh = [[Class_bt64 alloc] init];
       
        [GiaiPhuongTrinh GiaiPhuongTrinhBacNhat:4 :-8 ];
     
    }
    return 0;
}
@vi_tieu_bao VD nếu như a = 2 ; b = 5 thì phải khai báo ntn để ra kết quả là -2.5 vậy bạn?
Himura__
ĐẠI BÀNG
10 năm
@tuanhsu10 Muốn in ra kết quả -2.5 thì bác phải dùng biến kiểu float
iThanh
ĐẠI BÀNG
11 năm
Bạn vi_tieu_bao đã hiểu và áp dụng được Class rồi.

Tuy nhiên để tiện, thì khi tạo 1 hàm để tính toán như vậy, bạn nên cho nó trả về giá trị. Chứ đừng nên xuất ngay ra cửa sổ Log trong hàm.

Khi trả về giá trị, dĩ nhiên bạn sẽ tuỳ biến được giá trị đó sau khi nhận được. Bạn có thể gán cho biến, Log ra, so sánh với giá trị khác, ...

Như bên dưới:
Code:
-(int)TongTuSoMDenN😔int)m SoN:(int)n {
    if (n > m){
        for (int x = m ; x < n ; x++) {
            Tong = Tong + x;
        }
    }
    return Tong;
}
*** Hình như bạn vi_tieu_bao đang dùng Xcode cũ.
Bạn nên cập nhật Xcode mới nhất để phù hợp với những bài viết sau này (liên quan đến iOS và các foundation mới, APIs mới từ Apple Developer)
vi_tieu_bao
ĐẠI BÀNG
11 năm
@iThanh
mình đang dùng Xcode Version 4.6.2 (4H1003). không biết ver mới nhất giờ là bao nhiêu ta? có download offline về đc ko ha?
vi_tieu_bao
ĐẠI BÀNG
11 năm
@iThanh ok mình hỏi 1 cái nữa là trong bài mình làm so với bài iThanh mới post thì có 2 chỗ khác nhau này thì iThanh có thể nói rõ hơn sự khác hay giống nhau của 2 cái này hông?

-(void) TongTuSoMDenN: (int)m : (int)n
-(int)TongTuSoMDenN: (int)m SoN: (int)n

Thanks
iThanh
ĐẠI BÀNG
11 năm
Nếu bạn vi_tieu_bao đã hiểu được như vậy là rất tốt, tuy nhiên bạn cần phải cân nhắc việc sử dụng Class, Object vào các bài toán sao cho hợp lý.

Ví dụ, một bài đơn giản, và công việc đó không cần thiết phải lặp đi lặp lại hoặc nó không quá khó để ây dựng hàm, cũng không quá dài, ... lúc đó bạn có thể viết code luôn, điều này tiện hơn rất nhiều.

Bạn cứ nghĩ có nhiều hàm thì chương trình sẽ rõ ràng hơn, nhưng có quá nhiều thì việc xem và sửa code cũng khá phức tạp đấy bạn ạ.

Xu hướng

Bài mới









  • Chịu trách nhiệm nội dung: Trần Mạnh Hiệp
  • © 2024 Công ty Cổ phần MXH Tinh Tế
  • Địa chỉ: Số 70 Bà Huyện Thanh Quan, P. Võ Thị Sáu, Quận 3, TPHCM
  • Số điện thoại: 02822460095
  • MST: 0313255119
  • Giấy phép thiết lập MXH số 11/GP-BTTTT, Ký ngày: 08/01/2019