r06.pdf
(
336 KB
)
Pobierz
Szablon dla tlumaczy
Rozdział 6.
Programowanie
zorientowane obiektowo
Klasy rozszerzają wbudowane w C++ możliwości, ułatwiające rozwiązywanie złożonych,
„rzeczywistych” problemów.
Z tego rozdziału dowiesz się:
•
czym są klasy i obiekty,
•
jak definiować nową klasę oraz tworzyć obiekty tej klasy,
•
czym są funkcje i dane składowe,
•
czym są konstruktory i jak z nich korzystać.
Czy C++ jest zorientowane obiektowo?
Język C++ stanowi pomost pomiędzy programowaniem zorientowanym obiektowo a językiem C,
najpopularniejszym językiem programowania aplikacji komercyjnych. Celem jego autorów było
stworzenie obiektowo zorientowanego języka dla tej szybkiej i efektywnej platformy.
Język C jest etapem pośrednim pomiędzy wysokopoziomowymi językami aplikacji „firmowych”,
takimi jak COBOL, a niskopoziomowym, wysokowydajnym, lecz trudnym do użycia asemblerem.
C wymusza programowanie „strukturalne”, w którym poszczególne zagadnienia są dzielone na
mniejsze jednostki powtarzalnych działań, zwanych funkcjami.
Programy, które piszemy na początku dwudziestego pierwszego wieku, są dużo bardziej złożone
niż te, które były pisane pod koniec wieku dwudziestego. Programy stworzone w językach
proceduralnych są trudne w zarządzaniu i konserwacji, a ich rozbudowa jest niemożliwa.
Graficzne interfejsy użytkownika, Internet, telefonia cyfrowa i bezprzewodowa oraz wiele innych
technologii, znacznie zwiększyły poziom skomplikowania nowych projektów, a wymagania
konsumentów dotyczące jakości interfejsu użytkownika wzrosły.
W obliczu rosnących wymagań, programiści bacznie przyjrzeli się przemysłowi informatycznemu.
Wnioski, do jakich doszli, były co najmniej przygnębiające. Oprogramowanie powstawało z
opóźnieniem, posiadało błędy, działało niestabilnie i było drogie. Projekty regularnie przekraczały
budżet i trafiały na rynek z opóźnieniem. Koszt obsługi tych projektów był znaczny, zmarnowano
ogromne ilości pieniędzy.
Jedynym wyjściem z tej sytuacji okazało się tworzenie oprogramowania zorientowanego
obiektowo. Języki programowania obiektowego stworzyły silne więzy pomiędzy strukturami
danych a metodami manipulowania tymi danymi. A co najważniejsze, w programowaniu
zorientowanym obiektowo nie już musisz myśleć o strukturach danych i manipulujących nimi
funkcjami; myślisz o obiektach. Rzeczach.
Świat jest wypełniony przedmiotami: samochodami, psami, drzewami, chmurami, kwiatami.
Rzeczy. Każda
rzecz
ma charakterystykę (szybki, przyjazny, brązowy, puszysty, ładny).
Większość rzeczy cechuje jakieś zachowanie (ruch, szczekanie, wzrost, deszcz, uwiąd). Nie
myślimy o danych psa i o tym, jak moglibyśmy nimi manipulować — myślimy o psie jako o
rzeczy: do czego jest podobny i co robi.
Tworzenie nowych typów
Poznałeś już kilka typów zmiennych, m.in. liczby całkowite i znaki. Typ zmiennej dostarcza nam
kilka informacji o niej. Na przykład, jeśli zadeklarujesz zmienne
Height
(wysokość) i
Width
(szerokość) jako liczby całkowite typu
unsigned short int
, wiesz, że w każdej z nich możesz
przechować wartość z przedziału od 0 do 65 535 (przy założeniu że typ
unsigned short int
zajmuje dwa bajty pamięci). Są to liczby całkowite bez znaku; próba przechowania w nich
czegokolwiek innego powoduje błąd. W zmiennej typu
unsigned short
nie możesz umieścić
swojego imienia, nie powinieneś nawet próbować.
Deklarując te zmienne jako
unsigned short int
, wiesz, że możesz dodać do siebie wysokość i
szerokość oraz przypisać tę wartość innej zmiennej.
Typ zmiennych informuje:
•
o ich rozmiarze w pamięci,
•
jaki rodzaj informacji mogą zawierać,
•
jakie działania można na nich wykonywać.
W tradycyjnych językach, takich jak C, typy były wbudowane w język. W C++ programista może
rozszerzyć język, tworząc potrzebne mu typy, zaś każdy z tych nowych typów może być w pełni
funkcjonalny i dysponować tą samą siłą, co typy wbudowane.
Po co tworzyć nowy typ?
Programy są zwykle pisane w celu rozwiązania jakiegoś realnego problemu, takiego jak
prowadzenie rejestru pracowników czy symulacja działania systemu grzewczego. Choć istnieje
możliwość rozwiązywania tych problemów za pomocą programów napisanych wyłącznie przy
użyciu liczb całkowitych i znaków, jednak w przypadku większych, bardziej rozbudowanych
problemów, dużo łatwiej jest stworzyć reprezentacje obiektów, o których się mówi. Innymi słowy,
symulowanie działania systemu grzewczego będzie łatwiejsze, gdy stworzymy zmienne
reprezentujące pomieszczenia, czujniki ciepła, termostaty i bojlery. Im bardziej te zmienne
odpowiadają rzeczywistości, tym łatwiejsze jest napisanie programu.
Klasy i składowe
Nowy typ zmiennych tworzy się, deklarując klasę. Klasa jest właściwie grupą zmiennych —
często o różnych typach — skojarzonych z zestawem odnoszących się do nich funkcji.
Jedną z możliwości myślenia o samochodzie jest potraktowanie go jako zbioru kół, drzwi, foteli,
okien, itd. Inna możliwość to wyobrażenie sobie, co samochód może zrobić: jeździć, przyspieszać,
zwalniać, zatrzymywać się, parkować, itd. Klasa umożliwia kapsułkowanie, czyli upakowanie,
tych różnych części oraz różnych działań w jeden zbiór, który jest nazywana obiektem.
Upakowanie wszystkiego, co wiesz o samochodzie, w jedną klasę przynosi programiście liczne
korzyści. Wszystko jest na miejscu, ułatwia to odwoływanie się, kopiowanie i manipulowanie
danymi. Klienty twojej klasy — tj. te części programu, które z niej korzystają — mogą używać
twojego obiektu bez zastanawiania się, co znajduje się w środku i jak on działa.
Klasa może składać się z dowolnej kombinacji zmiennych prostych oraz zmiennych innych klas.
Zmienna wewnątrz klasy jest nazywana zmienną składową lub daną składową. Klasa
Car
(samochód) może posiadać składowe reprezentujące siedzenia, typ radia, opony, itd.
Zmienne składowe są zmiennymi w danej klasie. Stanowią one część klasy, tak jak koła i silnik
stanowią część samochodu.
Funkcje w danej klasie zwykle manipulują zmiennymi składowymi. Funkcje klasy nazywa się
funkcjami składowymi lub metodami klasy. Metodami klasy
Car
mogą być
Start()
(uruchom)
oraz
Brake()
(hamuj). Klasa
Cat
(kot) może posiadać zmienne składowe, reprezentujące wiek i
wagę; jej metodami mogą być
Sleep()
(śpij),
Meow()
(miaucz) czy
ChaseMice()
(łap myszy).
Funkcje składowe (metody) są funkcjami w klasie. Podobnie jak zmienne składowe, stanowią
część klasy i określają, co dana klasa może zrobić.
Deklarowanie klasy
Aby zadeklarować klasę, użyj słowa kluczowego
class
, po którym następuje otwierający nawias
klamrowy, a następnie lista danych składowych i metod tej klasy. Deklaracja kończy się
zamykającym nawiasem klamrowym i średnikiem. Oto deklaracja klasy o nazwie
Cat
(kot):
class Cat
{
unsigned int itsAge;
unsigned int itsWeight;
void Meow();
};
Zadeklarowanie takiej klasy nie powoduje zaalokowania pamięci dla obiektu
Cat
. Informuje
jedynie kompilator, czym jest typ
Cat
, jakie dane zawiera (
itsAge
— jego wiek oraz
itsWeight
— jego waga) oraz co może robić (
Meow()
— miaucz). Informuje także kompilator, jak duża jest
zmienna typu
Cat
— to jest, jak dużo miejsca w pamięci ma przygotować w przypadku tworzenia
zmiennej typu
Cat
. W tym przykładzie, o ile typ
int
ma cztery bajty, zmienna typu
Cat
zajmuje
osiem bajtów: cztery bajty dla zmiennej
itsAge
i cztery dla zmiennej
itsWeight
. Funkcja
Meow()
nie zajmuje miejsca, gdyż dla funkcji składowych (metod) miejsce nie jest rezerwowane.
Kilka słów o konwencji nazw
Jako programista, musisz nazwać wszystkie swoje zmienne składowe, funkcje składowe oraz
klasy. Jak przeczytałeś w rozdziale 3., „Stałe i zmienne,” nazwy te powinny być zrozumiałe i
znaczące. Dobrymi nazwami klas mogą być wspomniana
Cat
,
Rectangle
(prostokąt) czy
Employee
(pracownik).
Meow()
,
ChaseMice()
czy
StopEngine()
(zatrzymaj silnik) również
są dobrymi nazwami funkcji, gdyż informują, co robią te funkcje. Wielu programistów nadaje
nazwom zmiennych składowych przedrostek „its” (jego), tak jak w zmiennych
itsAge
,
itsWeight
czy
itsSpeed
(jego szybkość). Pomaga to w odróżnieniu zmiennych składowych od
innych zmiennych.
Niektórzy programiści wolą przedrostek „my” (mój), tak jak w nazwach
myAge
,
myWeight
czy
mySpeed
. Jeszcze inni używają po prostu litery m (od słowa
member
— składowa), czasem wraz
ze znakiem podkreślenia (
_
):
mAge
i
m_age
,
mWeight
i
m_weight
czy
mSpeed
i
m_speed
.
Język C++ uwzględnia wielkość liter, dlatego wszystkie nazwy klas powinny przestrzegać tej
samej konwencji. Dzięki temu nigdy nie będziesz musiał sprawdzać pisowni nazwy klasy (czy to
było
Rectangle
,
rectangle
czy
RECTANGLE
?).
Niektórzy programiści lubią poprzedzić każdą nazwę klasy określoną literą — na przykład
cCat
czy
cPerson
— podczas, gdy inni używają wyłącznie dużych lub małych liter. Ja sam korzystam
z konwencji, w której wszystkie nazwy klas rozpoczynają się od dużej litery, tak jak
Cat
czy
Person
(osoba).
Wielu programistów rozpoczyna wszystkie nazwy funkcji od dużej litery, zaś wszystkie nazwy
zmiennych — od małej. Słowa zwykle rozdzielane są znakiem podkreślenia — tak jak w
Chase_Mice
— lub poprzez zastosowanie dużej litery dla każdego słowa — na przykład
ChaseMice
czy
DrawCircle
(rysuj okrąg).
Ważne jest, by wybrać określony styl i trzymać się go w każdym programie. Z czasem rozwiniesz
swój styl nie tylko na konwencje nazw, ale także na wcięcia, wyrównanie nawiasów klamrowych
oraz styl komentarzy.
UWAGA W firmach programistycznych powszechne jest określenie standardu wielu elementów
stylu zapisu kodu źródłowego. Sprawia on, że wszyscy programiści mogą łatwo odczytywać
wzajemnie swój kod.
Definiowanie obiektu
Definiowanie obiektu nowego typu przypomina definiowanie zmiennej całkowitej:
unsigned int GrossWeight; // definicja zmiennej typu unsigned int
Cat Mruczek; // definicja zmiennej typu Cat
Ten kod definiuje zmienną o nazwie
GrossWeight
(łączna waga), której typem jest
unsigned
int
. Oprócz tego definiuje zmienną o nazwie
Mruczek
, która jest obiektem klasy (typu)
Cat
.
Klasy a obiekty
Nigdy nie karmi się definicji kota, lecz konkretnego kota. Należy dokonać rozróżnienia pomiędzy
ideą kota a konkretnym kotem, który właśnie ociera się o twoje nogi. C++ również dokonuje
rozróżnienia pomiędzy klasą
Cat
, będącą ideą kota, a poszczególnymi obiektami typu
Cat
. Tak
więc
Mruczek
jest obiektem typu
Cat
, tak jak
GrossWeight
jest zmienną typu
unsigned int
.
Obiekt jest indywidualnym egzemplarzem klasy.
Dostęp do składowych klasy
Gdy zdefiniujesz już faktyczny obiekt
Cat
— na przykład
Mruczek
— w celu uzyskania dostępu
do jego składowych możesz użyć operatora kropki (
.
). Aby zmiennej składowej
itsWeight
obiektu
Mruczek
przypisać wartość
50
, powinieneś napisać:
Mruczek.itsWeight = 50;
Aby wywołać funkcję
Meow()
, możesz napisać:
Mruczek.Meow();
Gdy używasz metody klasy, oznacza to, że wywołujesz tę metodę. W tym przykładzie wywołałeś
metodę
Meow()
obiektu
Mruczek
.
Przypisywać należy obiektom, nie klasom
W C++ nie przypisuje się wartości typom; przypisuje się je zmiennym. Na przykład, nie można
napisać:
int = 5; // źle
Kompilator uzna to za błąd, gdyż nie można przypisać wartości pięć typowi całkowitemu. Zamiast
tego musisz zdefiniować zmienną typu całkowitego i przypisać jej wartość
5
. Na przykład:
Plik z chomika:
Wojteczek
Inne pliki z tego folderu:
rdodc.pdf
(84 KB)
rdodb.pdf
(72 KB)
rdoda.pdf
(184 KB)
r21.pdf
(370 KB)
r20.pdf
(275 KB)
Inne foldery tego chomika:
Cisco
Kurs C++ od zera do hackera v. 1.0
Pascal
ZAHASŁOWANE
Zgłoś jeśli
naruszono regulamin