PHP – obiektowo


Programowanie obiektowe – OOP (object-oriented programming) – pozwala na przedstawienie rzeczywistości i relacji w niej zachodzących za pomocą obiektów.

Klasa i obiekt

Kiedy mówimy o klasie musimy wyobrazić ją sobie jak ogólny zarys/opis jakiegoś obiektu, zbiór cech wspólnych dla np. człowieka. Gdybyśmy mieli klasę człowiek moglibyśmy określić ogólne cechy jakie definiują ludzi, czyli np. to że śpi, że ma głos, oczy, włosy, ręce, nogi itd.

Obiekt jest instancją danej klasy, czyli konkretnym człowiekiem np. Janem Kowalskim, który ma brązowe włosy, jest typem „skowronka” i ma niebieskie oczy. Te cechy nie są bezpośrednio związane z klasą, a z obiektem (instancją/wystąpieniem klasy).

Można powiedzieć, że Jan Kowalski jest zmienną typu klasy, czyli obiektem typu człowiek.

Przykład utworzenia klasy:

<?php
//tworzymy klasę człowiek
class Czlowiek {

  public $kolorOczu;
  public $kolorWlosow;
  public $wiek;

}
?>

Mając tak zdefiniowana klasę możemy otworzyć konkretny obiekt:

<?php

$czlowiek_1 = new Czlowiek(); //tworzymy nowy obiekt klasy Czlowiek

//nadajemy konkretne cechy
$czlowiek_1 -> kolorOczu = 'brązowe'; 
$czlowiek_1 -> kolorWlosow = 'brązowe';
$czlowiek_1 -> wiek = 17;

//wyświetlamy rezultaty
echo 'Osoba 1 ma '.$czlowiek_1 -> kolorOczu . ' oczy, ' . $czlowiek_1 -> kolorWlosow . ', włosy i ma lat ' . $czlowiek_1 -> wiek;

// Osoba 1 ma brązowe oczy, brązowe, włosy i ma lat 17

?>

Możemy wyświetlić sobie stworzony obiekt:

<?php
  echo '<pre>';
  print_r($czlowiek_1);
  echo '</pre>';
?>
wyświetli się:
Czlowiek Object
(
    [kolorOczu] => brązowe
    [kolorWlosow] => brązowe
    [wiek] => 17
)

Klasie możemy nadać domyślne wartości, które zostaną nadane w momencie tworzenia obiektu:

<?php

class Czlowiek {

  public $kolorOczu;
  public $kolorWlosow;
  public $wiek=17; //nadajemy wartość domyślną

}

$czlowiek_1 = new Czlowiek(); //tworzymy nowy obiekt klasy Czlowiek

//nadajemy konkretne cechy
$czlowiek_1 -> kolorOczu = 'brązowe'; 
$czlowiek_1 -> kolorWlosow = 'brązowe';

//wyświetlamy rezultaty
echo 'Osoba 1 ma '.$czlowiek_1 -> kolorOczu . ' oczy, ' . $czlowiek_1 -> kolorWlosow . ', włosy i ma lat ' . $czlowiek_1 -> wiek;

// Osoba 1 ma brązowe oczy, brązowe, włosy i ma lat 17
?>

Już potrafisz:

  • stworzyć definicję obiektu w postaci klasy
  • dodać publiczne pola do klasy i nadawać im wartości domyślne
  • przypisywać im wartości
  • odczytywać ich wartość
  • korzystać z „->”, by dostać się do pola klasy

Metody

Klasa może definiować metody, czyli nic innego jak funkcje z podejścia proceduralnego. Kiedy tworzymy obiekt nadajemy mu dostęp do metod danej klasy.

Trochę praktyki:

<?php

class Czlowiek {

  public $kolorOczu;
  public $kolorWlosow;
  public $wiek=17; //nadajemy wartość domyślną

//teraz tworzymy metodę
  public function pobierzWiek() {
    return $this->wiek;
  }

}

$czlowiek_1 = new Czlowiek();
$czlowiek_1 -> wiek=16;

$czlowiek_2 = new Czlowiek();
$czlowiek_2 -> wiek=18;

$czlowiek_3 = new Czlowiek();


echo '<pre>';
print_r($czlowiek_1);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_1 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_2);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_2 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_3);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_3 -> pobierzWiek().'<br>';
?>

Zostanie wyświetlone:
Czlowiek Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => 16
)

