Câu trả lời:
Giống như hầu hết các câu trả lời khác đã nói, các phương thức thể hiện sử dụng một thể hiện của một lớp, trong khi một phương thức lớp có thể được sử dụng chỉ với tên lớp. Trong Objective-C, chúng được định nghĩa như vậy:
@interface MyClass : NSObject
+ (void)aClassMethod;
- (void)anInstanceMethod;
@end
Sau đó chúng có thể được sử dụng như vậy:
[MyClass aClassMethod];
MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];
Một số ví dụ thực tế về các phương thức lớp là các phương thức tiện lợi trên nhiều lớp Foundation như NSString
's +stringWithFormat:
hoặc NSArray
' +arrayWithArray:
. Một phương pháp dụ sẽ là NSArray
's -count
phương pháp.
Tất cả các chi tiết kỹ thuật đã được bao phủ độc đáo trong các câu trả lời khác. Tôi chỉ muốn chia sẻ một sự tương tự đơn giản mà tôi nghĩ là minh họa độc đáo sự khác biệt giữa một lớp và một thể hiện:
Một lớp giống như bản thiết kế của một ngôi nhà: Bạn chỉ có một bản thiết kế và (thông thường) bạn không thể làm điều đó nhiều với bản thiết kế.
Một ví dụ (hoặc một đối tượng ) là ngôi nhà thực tế mà bạn xây dựng dựa trên bản thiết kế: Bạn có thể xây dựng nhiều ngôi nhà từ cùng một bản thiết kế. Sau đó, bạn có thể sơn các bức tường một màu khác nhau trong mỗi ngôi nhà, giống như bạn có thể thay đổi độc lập các thuộc tính của từng thể hiện của một lớp mà không ảnh hưởng đến các thể hiện khác.
difference between class method and an instance method
;
Giống như các câu trả lời khác đã nói, các phương thức cá thể hoạt động trên một đối tượng và có quyền truy cập vào các biến thể hiện của nó, trong khi một phương thức lớp hoạt động trên toàn bộ một lớp và không có quyền truy cập vào các biến của một thể hiện cụ thể (trừ khi bạn chuyển thể hiện trong như một tham số).
Một ví dụ điển hình của phương thức lớp là phương thức kiểu đối lập, trả về tổng số thể hiện của một lớp. Các phương thức lớp bắt đầu bằng một +
, trong khi các thể hiện bắt đầu bằng một -
. Ví dụ:
static int numberOfPeople = 0;
@interface MNPerson : NSObject {
int age; //instance variable
}
+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
@end
@implementation MNPerson
- (id)init{
if (self = [super init]){
numberOfPeople++;
age = 0;
}
return self;
}
+ (int)population{
return numberOfPeople;
}
- (int)age{
return age;
}
@end
chính
MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);
Đầu ra: Tuổi: 0 Số người: 2
Một ví dụ khác là nếu bạn có một phương thức mà bạn muốn người dùng có thể gọi, đôi khi thật tốt khi biến nó thành một phương thức lớp. Ví dụ: nếu bạn có một lớp gọi là MathFifts, bạn có thể làm điều này:
+ (int)square:(int)num{
return num * num;
}
Vì vậy, sau đó người dùng sẽ gọi:
[MathFunctions square:34];
mà không bao giờ phải khởi tạo lớp học!
Bạn cũng có thể sử dụng các hàm lớp để trả về các đối tượng được tự động phát hành, như của NSArray
+ (NSArray *)arrayWithObject:(id)object
Điều đó lấy một đối tượng, đặt nó vào một mảng và trả về một phiên bản tự động của mảng mà không phải quản lý bộ nhớ, tuyệt vời cho các mảng ôn đới và những gì không.
Tôi hy vọng bây giờ bạn hiểu khi nào và / hoặc tại sao bạn nên sử dụng các phương thức lớp !!
Một phương thức cá thể áp dụng cho một thể hiện của lớp (tức là một đối tượng) trong khi một phương thức lớp áp dụng cho chính lớp đó.
Trong C #, một phương thức lớp được đánh dấu tĩnh. Các phương thức và thuộc tính không được đánh dấu tĩnh là các phương thức thể hiện.
class Foo {
public static void ClassMethod() { ... }
public void InstanceMethod() { ... }
}
Câu trả lời cho câu hỏi của bạn không dành riêng cho object-c, tuy nhiên trong các ngôn ngữ khác nhau, các phương thức Class có thể được gọi là phương thức tĩnh.
Sự khác biệt giữa các phương thức lớp và phương thức cá thể là
Phương thức lớp
Phương pháp sơ thẩm
Tôi nghĩ rằng cách tốt nhất để hiểu điều này là nhìn vào alloc
và init
. Chính lời giải thích này đã cho phép tôi hiểu được sự khác biệt.
Phương pháp lớp học
Một phương thức lớp được áp dụng cho toàn bộ lớp. Nếu bạn kiểm tra alloc
phương thức, đó là một phương thức lớp được biểu thị bằng +
trước khi khai báo phương thức. Đây là một phương thức lớp vì nó được áp dụng cho lớp để tạo một thể hiện cụ thể của lớp đó.
Phương pháp sơ thẩm
Bạn sử dụng một phương thức cá thể để sửa đổi một thể hiện cụ thể của một lớp duy nhất cho cá thể đó, thay vì toàn bộ lớp. init
ví dụ (được biểu thị bằng a -
trước khi khai báo phương thức), là một phương thức thể hiện bởi vì bạn thường sửa đổi các thuộc tính của lớp đó sau khi nó được tạo bằng alloc
.
Thí dụ
NSString *myString = [NSString alloc];
Bạn đang gọi phương thức lớp alloc
để tạo một thể hiện của lớp đó. Lưu ý cách người nhận tin nhắn là một lớp.
[myString initWithFormat:@"Hope this answer helps someone"];
Bạn đang sửa đổi thể hiện của cuộc NSString
gọi myString
bằng cách đặt một số thuộc tính trên thể hiện đó. Lưu ý cách người nhận tin nhắn là một thể hiện (đối tượng của lớp NSString
).
alloc
phân bổ đủ bộ nhớ cho đối tượng, init
sẽ sửa đổi những gì trong các địa chỉ bộ nhớ đó để xác định trạng thái của đối tượng. Chúng tôi không thể sửa đổi một đối tượng trừ khi có không gian để sửa đổi nó, vì vậy chúng tôi sử dụng alloc
trên lớp sẽ quyết định cung cấp cho chúng tôi không gian đó.
Các phương thức lớp thường được sử dụng để tạo các thể hiện của lớp đó
Ví dụ, [NSString stringWithFormat:@"SomeParameter"];
trả về một NSString
thể hiện với tham số được gửi đến nó. Do đó, vì nó là một phương thức Class trả về một đối tượng cùng loại, nên nó còn được gọi là phương thức tiện lợi.
Vì vậy, nếu tôi hiểu chính xác.
Một class
phương thức không cần bạn phân bổ thể hiện của đối tượng đó để sử dụng / xử lý nó. Một class
phương thức được khép kín và có thể hoạt động mà không phụ thuộc vào trạng thái của bất kỳ đối tượng nào của lớp đó. Một class
phương thức được dự kiến sẽ phân bổ bộ nhớ cho tất cả công việc của chính nó và phân bổ khi hoàn thành, vì không có trường hợp nào của lớp đó có thể giải phóng bất kỳ bộ nhớ nào được phân bổ trong các cuộc gọi trước đó cho phương thức lớp.
Một instance
phương pháp thì ngược lại. Bạn không thể gọi nó trừ khi bạn phân bổ một thể hiện của lớp đó. Nó giống như một lớp bình thường có hàm tạo và có thể có hàm hủy (giúp dọn sạch tất cả bộ nhớ được phân bổ).
Trong hầu hết các khả năng (trừ khi bạn đang viết một thư viện có thể sử dụng lại, bạn không cần một class
biến.
Lấy ví dụ một trò chơi trong đó rất nhiều xe được sinh ra .. mỗi chiếc thuộc về lớp CCar. Khi một chiếc xe được khởi tạo, nó sẽ gọi
[CCar registerCar:self]
Vì vậy, lớp CCar, có thể lập danh sách mọi CCar ngay lập tức. Giả sử người dùng hoàn thành một cấp độ và muốn xóa tất cả ô tô ... bạn có thể: 1- Đi qua danh sách mọi CCar bạn đã tạo thủ công và thực hiện whicheverCar.remove();
hoặc 2- Thêm phương thức removeAllCars vào CCar, điều này sẽ làm điều đó cho bạn khi bạn gọi [CCar remove ALLCars]. I E allCars[n].remove();
Hoặc ví dụ: bạn cho phép người dùng chỉ định kích thước phông chữ mặc định cho toàn bộ ứng dụng, được tải và lưu khi khởi động. Nếu không có phương thức lớp, bạn có thể phải làm một cái gì đó như
fontSize = thisMenu.getParent().fontHandler.getDefaultFontSize();
Với phương thức lớp, bạn có thể thoát khỏi [FontHandler getDefaultFontSize]
.
Đối với chức năng removeVowels của bạn, bạn sẽ thấy rằng các ngôn ngữ như C # thực sự có cả hai phương thức nhất định như toLower hoặc toUpper.
ví dụ myString.removeVowels()
và String.removeVowels(myString)
(trong ObjC sẽ là [String removeVowels:myString]
).
Trong trường hợp này, cá thể có khả năng gọi phương thức lớp, vì vậy cả hai đều có sẵn. I E
public function toLower():String{
return String.toLower();
}
public static function toLower( String inString):String{
//do stuff to string..
return newString;
}
về cơ bản, myString.toLower()
các cuộc gọi [String toLower:ownValue]
Không có câu trả lời dứt khoát, nhưng nếu bạn cảm thấy muốn đưa một phương thức lớp vào sẽ cải thiện mã của bạn, hãy thử và lưu ý rằng một phương thức lớp sẽ chỉ cho phép bạn sử dụng các phương thức / biến lớp khác.
phương pháp lớp
là các phương thức được khai báo là tĩnh. Phương thức có thể được gọi mà không tạo một thể hiện của lớp. Các phương thức lớp chỉ có thể hoạt động trên các thành viên lớp chứ không phải các thành viên thể hiện vì các phương thức lớp không biết về các thành viên thể hiện. Các phương thức sơ thẩm của lớp cũng không thể được gọi từ bên trong một phương thức lớp trừ khi chúng được gọi trong một thể hiện của lớp đó.
Phương pháp sơ thẩm
mặt khác yêu cầu một thể hiện của lớp tồn tại trước khi chúng có thể được gọi, do đó, một thể hiện của một lớp cần được tạo bằng cách sử dụng từ khóa mới. Phương thức sơ thẩm hoạt động trên các trường hợp cụ thể của các lớp. Các phương thức sơ thẩm không được khai báo là tĩnh.
Trong Objective-C, tất cả các phương thức đều bắt đầu bằng ký tự "-" hoặc "+". Thí dụ:
@interface MyClass : NSObject
// instance method
- (void) instanceMethod;
+ (void) classMethod;
@end
Các ký tự "+" và "-" xác định xem một phương thức là một class method
hoặc một instance method
tương ứng.
Sự khác biệt sẽ rõ ràng nếu chúng ta gọi các phương thức này. Ở đây các phương thức được khai báo trong MyClass
.
instance method
yêu cầu một thể hiện của lớp:
MyClass* myClass = [[MyClass alloc] init];
[myClass instanceMethod];
Bên trong MyClass
các phương thức khác có thể gọi các phương thức MyClass
sử dụng self
:
-(void) someMethod
{
[self instanceMethod];
}
Nhưng, class methods
phải được gọi trên chính lớp:
[MyClass classMethod];
Hoặc là:
MyClass* myClass = [[MyClass alloc] init];
[myClass class] classMethod];
Điều này sẽ không hoạt động:
// Error
[myClass classMethod];
// Error
[self classMethod];
Một phương thức lớp thường tạo ra một thể hiện mới của lớp hoặc lấy một số thuộc tính toàn cục của lớp. Các phương thức lớp không hoạt động trên một cá thể hoặc có bất kỳ quyền truy cập nào vào biến thể hiện.
Một phương thức cá thể hoạt động trên một thể hiện cụ thể của lớp. Ví dụ, phương thức truy cập mà bạn đã triển khai là tất cả các phương thức thể hiện. Bạn sử dụng chúng để đặt hoặc lấy các biến đối tượng của một đối tượng cụ thể.
Để gọi một phương thức cá thể, bạn gửi tin nhắn đến một thể hiện của lớp.
Để gọi một phương thức lớp, bạn gửi tin nhắn trực tiếp đến lớp.
Nguồn: IOS - Objective-C - Phương thức lớp và phương thức sơ thẩm
Các phương thức lớp không thể thay đổi hoặc biết giá trị của bất kỳ biến thể hiện nào. Đó phải là tiêu chí để biết liệu một phương thức cá thể có thể là một phương thức lớp hay không.
Cũng cần nhớ, ý tưởng tương tự áp dụng cho các biến. Bạn sẽ bắt gặp các thuật ngữ như tĩnh, thành viên, thể hiện, lớp, v.v. khi nói về các biến giống như bạn làm cho các phương thức / hàm.
Có vẻ như thuật ngữ phổ biến trong cộng đồng Obj-C là ivar biến, nhưng tôi chưa phải là một chàng trai Obj-C.
Một bản cập nhật cho các câu trả lời ở trên, tôi đồng ý các phương thức cá thể sử dụng một thể hiện của một lớp, trong khi một phương thức lớp có thể được sử dụng chỉ với tên lớp.
Không còn có bất kỳ sự khác biệt nào giữa phương thức cá thể & phương thức lớp sau khi đếm tham chiếu tự động xuất hiện trong Objective-C.
Ví dụ: [NS StringWithformat:..]
một phương thức lớp & [[NSString alloc] initwihtformat:..]
một phương thức cá thể, cả hai đều giống nhau sau ARC
Lưu ý: Đây chỉ là định dạng mã giả
Phương pháp lớp
Hầu như tất cả những gì nó cần làm là trong thời gian biên dịch . Nó không cần bất kỳ đầu vào của người dùng, cũng như tính toán của nó dựa trên một thể hiện. Mọi thứ về nó đều dựa trên lớp / kế hoạch chi tiết, đó là duy nhất, tức là bạn không có nhiều bản thiết kế cho một lớp. Bạn có thể có các biến thể khác nhau trong thời gian biên dịch? Không, do đó, lớp này là duy nhất và do đó, bất kể bạn gọi một phương thức lớp bao nhiêu lần thì con trỏ trỏ tới nó sẽ giống nhau.
PlanetOfLiving: return @"Earth" // No matter how many times you run this method...nothing changes.
Phương pháp sơ thẩm
Trong trường hợp ngược lại, phương thức xảy ra trong thời gian chạy, vì chỉ khi đó bạn mới tạo ra một thể hiện của một cái gì đó có thể thay đổi theo mỗi lần khởi tạo.
initWithName: @"John" lastName: @"Doe"Age:12 @"cool"
initWithName: @"Donald" lastName: @"Drumpf"Age:5 attitude:@"He started"
initWithName: @"President" lastName: @"Obama"Age:54 attitude: @"Awesome"
//As you can see the value can change for each instance.
Nếu bạn đến từ các ngôn ngữ khác, các phương thức tĩnh giống như các phương thức lớp.
Nếu bạn đến từ Swift, các phương thức kiểu giống như các phương thức lớp.
Thêm vào câu trả lời trên
Phương thức lớp sẽ hoạt động trên lớp, chúng tôi sẽ sử dụng phương thức này cho mục đích chung trong đó như + stringWithFormat, kích thước của lớp và quan trọng nhất là cho init vv
NSString *str = [NSString stringWithFormat:@"%.02f%%",someFloat];
Phương thức sơ thẩm sẽ hoạt động trên một thể hiện của một lớp không thuộc một lớp như chúng tôi đang có hai người và chúng tôi muốn biết số dư của từng cá nhân ở đây, chúng tôi cần sử dụng phương thức cá thể. Bởi vì nó sẽ không trả lời chung. ví dụ như xác định số lượng NSSArray, v.v.
[johnson getAccountBalance];
[ankit getAccountBalance];