Różnica między kategorią a rozszerzeniem klasy?

85

Jaka jest różnica między kategorią a rozszerzeniem klasy. Uważam, że oba są używane do dodawania niestandardowych metod w istniejących klasach. Czy ktoś może rzucić na to światło? Egzamin z kodem będzie naprawdę mile widziany.

Abhinav
źródło
3
Akusete, nie można znaleźć strony.
Adil Hussain
wyraźnie zilustrowane tutaj, code.tutsplus.com/tutorials/ ...
grassyburrito

Odpowiedzi:

103

Kategoria to sposób na dodanie metod do istniejących klas. Zwykle znajdują się w plikach o nazwie „Class + CategoryName.h”, np. „NSView + CustomAdditions.h” (i oczywiście .m).

Rozszerzenie klasy to kategoria, z wyjątkiem dwóch głównych różnic:

  1. Kategoria nie ma nazwy. Jest deklarowane w następujący sposób:

    @interface SomeClass ()
    
    
    - (void) anAdditionalMethod;
    
    @koniec
  2. Implementacja rozszerzenia musi znajdować się w głównym bloku @implementation pliku.

Często zdarza się, że rozszerzenie klasy na górze pliku .m deklaruje więcej metod klasy, które są następnie implementowane poniżej w głównej sekcji @implementation klasy. Jest to sposób na zadeklarowanie metod „pseudo-prywatnych” (pseudo-prywatnych, ponieważ nie są one tak naprawdę prywatne, po prostu nie są ujawniane zewnętrznie).

Dave DeLong
źródło
13
W Class-Extensiosn możesz nadpisać właściwości z (publicznej) właściwości tylko do odczytu, aby były wewnętrznie do odczytu i zapisu. A od LLVM 1.5 możesz zrobić jeszcze więcej: możesz teraz deklarować zmienne instancji w rozszerzeniu klasy, aby zniknęły ze zwykłego interfejsu.
Max Seelemann
Po co dodawać rozszerzenie klasy, skoro można po prostu zaimplementować te metody i właściwości w klasie? Wydaje mi się to trochę zbędne.
user1721803
1
@ user1721803 Jak zasugerował Dave, możesz chcieć nie ujawniać kilku właściwości / metod. Dzieje się tak, gdy używane są rozszerzenia. Rozważ widok, możesz podłączyć wszystkie swoje IBOutlety i IBActions w rozszerzeniu i ujawnić metody, które pozwalają na inicjalizację / aktualizację Outlety i akcje mogą być delegowane z powrotem.
GoodSp33d
@MaxSeelemann czy możesz pokazać, jak za pomocą krótkiego skryptu zrobić „(publiczną) właściwość tylko do odczytu, która będzie wewnętrznie do odczytu i zapisu”? Dzięki.
allenlinli
W tej odpowiedzi podano rozszerzenie w pliku „Class + CategoryName.swift”, czy jest poprawne?
Rishi
47
  1. Kategoria

=> W celu C, jeśli chcesz dodać więcej funkcjonalności do klasy bez dziedziczenia, po prostu użyj dla niej kategorii.

=> ma własny plik .h i .m

=> Categoryużywa do dodania nowej metody, a nie właściwości.

  1. Rozszerzenie klasy
-> In Objective C, when you want to make behaviour of some property private you use class extension.

-> it comes with **.h** file only.

-> mainly for properties.

Uwaga: kiedy dodamy nowy plik i wybierzemy opcję celu, kategoria c pokazuje kategorię i „kategorię na”, a nie „podklasę”, więc wygląda jak

@interface className (categoryName)
@end

-Otrzymasz dwa pliki .h i .m z nazwy pliku jako ( className + categoryName.h i className + categoryName.m )

aw przypadku rozszerzenia otrzymasz

@interface className()
@end

- Otrzymasz tylko jeden plik o nazwie nazwa_klasy_nazwa_rozszerzenia.h

  • W kategorii nie jesteś właścicielem klasy, ale w rozszerzeniu jesteś.
Anurag Bhakuni
źródło
5
@Prasanna: rozszerzenie klasy jest dostarczane tylko z plikiem .m, a nie w .h
Saggy
1
rozszerzenie class jest dostarczane tylko z plikiem .h, a nie .m
Nishu_Priya
32
  1. Kategoria to sposób dodawania metod do klasy niezależnie od tego, czy kod źródłowy jest dostępny, czy nie, co oznacza, że ​​możesz dodać kategorię do klas podstawowych, takich jak NSString a także do własnych klas niestandardowych.

    Rozszerzenie można dodać tylko do klas, których kod źródłowy jest dostępny, ponieważ kompilator kompiluje kod źródłowy i rozszerzenie w tym samym czasie.

  2. Możemy dodać dodatkowe zmienne instancji i właściwości w rozszerzeniu klasy, ale nie w kategorii.

  3. Żadna zmienna i metoda wewnątrz rozszerzenia nie jest nawet dostępna dla dziedziczonych klas.

  4. Kategoria i rozszerzenie są w zasadzie stworzone do obsługi dużej bazy kodu, ale kategoria jest sposobem na rozszerzenie API klasy w wielu plikach źródłowych, podczas gdy rozszerzenie jest sposobem na dodanie wymaganych metod poza głównym plikiem interfejsu.

  5. Użyj kategorii, gdy musisz rozbić ten sam kod klasy na różne pliki źródłowe zgodnie z różnymi funkcjami i rozszerzenia, gdy potrzebujesz tylko dodać wymagane metody do istniejącej klasy poza głównym plikiem interfejsu. Ponadto, gdy musisz zmodyfikować publicznie zadeklarowaną zmienną instancji w klasie, na przykład tylko do odczytu, aby odczytać i zapisać, możesz ponownie zadeklarować ją w rozszerzeniu.