Pobrany wiek to: 16

Czlowiek Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => 18
)

Pobrany wiek to: 18

Czlowiek Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => 17
)

Pobrany wiek to: 17

Aby dostać się do konkretnego pola w obiekcie, korzystamy ze zmiennej $this.

W powyższym przykładzie nadawaliśmy wiek odnosząc się bezpośrednio do pola klasy. Nie jest to dobra metoda, ponieważ użytkownik może wpisać co chce w dane pole i niestety skrypt może się „wysypać”. Aby tego uniknąć dodajemy dane za pomocą metody, którą możemy łatwo zabezpieczyć przed niechcianym kodem.

Powyższy kod powinien wyglądać następująco:

<?php

  class Czlowiek {

  public $kolorOczu;
  public $kolorWlosow;
  public $wiek=17; //nadajemy wartość domyślną

//teraz tworzymy metodę
  public function pobierzWiek() {
    return $this->wiek;
  }
  
  public function przypiszWiek($wiek) {
    $this->wiek = $wiek; //można dodać tutaj sprawdzanie czy wprowadzona wartość jest int i mieści się w określonym przedziale
  }

}

$czlowiek_1 = new Czlowiek();
$czlowiek_1->przypiszWiek(16);

$czlowiek_2 = new Czlowiek();
$czlowiek_2->przypiszWiek(18);

$czlowiek_3 = new Czlowiek();


echo '<pre>';
print_r($czlowiek_1);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_1 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_2);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_2 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_3);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_3 -> pobierzWiek().'<br>';
?>

A teraz przykład z walidacją wieku:

<?php
class Czlowiek_przyklad {

  public $kolorOczu;
  public $kolorWlosow;
  public $wiek='wiek nieznany'; //nadajemy wartość domyślną

//teraz tworzymy metodę
  public function pobierzWiek() {
    return $this->wiek;
  }
  
  public function przypiszWiek($wiek) {
	$wiek = intval($wiek);//sprawdzanie czy wprowadzona wartość jest int i mieści się w określonym przedziale
    if ($wiek > 0 && $wiek < 120)
    $this->wiek = $wiek; 
  }

}

$czlowiek_1 = new Czlowiek_przyklad();
$czlowiek_1->przypiszWiek('sdf');

$czlowiek_2 = new Czlowiek_przyklad();
$czlowiek_2->przypiszWiek(18);

$czlowiek_3 = new Czlowiek_przyklad();


echo '<pre>';
print_r($czlowiek_1);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_1 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_2);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_2 -> pobierzWiek().'<br>';

echo '<pre>';
print_r($czlowiek_3);
echo '</pre>';

echo 'Pobrany wiek to: '.$czlowiek_3 -> pobierzWiek().'<br>';
?>

Wyświetli się:
Czlowiek_przyklad5 Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => wiek nieznany
)

Pobrany wiek to: wiek nieznany

Czlowiek_przyklad5 Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => 18
)

Pobrany wiek to: 18

Czlowiek_przyklad5 Object
(
    [kolorOczu] => 
    [kolorWlosow] => 
    [wiek] => wiek nieznany
)

Pobrany wiek to: wiek nieznany

Już potrafisz:

  • stworzyć metodę klasy
  • zwrócić wartość i przekazać argumenty
  • korzystać ze zmiennej $this
  • zabezpieczyć dane

Modyfikatory dostępu

Do tej pory wykonywaliśmy przykłady w oparciu o publiczną dostępność danego elementu, czyli public. Taka metoda lub właściwość jest publiczna, więc widoczna wszędzie wewnątrz obiektu i poza nim. Dostęp do pola jest nieograniczony i można je odczytywać i zmieniać dowolnie.

Właściwość lub metoda może być prywatna, czyli private, wówczas może zostać użyta tylko wewnątrz obiektu.

Właściwość lub metoda protected może być użyta tylko wewnątrz obiektu, ale może być również dziedziczona.

Zaleca się w programowaniu i w życiu, nie udostępniać zbyt wiele informacji na zewnątrz, więc tego się trzymajmy – korzystamy z modyfikatorów private.

Ale trochę praktyki:

<?php

class Szkola {
  public $czyZamknieta = true;

  public function otworz() {
    $this->czyZamknieta = false;
  }

  public function zamknij() {
    $this->czyZamknieta = true;
  }

