← Lekcje
Języki obok siebie · lekcja 03

Klasy i obiekty w trzech językach

  1. Klasa to foremka, obiekt to ciastko
  2. Jedna klasa Product, trzy zapisy: pola, konstruktor, metoda
  3. Ściąga na jednej kartce, do przepisania
  4. Ćwiczenie: klasa Student ze średnią ocen
Rozgrzewka · 3 minuty

Co zostało z list i słowników?

  1. Jak zapiszecie listę trzech ocen w języku, który znacie?
  2. Czym słownik różni się od listy?
  3. Jak przejść po wszystkich elementach listy?
Część 1 · Po co klasa

Klasa to foremka, obiekt to ciastko

KLASA Product foremka: opis pola: name, price jedna na cały program tworzymy OBIEKT name: „Zeszyt”, price: 12 OBIEKT name: „Plecak”, price: 180 OBIEKT name: „Długopis”, price: 4

Na poprzedniej lekcji słownik trzymał same dane: nazwę i cenę. Klasa trzyma dane i czynności, które się na nich wykonuje, na przykład policzenie ceny z podatkiem. Dlatego obiekt umie coś zrobić, a słownik tylko leży.

php.net: Language Reference › Classes and Objects › The Basics · docs.python.org: tutorial 9.3 „A First Look at Classes” · MDN: Web/JavaScript/Guide/Using_classes
Część 1 · Definicja klasy

Ta sama klasa w trzech zapisach

PHP

class Product {
  public $name;
  public $price;

  public function __construct($name, $price) {
    $this->name = $name;
    $this->price = $price;
  }
}

Python

class Product:

    def __init__(self, name, price):
        self.name = name
        self.price = price

JavaScript

class Product {

  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}

Słowo class i nazwa wielką literą są wszędzie takie same. Różni się nazwa konstruktora, czyli czynności, która ustawia dane nowego obiektu: __construct, __init__, constructor. W PHP pola trzeba jeszcze zapowiedzieć na górze klasy, w Pythonie i JavaScripcie powstają same w konstruktorze.

php.net: Language Reference › Classes and Objects › Properties · Constructors and Destructors · docs.python.org: tutorial 9.3.1 „Class Definition Syntax” · MDN: Web/JavaScript/Reference/Classes/constructor
Część 2 · Słowo „ja”

Skąd obiekt wie, że chodzi o niego?

CoPHPPythonJavaScript
słowo „ja”$thisselfthis
pole tego obiektu$this->priceself.pricethis.price
czy stoi w nawiasienie, jest z automatutak, zawsze pierwszynie, jest z automatu
public function __construct($price) {
  $this->price = $price;
}
def __init__(self, price):
    self.price = price
constructor(price) {
  this.price = price;
}

Zadanie jest jedno: odróżnić pole obiektu od zwykłej zmiennej o tej samej nazwie. Python robi to jawnie i każe wpisać self na początku listy parametrów każdej metody. PHP i JavaScript podstawiają swoje słowo same.

php.net: Language Reference › Classes and Objects › The Basics · docs.python.org: tutorial 9.3.3 „Instance Objects” i 9.3.4 „Method Objects” · MDN: Web/JavaScript/Reference/Operators/this
Część 2 · Tworzenie obiektu

Dwa obiekty, dwa osobne komplety danych

PHP

$book = new Product("Zeszyt", 12);
$bag = new Product("Plecak", 180);

echo $book->name;
echo $bag->price;

Python

book = Product("Zeszyt", 12)
bag = Product("Plecak", 180)

print(book.name)
print(bag.price)

JavaScript

const book = new Product("Zeszyt", 12);
const bag = new Product("Plecak", 180);

console.log(book.name);
console.log(bag.price);
book name: „Zeszyt” · price: 12 bag name: „Plecak” · price: 180 osobno

Słowo new jest w PHP i JavaScripcie, w Pythonie nie ma go wcale. Do pola PHP sięga strzałką ->, Python i JavaScript kropką. Każdy obiekt ma własny komplet pól, więc zmiana ceny plecaka nie rusza zeszytu.

php.net: Language Reference › Classes and Objects › The Basics · docs.python.org: tutorial 9.3.2 „Class Objects” · MDN: Web/JavaScript/Reference/Operators/new
Część 3 · Metoda

Metoda: funkcja w środku klasy

PHP

public function priceWithTax() {
  return $this->price * 1.23;
}

echo $book->priceWithTax();

Python

def price_with_tax(self):
    return self.price * 1.23

print(book.price_with_tax())

JavaScript

priceWithTax() {
  return this.price * 1.23;
}

