Pokročilé techniky objektově orientovaného programování
Klonování
- proměnná s instancí se chová jako reference: přiřazení ani předání do funkce kopii nevytvoří
- někdy je vhodné předat kopii (třeba při kešování)
- k tomu slouží operátor
clone- vytváří mělkou kopii: atributy obsahující další objekty zůstávají sdílené
- hlubokou kopii zajistí magická metoda
__clone, která se zavolá na nové kopii - od PHP 8.5 lze použít i jako funkci a vybrané atributy na kopii rovnou přenastavit
- viz referenční dokumentace
Příklad - mělká a hluboká kopie
class Order {
public function __construct(
public string $name,
public DateTime $created,
) {}
}
$order = new Order( 'Objednávka', new DateTime( '2026-01-01' ) );
$copy = clone $order;
$copy->name = 'Kopie';
echo $order->name; // Objednávka - řetězec se zkopíroval
$copy->created->modify( '+1 day' );
echo $order->created->format( 'Y-m-d' ); // 2026-01-02 - DateTime je sdílený (NEŽÁDOUCÍ)Hlubokou kopii zajistí __clone:
class Order {
// ...
public function __clone() {
$this->created = clone $this->created;
}
}Od PHP 8.5 lze při klonování rovnou změnit vybrané atributy (funguje i pro readonly):
$copy = clone( $order, [ 'name' => 'Kopie' ] );Dědičnost - self, late static binding
Pozor na jakou třídu ukazuje self a static.
class ParentClass {
public function hello():void {
echo "Hello from parent class" . PHP_EOL;
}
public function callSelf(): void {
self::hello();
}
public function callStatic(): void {
static::hello();
}
}
class ChildClass extends ParentClass {
public function hello():void {
echo "Hello from child class" . PHP_EOL;
}
}
$parent = new ParentClass();
$parent->callSelf();
$parent->callStatic();
$child = new ChildClass();
$child->callSelf();
$child->callStatic();Platí:
self
- v čase čtení kódu (compile time)
static
- v čase běhu kódu (runtime)
Příklad
class Attachment {
public const string TYPE = 'application/octet-stream';
protected static int $sequence = 0;
public function __construct()
{
$this->id = ++self::$sequence;
$this->type = static::TYPE;
}
}
class Text extends Attachment
{
public const string TYPE = 'text/plain';
}
class JpegImage extends Attachment
{
public const string TYPE = 'image/jpeg';
}Abstraktní třídy
- klíčové slovo
abstract - sdílení kódu
- nelze instanciovat
- v potomcích abstraktní třídy obvykle různé implementace operací
- třída s alespoň jednou abstraktní metodou musí být sama abstraktní
- může obsahovat i atributy
Příklad
abstract class Image {
abstract function display();
}
class Jpeg extends Image {
function display() { ... }
}Rozhraní
- dohoda splňovat zadané požadvky
- interface segregation principle (part of SOLID)
- PHP
- klíčové slovo
interface - obsahuje hlavičky metod a konstanty
- rozhraní mohou dědit
- třídy mohou implementovat jedno nebo více rozhraní pomocí klíčového slova
implements - Predefinované rozhraní
- klíčové slovo
Příklad
interface Filesystem {
function mkdir($path);
function rmdir($path);
}
class LocalFilesystem implements Filesystem {
function mkdir($path) { ... }
function rmdir($path) { ... }
}Traity
- klíčové slovo
trait, použitíuseuvnitř třídy - náhrada za vícenásobnou dědičnost
- kdekoliv znovupoužitelný kód
- přidává kód i do spolu nesouvisejících tříd
- může pracovat s
$thiscílové třídy
Příklad
trait CRUD {
public function create(...) {...}
}
class Entity {
use CRUD;
}