Problemy techniczne - internet też rzecz i czasami siada

Bierzemy się już za programowanie.
Obiektowość. Klasy -z czym to się je
Aby dobrze pojąć takie coś jak obiekt (object) i klasa (class) potrzebne nam jest na początek tylko i wyłącznie poprawne rozumowanie obiektów otaczających nas dookoła. A dokładnie chodzi o proste powiązania rzeczy/istoty żywej oraz to co mogą robić czy jak się zachowywać.
Weźmy np. człowieka. Ów człowiek jest klasą (class), Ogólna postać człowieka opisuje nam każdego człowieka jak np. "Józek", który jest obiektem tej klasy (człowieka).
Człowieka potrafi chodzić, mówić, jeść etc. - są to funkcje które mu przypisujemy. Funkcje te w klasach są nazywane metodami. Człowiek nasz posiada także różne cechy takie jak: kolor, imię i nazwisko, wiek etc.
Idąc dalej tym tropem mamy:
- Klasa: człowiek
- Cechy: nazwisko, wiek
- Funkcje/Metody: chodzenie, mówienie
Jak widać klasa (class) to opis obiektu (object).
Człowiek należy również do jakiegoś gatunku t.j. ssak naczelny. I wywodzi się właśnie z niego. Można powiedzieć, że dziedziczy pewne cechy oraz funkcje od tego gatunku, czyli jest jakby jego potomkiem. W programowaniu nazywamy to inheritance czyli dziedziczenie - praktycznie nierozłączna część programowania w Objective C.
Już od samego początku poznamy i zaprzyjaźnimy się z dziedziczeniem, ale tylko w podstawowej jego części - reszta w dalszych częściach kursu.
Każdego człowieka możemy zapytać np o wiek czy o nazwisko czy również możemy także, jeśli np jest to nasz pracownik polecić aby coś zrobił, chociaż nie zawsze musi wiedzieć jak (o tym będzie w innej części kursu). Możemy nawet zmienić ich cechy (chociaż nie zawsze

Polega to na zasadzie, iż jeśli chcemy komuś wysłać wiadomość/polecenie musimy wiedzieć do kogo ją zaadresować. Ten ktoś jest nazywany odbiorcą - receiver, a nadawca - sender.
Wygląda to tak:
[odbiorca wiadomosc/polecenie]
Gdzie wiadomość/polecenie to metoda obiektu, czyli naszego odbiorcy. A odbiorca to obiekt.
Myślę, że tak krótki opis co to jest obiekt wystarczy.
Przejdziemy teraz do tworzenia obiektów w Objective C oraz ich używania.
Składnia
Od tej pory będę tylko używał określenia metoda dla określenie polecenia czy funkcji, czy wiadomość (tu message) klasy/obiektu.
Każda klasa jest deklarowana poprzez
@interface NaszKlasa: KlasaPoKtorejDziedziczymy
{
// cechy klasy
}
//metody/polecenia
@end
Cechy klasy tworzymy poprzez normalne deklaracje zmiennych, czyli np:
int wiek;
NSString *nazwisko;
Metody/polecenia obiektu (nie klasy) tworzy się poprzez:
-(typ jaki zwraca metody) metoda;
-(typ jaki zwraca metody) metoda: (typ argumentu) argument;
-(typ jaki zwraca metody) metoda: (typ argumentu) argument iDrugiAgrument:(typ drugiego argumentu) drugiArgument;
Gdzie "typ jaki zwraca metoda" może zostać pominięty. Ale ten temat zostawimy na cześć kursu o dziedziczeniu.
"metoda" jest także nazwą argumentu, jeśli takowy istnieje, bądź wskazówką dla pierwszego argumentu.
W 3 przykładzie metody nazwa "iDrugiArgument" jest opcjonalna, ale dla czytelności kodu lepiej używać nazw argumentów. Przykład:
Z nazwą argumentu:
-[czlowiek ustawNazwisko: @"nazwisko" iWiek: 25]
I bez nazwy argumentu:
-[czlowiek ustawNazwisko: @"nazwisko" : 25]
Także sam/a stwierdź, który sposób jest lepszy -czyt. bardziej czytelny.
Natomiast definicja/implmentacje naszej klasy wyglada tak:
@implementation NaszaKlasa: KlasaPoKtorejDziedziczymy
// definicje metod/implementacje
-(type jaki zwraca metoda) metoda
{
}
-(typ jaki zwraca metoda) metoda: (typ argumentu) argument
{
}
@end
Na podstawie tych wiadomości możemy już stworzyć klasę naszego Człowieka
@interface Czlowiek: NSObject
{
int wiek;
NSString *nazwisko;
}
-(void) ustawNazwisko: (NSString *) n;
-(void) ustawWiek: (int) w;
-(void) ustawNazwisko: (NSString *) n iWiek: (int) w;
-(NSString *) nazwisko;
-(int) wiek;
@end
@implementation Czlowiek
-(void) ustawNazwisko: (NSString *) n
{
nazwisko = n;
}
-(void) ustawWiek: (int) w
{
wiek = w;
}
-(void) ustawNazwisko: (NSString *) n iWiek: (int) w
{
nazwisko = n;
wiek = w;
}
-(NSString *) nazwisko
{
return nazwisko;
}
-(int) wiek
{
return wiek;
}
@end
NSObject jest obiektem bazowym. Którego będziemy używać na razie jak coś co musi być

NSString jest klasą napisów z biblioteki Foundation. Będziemy jej używać do manipulacji tekstem.
Napisy z NSString tworzy się w ten sposób:
NSString *napis1 = @"Tworzy sie je jeszcze inaczej";
NSString *napis2 = @"Ale dla naszych potrzeb wystarczy";
A żeby użyć tego napisu przez np. funkcje printf, potrzebujemy wysłać metodę o napis w stylu C:
printf("%s", [napis1 cString]);
Metody ustawNazwisko, ustawWiek oraz ustawNazwisko: iWiek są tak zwanymi setterami.
Nazwa wzięła się z angielskiego i znaczy to ustaw (set). Normalnie by to wygladało tak:
-(void) setName: (NSString *) n;
...
a (int) wiek; to tak zwany getter, czyli pobierz od angielskiego get. Zauważ, że nazwa metody gettera jest taka sama jak cechy/zmiennej klasy. Możesz użyć nazwy jakiej chcesz, ale użycie tej samej nazwy jest bardziej czytelne i zrozumiałe.
Klasa człowieka, którą stworzyliśmy poprzez @interface, to tylko informacja co zawiera nasz klasa. Do tego potrzeba jeszcze dorobić implementacje.
Implementację umieszcza się zazwyczaj w plikach do kompilacji czyli w przypadku Objective C są to pliki z końcówką .m Natomiast pełną deklarację (@interface) umieszczamy w standardowym pliku nagłówkowym z C czyli .h
Aczkolwiek nie jest to wymóg i można umieszczać i deklaracje i implementację w jednym pliku .m, jak i my to zrobimy dzisiaj (tylko dla celów edukacyjnych

Teraz jak już mamy nasz opis (klasę) człowieka możemy stworzyć "Józka".
Wygląda to mniej więcej tak:
Czlowiek *jozek;
jozek = [Czlowiek alloc];
jozek = [jozek init];
Wszystkie obiekty podczas ich deklaracji muszą być poprzedzone gwiazdką "*", ponieważ są to wskaźniki (referencje) do tych obiektów. Więcej na ten temat w dalszych częściach kursu.
Każdy obiekt musi mieć przydzieloną pamięć - alloc oraz być zainicjowanym - init.
Pamięć przydziela się poprzez wywołanie metody alloc z klasy, która jest dziedziczona po NSObject.
Metoda alloc jest metodą klasy nie obiektu - o tym trochę później, który zwraca typ. Natomiast metoda init jest wywołana już dla naszego obiektu. Jest ona dziedziczona również poprzez NSObject.
Na razie musimy tylko wiedzieć, że za każdym razem jak tworzymy obiekt to musimy go w ten sposób utworzyć

Powyższy zapis tworzenia obiektu możemy skrócić do:
Czlowiek *jozek = [[Czlowiek alloc] init];
Pilega to na tym, iż możemy zagnieżdżać wysyłanie wiadomości do obiektów pamiętając, że najpierw pierwszeństwo w dostawaniu wiadomości ma obiekt bliżej środka. Czyli najpierw Czlowiek potem obiekt przez niego stworzony w naszym przypadku "jozek".
Po stworzeniu naszego obiektu musimy go zawsze zwolnić poprzez wysłanie do obiektu metody release:
[jozek release];
Na sam koniec już dzisiejszej części kursu zostało nam zrobić jeszcze program który to przetestuje:
#import
#import
#import
ZAMIAST TEGO TEKSU WSTAW KLASE CZLOWIEK
int main(int argc, char *argv[])
{
Czlowiek *jozek = [[Czlowiek alloc] init];
[jozek ustawNazwisko: @"panaNazwisko"];
[jozek ustawWiek: 25];
printf("%s ma %d lat.\n", [[jozek nazwisko] cString], [jozek wiek]);
[jozek ustawNazwisko: @"paniNazwisko" iWiek: 24];
printf("A %s ma %d lat.\n", [[jozek nazwisko] cString], [jozek wiek]);
[jozek release];
return 0;
}
Pozdrawiam.
*****************************************************************************************************
Ćwiczenie:
Stworzyć kilka klas oraz po kilka metod do nich razem z cechami.
Może to być: samochód, telewizor, mp3 itp itd;
Tylko pamiętajcie żeby dziedziczyć po NSObject.
POPRZEDNIE CZĘŚC KURSU:
01. Wprowadzenie
02. Konfiguracja i instalacja