  public function sprawdzCzyZamknieta() {
    return $this->czyZamknieta;
  }
}
$szkola = new Szkola();
$szkola->zamknij();
$szkola->czyZamknieta = false; //zmieniamy wartość parametru
echo $szkola->sprawdzCzyZamknieta() ? 'szkoła zakmnięta' : 'szkoła otwarta';

?>

//wyświetli szkoła otwarta

W powyższym przykładzie należy zwrócić uwagę na to, że pomimo iż ostatnią operacją na obiekcie było zamknięcie szkoły, wprowadzenie bezpośredniej zmiany pola $szkola->czyZamknieta na false, sprawiło że otrzymujemy informację, że szkoła jest otwarta. Możemy tego uniknąć blokując dostęp do pól i metod klasy, czyli zmieniając ich modyfikatory z publicznych na prywatne.

Ustawiamy wartość prywatną:

class Szkola_przyklad2 {
  private $czyZamknieta = true; //modyfikator prywatny, brak dostępu z zewnątrz

  public function otworz() {
    $this->czyZamknieta = false;
  }

  public function zamknij() {
    $this->czyZamknieta = true;
  }

  public function sprawdzCzyZamknieta() {
    return $this->czyZamknieta;
  }
}
$szkola = new Szkola_przyklad2();
$szkola->zamknij();
$szkola->czyZamknieta = false; //chcemy zmienić wartość parametru

//tutaj interpreter zwróci błąd, gdyż nie ma dostępu do zmiennej

echo $szkola->sprawdzCzyZamknieta() ? 'szkoła zakmnięta' : 'szkoła otwarta';

Przykład powyższy generuje błąd, ponieważ nie ma dostępu do prywatnej wartości pola klasy.

Ustawimy teraz metody na prywatne i publiczne:

<?php
class Kolo {
  private $promien=5;
  private function obliczSrednice() {
    return $this->promien * 2 * pi();
  }	
  public function czySieZmiesci($patyk) {
    return $this->obliczSrednice() > $patyk ? 'TAK' : 'NIE';
  }
}
$csz = new Kolo();

echo '<pre>';
print_r($csz);
echo '</pre>';

echo $csz->czySieZmiesci(5);
//wyświetli TAK
echo $csz->czySieZmiesci(40);
//wyświetli NIE
echo $csz->obliczSrednice(); //tutaj interpreter zwróci błąd, gdyż nie ma dostępu do metody
?>

O modyfikatorze protected, trochę później – przy temacie dziedziczenie.

Już potrafisz:

  • ograniczać dostęp do pól klasy i metod
  • pozwalać klasie bazowej oraz klasom dziedziczącym na modyfikację pola lub metody

Dziedziczenie

Tak jak w życiu – jako potomkowie dziedziczymy po naszych przodkach pewne cechy (tak naprawdę to 50% od matki i 50% od ojca), tak samo klasy dziedziczą pola i metody, ale mogą zostać uzupełnione o inne elementy, których przodek nie posiada.

Jeżeli klasa przodka posiada pola i metody, które nie są prywatne, to klasa potomna również będzie je posiadać.

Klasa może dziedziczyć tylko po jednej klasie 
(rozszerzać tylko jedną klasę bazową )

Aby klasa dziedziczyła po innej należy użyć słówka extends i podać nazwę klasy przodka:

<?php
class Choroba {
	private $pesel='12345678900';
	protected $stan_zdrowia=5;
	public $imie;
	public function czyIscDoLekarza(){
		return $this->stan_zdrowia<2;
	}
	public function katar(){
		return $this->choruj(2);
	}
	protected function choruj($iloscChorob) {
    return $this->stan_zdrowia -= $iloscChorob;
    if ($this->stan_zdrowia < 0)
      return $this->stan_zdrowia = 0;
  }
}
//następuje dziedziczenie
class Choroba1 extends Choroba{ 
	private $goraczka=36.6;
	public function goraczkaIkatar() {
		return $this->temperaturaIkatar(2);
	}
	private function temperaturaIkatar($iloscChorob) {
		  if ($this->stan_zdrowia > 0) // tutaj mamy dostęp do pola czystosc, gdyż jest protected
			return $this->katar($iloscChorob); // oraz do metody pobrudz, gdyż jest protected
		  return $this->goraczka += $iloscChorob;
	}
}
$czlowiek = new Choroba1();

