Phần mở rộng lớp học so với loại lớp học


82

Các phần 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ể.

Có những điểm khác biệt nào khác và khi nào người ta nên sử dụng một danh mục trên một phần mở rộng lớp?


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

Đối với phần mở rộng khi chúng được sử dụng trong Swift, xem câu hỏi này: stackoverflow.com/questions/24142829/...
Suragch

Câu trả lời:


91

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 phần mở rộng của mình @implementation, trong khi với một danh mục, bạn có một @implementationkhối riêng biệt . Vì vậy, hầu như bạn chỉ nên sử dụng một tiện ích mở rộng ở đầu .mtệp chính của mình (tình cờ là nơi duy nhất bạn nên quan tâm đến ivars) - nó chỉ có nghĩa là, một tiện ích mở rộng .


41
Phần mở rộng là tốt nhất cho các phương thức riêng tư mà bạn muốn khai báo trong .mtệp của mình . Tôi sử dụng nó cho việc này mọi lúc. Các 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 - danh mục :) - 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à phần mở rộng lớp sử dụng thuộc tính.
Paul.s

23
Các phần mở rộng lớp cũng được thiết kế đặc biệt để cho phép một thuộc tính được công khai readonlyvà riêng tư readwrite. Không thể làm điều đó với các danh mục (một lựa chọn thiết kế có ý thức).
bbum

Tại sao Google sử dụng danh mục để triển khai các phương pháp riêng tư thay vì tiện ích mở rộng? ví dụ: code.google.com/p/gdata-objectivec-client/source/browse/trunk/…
Ryan

phần mở rộng yêu cầu tất cả các phương thức được triển khai trong khối @implementation, đồng thời nó cũng cung cấp khả năng nâng cao cho các biến. Nhưng chúng ta về cơ bản cố gắng để đưa một số phương pháp riêng thay vì sử dụng các biến riêng, vì vậy trong trường hợp đó chúng ta thích loại thay vì mở rộng
Ankit Thakur

29

Phần mở rộng lớp mang một số điểm tương đồng với một danh mục, nhưng nó chỉ có thể được thêm vào một lớp mà bạn có mã nguồn tại thời điểm biên dịch (lớp được biên dịch cùng lúc với phần mở rộng lớp). Các phương thức được khai báo bởi phần mở rộng lớp được triển khai trong khối @implementation cho lớp gốc, vì vậy, ví dụ: bạn không thể khai báo phần mở rộng lớp 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 tương tự như cú pháp cho một danh mục và trông giống như sau:

@interface ClassName ()
@end

Bởi vì không có tên nào được đặt trong dấu ngoặc đơn, phần mở rộng lớp thường được gọi là danh mục ẩn danh.

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

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

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

Sử dụng tiện ích mở rộng lớp để ẩn thông tin cá nhân

Phần 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 thức hoặc thuộc tính riêng tư bổ sung để sử dụng trong quá trình triển khai của chính lớp đó. Ví dụ, thông thường, định nghĩa một thuộc tính là chỉ đọc trong giao diện, nhưng là ghi đọc trong phần mở rộng lớp được khai báo ở trên việc triển khai, để các phương thức bên trong 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 một thuộc tính gọi là uniqueIdentifier, được thiết kế để theo dõi thông tin như Số an sinh xã hội ở Hoa Kỳ.

Nó thường yêu cầu một lượng lớn thủ tục giấy tờ để có một số nhận dạng duy nhất được chỉ định cho một cá nhân trong thế giới thực, vì vậy 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ột số nhận dạng được chỉ định, như sau:

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

Để lớp XYZPerson có thể thay đổi thuộc tính bên trong, nên khai báo lại thuộc tính trong phần mở rộng lớp được định nghĩa ở đầu tệp triển khai cho lớp:

@property (readwrite) NSString *uniqueIdentifier;

Lưu ý: Thuộc tính readwrite là tùy chọn vì nó là thuộc tính mặc định. Bạn có thể muốn sử dụng nó khi khai báo lại một thuộc tính, để rõ ràng.


7

Danh mục là một tính năng ngôn ngữ Objective-C cho phép bạn thêm các phương thức mới vào một lớp hiện có. Phần mở rộng là một trường hợp đặc biệt của các 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.

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


"phải được khai báo trong khối thực thi chính." -> điều đó phải được "thực hiện" trong khối triển khai chính
Fawkes

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

0

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


Java không hỗ trợ phương pháp khuyến nông
someUser

lấy làm tiếc ! Sao chép-dán lỗi đánh máy. danh mục ios giống với phần mở rộng lớp c #.
Add080bbA

Bạn có thể thêm một ví dụ về?
Pedro Trujillo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.