console.log(book.priceWithTax());
pole price: 12 metoda: razy 1,23 wynik: 14,76

Wszędzie tak samo: żadnego parametru w nawiasie, cenę metoda bierze ze słowa „ja”, wynik oddaje przez return. Różni się nazwa: PHP i JavaScript piszą priceWithTax, Python price_with_tax. To nie kaprys, to konwencja każdego z tych języków.

php.net: Language Reference › Classes and Objects › The Basics · docs.python.org: tutorial 9.3.4 „Method Objects” · PEP 8 „Function and Variable Names” · MDN: Web/JavaScript/Reference/Functions/Method_definitions
Część 3 · Pola schowane

Pole tylko dla wnętrza klasy

JęzykZapisCo się stanie z zewnątrz
PHPprivate $price;program zatrzymuje się z błędem
JavaScript#price;kod się nie uruchomi, błąd składni
Pythonself._pricezadziała, to tylko umowa między programistami

Dwa języki pilnują tego za Was, trzeci liczy na Waszą uczciwość. Podkreślnik w Pythonie mówi: „to jest wnętrze klasy, nie ruszaj z zewnątrz”. Nic go nie wymusza, ale każdy programista Pythona tę umowę zna.

php.net: Language Reference › Classes and Objects › Visibility · docs.python.org: tutorial 9.6 „Private Variables” · MDN: Web/JavaScript/Reference/Classes/Private_elements
Ściąga · do zeszytu

Jedna tabela na trzy języki

CoPHPPythonJavaScript
klasaclass Product { }class Product:class Product { }
zapowiedź polapublic $price;niepotrzebnaniepotrzebna
konstruktor__construct($price)__init__(self, price)constructor(price)
słowo „ja”$this->priceself.pricethis.price
nowy obiektnew Product(12)Product(12)new Product(12)
pole obiektu$book->pricebook.pricebook.price
nazwa metodypriceWithTax()price_with_tax(self)priceWithTax()
wywołanie metody$book->priceWithTax()book.price_with_tax()book.priceWithTax()
pole schowaneprivate $price;self._price (umowa)#price;
php.net: Language Reference › Classes and Objects · docs.python.org: tutorial 9.3 i 9.6 · MDN: Web/JavaScript/Reference/Classes
Ćwiczenie · na kartce · 12 minut

Klasa Student ze średnią

Po prawej masz klasę Student w Pythonie. Trzyma imię i listę ocen, a metoda liczy średnią. Przepisz ją, nazw nie zmieniaj.

  1. Przepisz tę klasę na JavaScript.
  2. Przepisz tę klasę na PHP.
  3. Dla chętnych: dopisz metodę, która mówi, czy średnia sięga 3.

Zanim oddasz kartkę, sprawdź cztery rzeczy: słowo class i nazwa wielką literą, konstruktor pod właściwą nazwą, słowo „ja” przy każdym polu, metoda z return. W PHP dopisz jeszcze zapowiedź pól i pamiętaj o strzałce zamiast kropki.

Klasa w Pythonie

class Student:

    def __init__(self, name, grades):
        self.name = name
        self.grades = grades

    def average(self):
        return sum(self.grades) / len(self.grades)

student = Student("Ala", [3, 4, 5])
print(student.name)
print(student.average())
Sprawdzenie

Trzy pytania na koniec

  1. Czym klasa różni się od obiektu?
  2. W którym z trzech języków słowo „ja” stoi jawnie w nawiasie metody?
  3. Jak sięgacie do pola obiektu w PHP, a jak w dwóch pozostałych?
Podsumowanie

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
klasa ProductW sklepie internetowym osobne klasy opisują produkt, koszyk, zamówienie i klientacodziennie
metoda z wynikiemCena z podatkiem, rabat, koszt wysyłki: każda liczba ma swoją metodęcodziennie
pole schowaneHasło i numer karty siedzą w polach prywatnych, żeby nikt nie nadpisał ich z zewnątrzstandard
dziedziczenieKlasa bierze pola i metody od innej: extends Base w PHP i JavaScripcie, class Vip(Client): w Pythoniena następnej lekcji

Ciekawostka: słowo class weszło do JavaScriptu dopiero w wersji ES2015. Obiekty były w tym języku od początku, tylko opisywało się je inaczej, przez prototypy. Zapis z klasą jest wygodniejszą nakładką na ten sam mechanizm.

ciekawostka: MDN: Web/JavaScript/Reference/Classes · php.net: Language Reference › Classes and Objects › Object Inheritance · docs.python.org: tutorial 9.5 „Inheritance”