$czlowiek->imie = 'Jan';
$czlowiek->katar(); 
$czlowiek->goraczkaIkatar();
if ($czlowiek->czyIscDoLekarza()) 
  echo $czlowiek->imie.' idziemy do lekarza!';
echo '<pre>';
print_r($czlowiek);
echo '</pre>';
//$stan_zdrowia = $czlowiek->stan_zdrowia; // ta linijka wysypie błąd, gdyż z zewnątrz nie mamy dostępu do pola
//$stan_zdrowia->choruj(1); // ta linijka podobnie, jak wyżej
?>

Final, a nadpisywanie

Wiemy już doskonale, że zadeklarowanie w kodzie zmiennej o nazwie, która już istnieje, spowoduje nadpisanie jej wartości. Tak samo dzieje się z metodami. Jeżeli klasa dziedzicząca będzie posiadała metodę o nazwie istniejącej w klasie bazowej, to jej funkcjonalność zostanie nadpisana:

class Ja {
	public function wyswietlImie(){
		echo "Nazywam się: Jan Kowalski";
	}
}

class Ty extends Ja {
	public function wyswietlImie(){
		echo "Nazywam się: John Smith";
	}
}

$nazwa = new Ty();
$nazwa->wyswietlImie();

//wyświetli: Nazywam się: John Smith

W powyższym kodzie widzimy, że metoda wyswietlImie() została nadpisana i zamiast wyświetlić „Nazywam się: Jan Kowalski” otrzymaliśmy „Nazywam się: John Smith”.

Jeżeli chcemy zabronić klasie potomnej nadpisywania metod w klasie bazowej, używamy słowa final przed deklaracja metody:

class Ja {
	final public function wyswietlImie(){
		echo "Nazywam się: Jan Kowalski";
	}
}

class Ty extends Ja {
	/*public function wyswietlImie(){
		ta metoda wygeneruje błąd: Fatal error: Cannot declare class Ty, because the name is already in use...
	}*/
}

$nazwa = new Ty();
$nazwa->wyswietlImie();

Modyfikatora final możemy użyć przed nazwą klasy, wówczas ta klasa nie będzie mogła być dziedziczona.

Już potrafisz:

  • stworzyć klasę rozszerzającą inną klasę
  • korzystać z pól i metod klasy bazowej
  • nadpisywać metody klasy bazowej
  • blokować nadpisywanie przy pomocy słowa final

Metody magiczne

Nazwa tych metod wzięła się stąd, że wywoływane są automatycznie w momencie tworzenia obiektu i nie wymagają dodatkowych akcji. Metody te występują tylko w kontekście klas, a ich nazwy są poprzedzone 2 znakami „podłogi” (podkreślnika) __ .

Konstruktor – __construct

Dzięki konstruktorowi możemy przesłać określone wartości do obiektu w momencie jego tworzenia.

Teoretycznie PHP umożliwia stworzenie tylko 1go konstruktora, ale po to mamy kreatywność żeby móc sobie z tym poradzić 🙂 Zapraszam do zbadania tej ewentualności na stronie: https://kursphp.com/programowanie-obiektowe-php/konstruktor/

Destruktor – __destruct

Destruktor wykonuje się w momencie niszczenia obiektu.

Przykład użycia konstruktora i destruktora:

class Czlowiek_przyklad6
{
    private $imie;
    private $wiek;

    public function __construct(string $imie, int $wiek)
    {
        $this->imie = $imie;
        $this->wiek = $wiek;
    }

    public function getImie(): string
    {
        return $this->imie;
    }

    public function getWiek(): int
    {
        return $this->wiek;
    }

    public function __destruct()
    {
        echo '<br>Obiekt usunięty!';
    }
}

$czlowiek = new Czlowiek_przyklad6('Jan Kowalski', 17);
echo 'imie: ' . $czlowiek->getImie() . ', wiek: ' . $czlowiek->getWiek(); // result: imie: Jan Kowalski, wiek: Warszawa

unset($czlowiek); // usuwanie obiektu, result: Obiekt usunięty!

Więcej informacji na temat metod magicznych znajdziesz w dokumentacji: http://php.net/manual/en/language.oop5.magic.php

Stałe

Stała to właściwość klasy tylko do odczytu. Jak wiemy z języka PHP, stałe deklarujemy drukowanymi literami, są dostępne public i nie można ich modyfikować w kodzie.

Aby zadeklarować stałą, używamy modyfikatora const.

