Autor: 24.05.2023
Programowanie zorientowane obiektowo w C++ - przewodnik dla początkujących
Klasy i obiekty
Jak pewnie wiesz, w języku C++ mamy różne typy danych: string, int, bool itp. To są przykłady typów wbudowanych, dostępnych “od ręki”. Masz też możliwość tworzenia własnych typów.
Klasa to jest twój własny typ. Klasy zostały wymyślone po to, aby przenieść niektóre obiekty ze świata zewnętrznego do naszego kodu. Tak jak niektóre obiekty ze świata zewnętrznego, tak samo nasze klasy mają odpowiednie zachowania np. obiekt “pralka” potrafi: prać, płukać, wirować itp.
Spójrz na przykładową definicję klasy:
class WashingMachine {
};
Aby zdefiniować klasę musisz użyć słowa kluczowego class, następnie musisz nadać nazwę swojej klasie. Ciało klasy objęte jest nawiasami klamrowymi { i }. Pamiętaj, że definicję klasy zakańczamy średnikiem “;”.
Klasa jest dosłownie typem. Teraz zdefiniujemy własną zmienną używając int oraz klasy WashingMachine:
int operation;
WashingMachine amica;
Powyższy przykład przedstawia sposób użycia zmiennych o typach int oraz WashingMachine. Zmienna o nazwie amica jest konkretnym obiektem klasy WashingMachine.
Jaka jest różnica pomiędzy klasą a obiektem?
Definicja klasy jest przykładem szablonu projektu w fabryce, a obiekt to już jest gotowy produkt, który schodzi z linii produkcyjnej - w naszym przypadku będzie to pralka amica, która jest typu WashingMachine. Nic nie stoi na przeszkodzie aby utworzyć obiekt o innej nazwie, ale identycznym typie np:
WashingMachine whirlpool;
Pola klasy
Aby klasa była bardziej interaktywna, możemy dodawać do niej składniki. Składnikami mogą być na przykład zmienne. Przeanalizuj poniższy kod, znajdziesz tutaj wiele ciekawych informacji.
class WashingMachine {
public:
int programNumber;
int size;
private:
float engineSpeed;
protected:
string name;
};
Kod przedstawia klasę WashingMachine, które zawiera tzw. pola: programNumber, size, engineSpeed, name. Pola klasy to nic innego jak najzwyklejsze zmienne. Pola klasy możemy ustawiać odpowiednimi wartościami.
Modyfikatory dostępu
Zapewne dało się zauważyć, że w kodzie dostępne są etykiety: public, private, protected. Nie są one obowiązkowe- jeżeli nie umieścić ich w klasie wówczas takie pola domyślnie objęte będą etykietą private. Po co nam takie etykiety? Pozwalają nam one na ograniczanie bądź luzowanie dostępu do pól klasy. Jakie poziomy dostępów realizują etykiety?
- public - mamy dostęp z zewnątrz (np. możemy odwołać się do składnika z metody main().
- private - nie mamy dostępu z zewnątrz. Dostęp do takich pól może być zrealizowany z wnętrza klasy (np. możemy manipulować takimi polami za pomocą metod składowych klasy).
- protected - nie mamy dostępu z zewnątrz. Dostęp do takich pól będzie realizowany w klasach, które odziedziczą klasę WashingMachine.
Dostęp do składników klasy możemy realizować na kilka sposobów. W zależności od tego w jaki sposób zadeklarujemy obiekt naszej klasy WashingMachine. Spójrz na poniższy kod:
#include <iostream>
using namespace std;
class WashingMachine {
public:
int size;
};
int main() {
WashingMachine beko; // obiekt
WashingMachine *wsk; // wskaźnik
WashingMachine &ref = beko; // referencja
beko.size = 50;
wsk->size = 50;
ref.size = 50;
cout << beko.size << endl;
cout << wsk->size << endl;
cout << ref.size << endl;
return 0;
}
Dostęp do publicznych pól składowych klasy jest realizowany w następujący sposób:
SPOSÓB DEKLARACJI OBIEKTU | ODWOŁANIE SIĘ DO SKŁADOWEJ KLASY |
---|---|
Obiekt (beko) | Kropka - beko.size |
Wskaźnik (*wsk) | Strzałka - wsk->size |
Referencja (&ref) | Kropka - ref.size |
Konstruktor
Bardzo ważną rolę w programowaniu obiektowym pełni tzw. konstruktor. Konstruktor jest dosyć charakterystyczny. Posiada kilka cech za pomocą, których możesz go zaobserwować w kodzie. Konstruktor nie zwraca żadnej wartości oraz nazywa się identycznie jak klasa w której występuje. Oto przykład takiego konstruktora:
#include <iostream>
using namespace std;
class Car {
string name;
public:
Car(string mark) {
name = mark;
cout << "Działa konstruktor, ustawiam: " << name << endl;
}
};
int main() {
Car audi = Car("audi");
return 0;
}
Pole name jest prywatne, a konstruktor jest publiczny. Może on operować na prywatnych polach, i dokładnie to robi ustawiając składnik klasy. Oto rezultat działania programu:
Działa konstruktor, ustawiam: audi
Funkcje składowe klasy
Metoda składowa klasy Car została zaprezentowana w poniższym kodzie. Metoda składowa ma zasięg w całej klasie oraz ma dostęp do jej składowych i może na nich operować. Spójrz na definicję metody oraz jej użycie:
#include <iostream>
using namespace std;
class Car {
private:
string name;
public:
Car(string mark) {
name = mark;
}
string getName() {
return name;
}
};
int main() {
Car audi = Car("audi");
cout << audi.getName() << endl;
return 0;
}
Za pomocą konstruktora ustawiamy markę samochodu. Metoda getName() może operować na polach składowych klasy Car. Metoda jest publiczna, więc możemy wywołać ją z zewnątrz. Wynik naszego kodu wygląda tak:
audi
Podsumowanie
W artykule pokazaliśmy kluczowe pojęcia dotyczące programowania zorientowanego obiektowo w języku OOP. To jest dopiero początek możliwości, jakie oferuje ten język - Tema programowania obiektowego jest bardzo szeroki. Od czegoś trzeba zacząć - i po to właśnie przygotowaliśmy ten krótki artykuł.
Jeśli chcesz od podstaw poznać język C++ i zdobyć umiejętności potrzebne do pracy na stanowisku Junior C++ Developer, to zacznij naukę ze Ścieżką Kariery. Nauka kończy się egzaminem, który uprawnia cię do posługiwania się Certyfikatem Specjalisty.