2011-08-21 27 views
67

Các tiện ích mở rộng lớp @interface Class() mạnh hơn rất nhiều và có thể đưa các biến vào lớp. Danh mục @interface Class (Category) không thể.Tiện ích mở rộng loại so với loại lớp

Có sự khác biệt nào khác và khi nào một người nên sử dụng danh mục trên tiện ích mở rộng lớp học?

+0

danh mục là mã thực. chúng là cách bạn thêm các đối tượng vào một lớp. các phần mở rộng (theo các thuật ngữ rất chung chung) chỉ là đường cú pháp, để báo hiệu các ý tưởng nhất định về quyền riêng tư, v.v ... cho các lập trình viên khác. các phần mở rộng không chứa mã và không phải là mã. – Fattie

+0

Đối với các tiện ích mở rộng khi chúng được sử dụng trong Swift, hãy xem câu hỏi này: http://stackoverflow.com/questions/24142829/how-to-create-swift-class-for-category – Suragch

Trả lời

77

Sự khác biệt chính là với phần mở rộng, trình biên dịch sẽ mong đợi bạn triển khai các phương thức trong chính @implementation, trong khi với danh mục bạn có khối @implementation riêng biệt. Vì vậy, bạn nên sử dụng phần mở rộng ở đầu tệp .m chính của bạn (nơi duy nhất bạn nên quan tâm về ivars, tình cờ) - nó chỉ có nghĩa là, một phần mở rộng .

+3

Nhưng sau đó, điểm của việc sử dụng tiện ích mở rộng là gì thể loại? – David

+32

Một phần mở rộng là tốt nhất cho các phương thức riêng mà bạn muốn khai báo trong tệp '.m' của bạn. Tôi sử dụng nó cho tất cả các thời gian. Danh mục hữu ích hơn khi bạn muốn nhóm các phương thức của mình thành các phần khác nhau - * categories * :) - hoặc khi bạn muốn thêm mã vào các lớp hiện có mà bạn không tạo. – jtbandes

+1

Bạn cũng có thể thêm dung lượng bổ sung là tiện ích mở rộng lớp sử dụng các thuộc tính. –

3

Danh mục là tính năng ngôn ngữ mục tiêu-C cho phép bạn thêm các phương thức mới vào lớp hiện có. Tiện ích mở rộng là trường hợp đặc biệt của danh mục cho phép bạn xác định các phương pháp phải được triển khai trong khối triển khai chính.

Tuyên bố riêng tư có thể nằm trong tiện ích mở rộng lớp, chủ yếu là một số thuộc tính, vì chúng tôi không cần phải khai báo phương thức trước khi chúng tôi gọi nó.

+0

"phải được khai báo trong khối triển khai chính." -> phải được "triển khai" trong khối triển khai chính – Fawkes

+0

Cảm ơn, tôi đã sửa đổi nó. –

0

ios phần mở rộng tương tự như C#, lớp trừu tượng java hoặc giao diện
loại ios tương tự như c mở rộng # lớp

+0

Java không hỗ trợ các phương thức mở rộng – someUser

+0

xin lỗi! Sao chép-dán lỗi đánh máy. ios loại tương tự như mở rộng lớp C#. – Add080bbA

15

Một phần mở rộng lớp mang một số tương đồng vào một danh mục, nhưng nó chỉ có thể được thêm vào một lớp học mà bạn có mã nguồn tại thời gian biên dịch (lớp được biên dịch cùng lúc với phần mở rộng của lớp). Các phương thức được khai báo bởi một phần mở rộng lớp được thực hiện trong khối @implementation cho lớp gốc, vì vậy bạn không thể khai báo một lớp mở rộng trên một lớp khung, chẳng hạn như lớp Cocoa hoặc Cocoa Touch như NSString.

Cú pháp để khai báo một phần mở rộng lớp cũng tương tự như cú pháp cho một thể loại, và trông như thế này:

@interface ClassName() 
@end 

Bởi vì không có tên được đưa ra trong dấu ngoặc đơn, mở rộng lớp thường được gọi loại như vô danh .

Không giống như các danh mục thông thường, tiện ích mở rộng lớp có thể thêm các thuộc tính và biến mẫu của riêng nó vào một lớp. Nếu bạn khai báo thuộc tính trong tiện ích mở rộng lớp học, như sau:

@interface XYZAnimal() { 
    id _someCustomInstanceVariable; 
} 
... 
@end 

IMHO, tốt nhất nên nghĩ về tiện ích mở rộng lớp là giao diện riêng tư cho một lớp học. Giao diện chính (trong tệp .h) của bạn hoạt động như một giao diện công cộng xác định hợp đồng hành vi của lớp với các lớp khác.

mở rộng Sử dụng lớp để Ẩn thông tin riêng tư

mở rộng lớp thường được sử dụng để mở rộng giao diện công cộng với các phương pháp bổ sung riêng hoặc tài sản để sử dụng trong việc thực hiện các lớp riêng của mình. Ví dụ, thông thường, để xác định thuộc tính là chỉ đọc trong giao diện, nhưng khi ghi đè trong tiện ích mở rộng lớp được khai báo bên trên việc triển khai, để các phương thức nội bộ của lớp có thể thay đổi trực tiếp giá trị thuộc tính.

Ví dụ, lớp XYZPerson có thể thêm thuộc tính được gọi là uniqueIdentifier, được thiết kế để theo dõi thông tin như Số an sinh xã hội ở Hoa Kỳ.

Thường đòi hỏi một số lượng lớn giấy tờ để có một mã định danh duy nhất được gán cho một cá nhân trong thế giới thực, do đó giao diện lớp XYZPerson có thể khai báo thuộc tính này là chỉ đọc và cung cấp một số phương thức yêu cầu mã định danh được gán này:

@interface XYZPerson : NSObject 
    ... 
    @property (readonly) NSString *uniqueIdentifier; 
    - (void)assignUniqueIdentifier; 
@end 

để cho lớp XYZPerson để có thể thay đổi tài sản trong nội bộ, nó làm cho tinh thần để redeclare tài sản trong một phần mở rộng lớp học đó là định nghĩa ở phía trên cùng của tập tin thực thi cho các lớp:

@property (readwrite) NSString *uniqueIdentifier; 

Lưu ý: Thuộc tính ghi đè là tùy chọn vì đó là mặc định. Bạn có thể muốn sử dụng nó khi redeclaring một tài sản, cho rõ ràng.

-1

Danh mục là cách để mở rộng API của các lớp hiện có và tiện ích mở rộng là cách thêm các phương thức cần thiết vào API bên ngoài tệp giao diện chính. Cả hai đều được thiết kế ban đầu để giảm bớt gánh nặng của việc duy trì các cơ sở mã lớn.

Hãy cẩn thận khi sử dụng loại:

1- Bạn không thể đáng tin cậy ghi đè lên các phương pháp quy định tại mục cho cùng lớp.

2- Danh mục không thể thêm biến mẫu. Điều này có nghĩa là bạn không thể khai báo các thuộc tính mới.

Tham chiếu: Objective-C Succinctly: Categories and Extensions. Nó có một cuộc thảo luận chi tiết với các ví dụ.

Các vấn đề liên quan