Aby się do niej odwołać wewnątrz klasy, musimy użyć modyfikatora self::

Aby wywołać właściwość poza klasą używamy modyfikatora nazwaKlasy::

class Okrag{
    const pi = 3.14;
    private $promien;
    public function __construct($promien){
        $this->promien = $promien;
    }
    public function obwod(){
        return 2*$this->promien*self::pi;
    }

}
// Okrag::pi = 40; // nie mozna modyfikowac
$dane=new Okrag(2);
echo 'Obwód wynosi: '.$dane->obwod().'<br>';
echo 'Liczba Pi wynosi: '.Okrag::pi.'<br>';

Metody i właściwości statyczne

Metody i właściwości statyczne to takie, które nie wymagają utworzenia obiektu, aby móc się do nich odwołać. Nadawane są dla całej klasy. Tworzymy je przy pomocy modyfikatora static.

Z racji tego, że właściwość ta nadawana jest dla klasy (nie dla obiektu), aby się do niej odwołać wewnątrz klasy, musimy użyć modyfikatora self::, nie korzystamy w tym przypadku z $this. Aby wywołać właściwość poza klasą używamy modyfikatora nazwaKlasy::

class Licznik{
    public static  $ilosc = 0;
    public function __construct(){
        self::$ilosc++;
    }

}
echo '$ilosc ='.Licznik::$ilosc.'<br />'; //wartość początkowa
$pierwsza = new Licznik;
$druga = new Licznik;
$trzecia = new Licznik;
echo '$ilosc = '.Licznik::$ilosc; //wartość po kilkukrotnym wykorzystaniu konstruktora

Klasy i metody abstrakcyjne

Klasa abstrakcyjna definiuje pewien model i zachowanie obiektu.

Taka klasa nie posiada definicji tych metod, jedynie ich deklaracje, że gdzieś dalej w kodzie muszą się pojawić. Czyli do czasu rozszerzenia ich o funkcjonalności w klasach dziedziczących, te metody nie istnieją (są abstrakcją).

Metody abstrakcyjne definiujemy w klasie bazowej klauzulą abstract. Wszystkie tego typu zadeklarowane metody będą musiały pojawić się w klasach dziedziczących. Jeśli nie pojawią się, to PHP wygeneruje nam błąd.

Nie można utworzyć obiektu klasy abstrakcyjnej. Klasa ta jest jedynie „bazą” dla klas potomnych.

Pamiętamy, że klasę dziedziczymy i możemy zrobić to tylko raz.

abstract class Osoba {

	abstract public function getName();
}

class Dziecko extends Osoba
{
    public function getName()
    {
        return 'imię';
    }
}

echo (new Dziecko())->getName();

Interfejsy

Interfejs jest zbiorem metod jakie wymagamy by posiadała klasa, która go implementuje.

Możemy implementować wiele interfejsów dla jednej klasy.

Wszystkie metody określane w interfejsie są abstrakcyjne.

interface PersonInterface
{
    public function getName(): string;
    public function getAddress(): string;
}

interface UserInterface
{
    public function getLogin(): string;
}

class Person implements PersonInterface, UserInterface
{
    public function getName(): string
    {
        return 'Jan Kowalski<br>';
    }

    public function getAddress(): string
    {
        return 'Długa 1, Warszawa<br>';
    }

    public function getLogin(): string
    {
        return 'jkowalski<br>';
    }
}
$osoba=new Person();
echo $osoba->getName();
echo $osoba->getAddress();
echo $osoba->getLogin();

Różnice między interfejsem, a klasą abstrakcyjną

  • klasa może implementować wiele interfejsów, ale rozszerzać tylko jednego rodzica
  • metody w interfejsie są publiczne, w klasie publiczne lub chronione
  • interfejs może zawierać tylko deklaracje metod, a klasa też metody zdefiniowane
  • klasy abstrakcyjne mogą zawierać atrybuty(pola), interfejsy nie
  • w interfejsach wszystkie metody są abstrakcyjne, natomiast w klasie abstrakcyjnej można stworzyć metody posiadające ciało, jak i abstrakcyjne
  • klasa abstrakcyjna zazwyczaj jest ściśle związana z klasami dziedziczącymi w sensie logicznym, czyli np. tworzymy klasę abstrakcyjną Planeta po której dziedziczą konkretne klasy planet (np. Ziemia, Mars). Interfejs natomiast nie musi być już tak mocno związany z daną klasą, on określa jej cechy, np możesz stworzyć interfejs Zniszczalny, który mówi że dany obiekt może zostać zniszczony. Taki interfejs możesz nadać zarówno klasą Planeta, Gwiazda, Budynek itp.
  • interfejs może dziedziczyć jedynie po innych interfejsach, a klasa abstrakcyjna może dziedziczyć po klasach abstrakcyjnych, interfejsach a nawet zwykłych klasach
  • interfejs nie może mieć konstruktora, w klasie abstrakcyjnej możemy dostarczyć implementację konstruktora domyślnego