Venu Gopal Tewari
źródło
3
Przeczytałem 5 podobnych pytań z wieloma odpowiedziami i to jest najlepsze. Dziękuję Ci!
Miód
1
Możesz również dodać właściwości w kategorii. Zobacz odpowiedź @Pebby.
atulkhatri
7

Rozbudowa : Aby uczynić metody prywatnymi i dodać właściwości naszej własnej klasy niestandardowej, a nie klasy Apple.

Kategoria : Aby dodać więcej metod w istniejącej klasie, a nie właściwość, można jej użyć zarówno dla klasy niestandardowej, jak i klasy Apple, takiej jak NSString.

Ankit garg
źródło
Prosty i elegancki. Tak trzymaj
Abdul Yasin
3

Możemy również mieć właściwości, używając właściwości związanych z zestawem w klasie kategorii.

@interface SomeClass (Private)

@property (nonatomic, assign) id newProperty;

@end

NSString * const kNewPropertyKey = @"kNewPropertyKey";

@implementation SomeClass (Private)

@dynamic newProperty;

- (void)setNewProperty:(id)aObject
{
    objc_setAssociatedObject(self, kNewPropertyKey, aObject, OBJC_ASSOCIATION_ASSIGN);
}

- (id)newProperty
{
    return objc_getAssociatedObject(self, kNewPropertyKey);
}

@end

Zobacz: http://inchoo.net/dev-talk/ios-development/how-to-add-a-property-via-class-category/

PradeepKN
źródło
2
@interface SomeClass ()


- (void) anAdditionalMethod;


@end

Myślę, że to nie jest sposób na zadeklarowanie kategorii. Kategoria musi mieć nazwę

@interface SomeClass (XYZ)


- (void) anAdditionalMethod;


@end

na przykład

@interface NSMutableArray (NSMutableArrayCreation)

+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;

@end

Zadeklarowane dla NSMutableArray przez Apple

Odkrywanie
źródło
W ten sposób deklarujesz i rozszerzasz, a nie kategorię -> @interface SomeClass ()
ChavirA
0

rozszerzenie ios podobne do C #, abstrakcyjna klasa java lub interfejs
kategoria ios podobna do C #, rozszerzenie klasy java

Add080bbA
źródło
4
Twoja odpowiedź brzmi jak „kot jest podobny do tygrysa, odpowiadając niewidomemu”. Lol
Muruganandham K
1
tak nie jest. Jest to najbardziej bezpośrednie i szybkie wyjaśnienie, jeśli znasz język C # lub Javę.
Add080bbA
Niezbyt opisowe i ledwo odpowiedział na pytanie.
KVISH
0

Kategorie

Kategorie są używane podczas tworzenia pliku zawierającego dużą liczbę metod, dzięki czemu dają możliwość rozbicia pojedynczej klasy na różne moduły, a także w przypadku jakichkolwiek zmian w kategoriach kompilator nie marnuje czasu na kompilację całego projektu .Kategorie nie mogą dodawać nowych zmiennych lub właściwości i wyszukiwać do ich klasy nadrzędnej. Możesz przesłonić metodę w kategorii, ale nie jest to dobry pomysł, ponieważ metoda nie może być dalej nadpisywana. Również przepływ może zostać zmieniony, ponieważ wszystkie kategorie mają ten sam poziom hierarchii, a zatem dwie kategorie należące do tej samej klasy nadrzędnej mogą istnieć w czasie wykonywania.Również metody chronione mogą być tworzone przy użyciu kategorii

Rozszerzenia

Rozszerzenia umożliwiają przesłonięcie właściwości lub dodanie nowej właściwości do istniejącej klasy nadrzędnej.Syntatycznie takie same dla kategorii, które nie mają nazwy i są reprezentowane jako @interface class () Brak pliku .m i metoda zadeklarowana w rozszerzeniu musi zostać zaimplementowana w implementacji pliku nadrzędnego

Więcej pomocy pod tym linkiem

Suryanarayan Sahu
źródło
0

Oto moje zrozumienie:

Rozszerzenia są zwykle używane w celu dodania dodatkowych funkcji do naszej własnej „ niestandardowej klasy” ”. Możemy dodać prywatne metody lub właściwości rozszerzające interfejs klasy, które mogą być używane w ramach implementacji klasy.

Rozszerzenia mają być zapisane w tym samym pliku co klasa. Dlatego nie można pisać rozszerzeń dla wstępnie zdefiniowanych typów, takich jak String, Float itp.

Z drugiej strony kategorie mogą służyć do dodawania dodatkowych metod do wcześniej istniejących klas. Przykład możemy stworzyć własne metody rozszerzając klasę String. Pamiętaj, że nie możemy tworzyć dodatkowych właściwości w kategoriach. Główną zaletą kategorii jest to, że możemy zapisywać kategorie w dowolnym innym pliku, poza plikiem, w którym kończy się Twoja klasa.

Również podczas tworzenia kategorii należy nadać jej nazwę w nawiasach. Ale dla rozszerzenia nie jest wymagana nazwa. Stąd czasami nazywane są kategoriami anonimowymi.

iPhoneDeveloper
źródło
Jesteś trochę na uboczu.
Abdul Yasin,
@iPhoneDeveloper Możemy napisać rozszerzenie dla predefiniowanych typów. Sprawdź ten link - stackoverflow.com/a/33942484/2060508
yo2bh