Co to jest klasa?
Klasa to jeden z podstawowych elementów programowania obiektowego. Można ją uznać za szablon, który definiuje strukturę oraz zachowanie obiektów.
Obiekty to instancje klas, czyli konkretne realizacje tego szablonu.
Struktura klasy
class Student {
// POLA (zmienne) - przechowują dane
imie: string;
nazwisko: string;
indeks: number;
// KONSTRUKTOR - inicjalizuje obiekt
constructor(imie: string, nazwisko: string, indeks: number) {
this.imie = imie;
this.nazwisko = nazwisko;
this.indeks = indeks;
}
// METODY - opisują działania
przedstawSie(): void {
console.log(`Jestem ${this.imie} ${this.nazwisko}`);
}
getIndeks(): number {
return this.indeks;
}
}Pola (Atrybuty)
Pola to zmienne należące do klasy. Każdy obiekt ma własne kopie pól.
class Auto {
marka: string; // pole type string
model: string; // pole type string
rocznik: number; // pole type number
przebieg: number; // pole type number
}Konstruktor
Konstruktor to specjalna metoda wywoływana automatycznie przy tworzeniu obiektu.
class Auto {
marka: string;
model: string;
rocznik: number;
// Konstruktor
constructor(marka: string, model: string, rocznik: number) {
this.marka = marka;
this.model = model;
this.rocznik = rocznik;
}
}Czym jest this?
this odnosi się do konkretnego obiektu. this.marka = pole marka tego obiektu.
// ❌ BŁĄD - nie przypisuje do pola
constructor(marka: string) {
marka = marka;
}
// ✅ POPRAWNIE - przypisuje do pola
constructor(marka: string) {
this.marka = marka;
}Metody
Metody to funkcje należące do klasy. Opisują, co obiekt potrafi robić.
class Kalkulator {
dodaj(a: number, b: number): number {
return a + b;
}
odejmij(a: number, b: number): number {
return a - b;
}
wyswietlInfo(): void {
console.log("To jest kalkulator");
}
}Tworzenie i używanie obiektów
Składnia
const <zmienna> = new <Klasa>(<argumenty>);Przykład
class Pojazd {
marka: string;
model: string;
rocznik: number;
constructor(marka: string, model: string, rocznik: number) {
this.marka = marka;
this.model = model;
this.rocznik = rocznik;
}
wyswietlInfo(): void {
console.log(`${this.marka} ${this.model} z ${this.rocznik} roku`);
}
sprzedaj(): void {
console.log(`${this.marka} ${this.model} została sprzedana`);
}
}
// Tworzenie obiektu
const pojazd1 = new Pojazd("Skoda", "Fabia", 2020);
pojazd1.wyswietlInfo(); // Skoda Fabia z 2020 roku
pojazd1.sprzedaj(); // Skoda Fabia została sprzedana
// Inny obiekt
const pojazd2 = new Pojazd("Toyota", "Corolla", 2022);
pojazd2.wyswietlInfo(); // Toyota Corolla z 2022 rokuWażne: Każdy obiekt ma swoje własne pola!
Modyfikatory dostępu
Czym są modyfikatory dostępu?
Modyfikatory dostępu kontrolują, skąd można odczytywać i zmieniać pola/metody klasy.
Trzy Główne Modyfikatory
public (domyślnie)
Dostęp z wszędzie – z innej klasy, z innego pliku, z globalnego zakresu.
class Osoba {
public imie: string; // Dostęp z wszędzie
public przedstawSie(): void {
console.log(`Jestem ${this.imie}`);
}
}
const osoba = new Osoba();
osoba.imie = "Jan"; // ✅ OK - zmienić z zewnątrz
osoba.przedstawSie(); // ✅ OK - wywołać z zewnątrz
console.log(osoba.imie); // ✅ OK - odczytać z zewnątrzprivate
Dostęp tylko wewnątrz klasy, z innego miejsca – brak dostępu.
class Konto {
private saldo: number; // Tylko wewnątrz klasy!
constructor(saldo: number) {
this.saldo = saldo;
}
// Metoda wewnątrz klasy - MOŻE uzyskać dostęp
wypłać(kwota: number): void {
if (kwota <= this.saldo) {
this.saldo -= kwota;
console.log(`Wypłacono ${kwota} zł`);
}
}
}
const konto = new Konto(1000);
konto.wypłać(100); // ✅ OK - metoda publiczna
// konto.saldo = 5000; // ❌ BŁĄD - saldo to private!
// console.log(konto.saldo); // ❌ BŁĄD - nie mogę uzyskać dostępuDlaczego private?
- Bezpieczeństwo – nikt nie może zmienić saldo wprost
- Kontrola – zmiana tylko przez publiczne metody
- Logika biznesowa – np. nie można mieć ujemnego salda
protected (zaawansowane)
Dostęp wewnątrz klasy. (Będzie ważne z dziedziczeniem w przyszłości)
class Osoba {
protected wiek: number; // Dostęp w Osoba, ale nie z zewnątrz
constructor(wiek: number) {
this.wiek = wiek;
}
}
const osoba = new Osoba(25);
// osoba.wiek = 30; // ❌ BŁĄD - protectedPorównanie
class Pracownik {
public imie: string; // Wszyscy mogą czytać i zmieniać
private wynagrodzenie: number; // Tylko Pracownik zna wynagrodzenie
protected stanowisko: string; // Dostęp w klasie
constructor(imie: string, wynagrodzenie: number, stanowisko: string) {
this.imie = imie;
this.wynagrodzenie = wynagrodzenie;
this.stanowisko = stanowisko;
}
// Metoda publiczna - każdy może wywołać
pracuj(): void {
console.log(`${this.imie} pracuje`);
}
// Metoda prywatna - tylko wewnątrz klasy
private obliczBonusDoWynagrodzeina(): number {
return this.wynagrodzenie * 0.1;
}
}GETTER I SETTER – dostęp do prywatnych pól
Problem
Pola private nie mogą być dostępne z zewnątrz, ale czasami chcemy udostępnić dostęp kontrolowany.
Rozwiązanie: Getter i Setter
Getter (pobieranie wartości)
class Konto {
private saldo: number;
constructor(saldo: number) {
this.saldo = saldo;
}
// Getter - pobiera wartość
get getSaldo(): number {
return this.saldo;
}
}
const konto = new Konto(1000);
console.log(konto.getSaldo); // 1000 (bez nawiasów!)Setter (przypisywanie wartości)
class Osoba {
private wiek: number;
constructor(wiek: number) {
this.wiek = wiek;
}
// Setter - ustawia wartość z walidacją
set setWiek(nowyWiek: number) {
if (nowyWiek > 0 && nowyWiek < 150) {
this.wiek = nowyWiek;
} else {
console.log("Nieprawidłowy wiek!");
}
}
// Getter - pobiera wartość
get getWiek(): number {
return this.wiek;
}
}
const osoba = new Osoba(25);
osoba.setWiek = 30; // ✅ OK - setter
console.log(osoba.getWiek); // 30 - getter
osoba.setWiek = 200; // ❌ Nieprawidłowy wiek!Praktyczny Przykład
class Produktu {
private nazwa: string;
private cena: number;
constructor(nazwa: string, cena: number) {
this.nazwa = nazwa;
this.cena = cena;
}
// Getter dla ceny
get getCena(): number {
return this.cena;
}
// Setter dla ceny ze zniżką
set setCenaZeZnizka(procentZnizki: number) {
if (procentZnizki > 0 && procentZnizki < 100) {
this.cena = this.cena * (1 - procentZnizki / 100);
}
}
// Getter dla nazwy
get getNazwa(): string {
return this.nazwa;
}
}
const produkt = new Produktu("Laptop", 3000);
console.log(produkt.getCena); // 3000
produkt.setCenaZeZnizka = 10; // 10% zniżki
console.log(produkt.getCena); // 2700Modyfikatory dostępu – porady
Reguła Złota
❌ Nie rób nic public jeśli nie musi być
✅ Domyślnie rób private
✅ Udostępnij przez gettery/settery jeśli potrzebaPrzykład: Budowanie Klasy
// ZŁYLE - wszystko public
class ZleKonto {
public saldo: number = 1000;
}
const zlekonto = new ZleKonto();
zlekonto.saldo = -9999; // 😱 Ujemne saldo!
// DOBRZE - saldo private, dostęp przez getter
class DobreKonto {
private saldo: number = 1000;
// Getter - tylko do odczytania
get Saldo(): number {
return this.saldo;
}
// Metoda publiczna - kontrolowana zmiana
wyplac(kwota: number): boolean {
if (kwota > 0 && kwota <= this.saldo) {
this.saldo -= kwota;
return true;
}
return false;
}
}Organizacja kodu – klasy w osobnych plikach
Problem: Wszystko w Jednym Pliku
Jeśli cały kod jest w jednym pliku – chaos!
app.ts (1000+ linii)
├─ Klasa Student
├─ Klasa Nauczyciel
├─ Klasa Szkoła
├─ Kod główny
└─ ... wszystko razemRozwiązanie: Klasy w Osobnych Plikach
src/
├─ models/
│ ├─ Student.ts
│ ├─ Nauczyciel.ts
│ └─ Szkoła.ts
├─ utils/
│ └─ helpers.ts
└─ app.ts (główny plik)Krok 1: Stwórz Plik dla Klasy
Plik: src/models/Student.ts
export class Student {
private imie: string;
private nazwisko: string;
private indeks: number;
constructor(imie: string, nazwisko: string, indeks: number) {
this.imie = imie;
this.nazwisko = nazwisko;
this.indeks = indeks;
}
get Imie(): string {
return this.imie;
}
przedstawSie(): void {
console.log(`Jestem ${this.imie} ${this.nazwisko}`);
}
}Ważne: export – pozwala innym plikom używać tej klasy!
Krok 2: Zaimportuj Klasę
Plik: src/app.ts
import { Student } from './models/Student';
// Teraz możesz używać Student
const student = new Student("Jan", "Kowalski", 123456);
student.przedstawSie();
console.log(student.Imie);Import: import { Student } from './models/Student';
Zadania:
ZADANIE 1: Klasa Osoba
Stwórz klasę Osoba z:
- Polami private: imie, nazwisko, wiek
- Konstruktorem
- Getterami dla wszystkich pól
- Setterem dla wieku z walidacją (0-120)
- Metodą
predstavSie()– wypisuje „Jestem [imie] [nazwisko]”
ZADANIE 2: Klasa Kalkulator
Stwórz klasę Kalkulator z metodami:
dodaj(a, b): numberodejmij(a, b): numberpomnoz(a, b): numberpodziel(a, b): number(sprawdź dzielenie przez 0)potega(a, b): number
ZADANIE 3: Klasa Auto
Stwórz klasę Auto z:
- Polami private: marka, model, rocznik, przebieg
- Konstruktorem
- Getterami dla wszystkich pól
- Metodą
jazda(km: number)– zwiększa przebieg - Metodą
wyswietlInfo()– wypisuje dane auta
ZADANIE 4: Projekt w Osobnych Plikach
Stwórz projekt z npm init:
- Klasa
Studentwsrc/models/Student.ts - Klasa
Nauczycielwsrc/models/Nauczyciel.ts - Główny plik
src/app.ts - Kompiluj i uruchamiaj
ZADANIE 5: System Biblioteczny
Stwórz klasy:
Ksiazka(titulo, autor, rok, dostępna)Uzytkownik(imie, nazwisko, wypożyczone)- Metody:
wypożycz(),zwróć(),wyswietlInfo()