Przestrzenie nazw

Przestrzenie nazw pozwalają na zadeklarowanie wielu klas o tej samej nazwie.

Shafik D. – Mistrz PHP. Pisz nowoczesny kod

Przydatne linki:

http://php.net/manual/en/language.oop5.php

https://webmastah.pl/jak-programowac-obiektowo-cz-1-wstep/

https://kursphp.com/programowanie-obiektowe-php/

https://www.phpdevs.pl/programowanie-obiektowe

http://phpmajster.blogspot.com/2017/01/php-abstrakcja-interfejsy-i-factory.html

http://zasoby.open.agh.edu.pl/~09sdczerner/strona/page/programowanie_obiektowe.html

Przykład

Napisz klasę odcinek w przestrzeni dwuwymiarowej (x,y). Klasa ta ma zawierać:
Punkt początkowy i punkt końcowy o zakresie prywatnym.
Dostęp do punktów zrealizowany ma być za pomocą publicznych metod.
Metodę zwracającą długość odcinka.

class Odcinek{
    private $pocz = array('x'=> 0, 'y' => 0);
    private $kon = array('x'=> 0, 'y' => 0);
    public function ustawWspolrzedne($pocz_x, $pocz_y, $kon_x, $kon_y) 
    {
        $this->pocz['x'] = $pocz_x;
        $this->pocz['y'] = $pocz_y;
        $this->kon['x'] = $kon_x;
        $this->kon['y'] = $kon_y;
    }    
    public function wypiszWspolrzedne(){
        echo "wektor ma wsporzedne :
            [{$this->pocz['x']},{$this->pocz['y']}]
          ->[{$this->kon['x']},{$this->kon['y']}]";
    }
    public function zwrocDlugosc(){
        return sqrt(($this->kon['x'] - $this->pocz['x'])**2 +($this->kon['y'] - $this->pocz['y'])**2);
    }
  }  
  $odc = new Odcinek();
  $odc->ustawWspolrzedne(1,1,4,2);
  $odc->wypiszWspolrzedne();
  echo 'Długość odcinka to: '.$odc->zwrocDlugosc();
	
	echo '<pre>';
	print_r($odc);
	echo '</pre>';
	echo '<br><br>';

Zadanie 1

Jesteś praktykantem w firmie zajmującej się tworzeniem witryn i aplikacji internetowych. Otrzymałeś zadanie polegające na stworzeniu aplikacji w języku PHP.

W aplikacji ma być utworzona klasa trójkąt, która zawiera dwa publiczne pola, takie jak: wysokość i podstawa, oraz konstruktor, który przypisze im losowo wygenerowane wartości.

Ponadto w klasie powinna być zadeklarowana metoda obliczająca pole trójkąta.
W aplikacji należy utworzyć dwa obiekty klasy trójkąt.

Wynikiem działania aplikacji ma być wyświetlona wartość wysokości, podstawy i pola powierzchni obu trójkątów oraz informacja, który z trójkątów ma większą powierzchnię.

Zadanie 2

Jesteś praktykantem w firmie zajmującej się tworzeniem witryn i aplikacji internetowych. Otrzymałeś zadanie polegające na stworzeniu aplikacji w języku PHP.

W aplikacji ma być utworzona klasa odcinek zawierająca cztery publiczne pola, określające współrzędne początku i końca odcinka we współrzędnych x, y. W klasie odcinek należy utworzyć konstruktor, który współrzędnym przypisze podane przez użytkownika (za pomocą formularza) wartości.

Ponadto w klasie powinna być zadeklarowana metoda obliczająca długość odcinka.

W aplikacji należy utworzyć dwa obiekty klasy odcinek.

Wynikiem działania aplikacji ma być wyświetlona wartość długości obu odcinków oraz informacja, który z nich jest dłuższy.