<?php
abstract class Price {
protected $value;
public function __construct($value) {
$this->value = $value;
}
// Duck typing means this declaration is actually optional
abstract protected function getRawValue();
public function getFormattedValue() {
// Calls a protected method of whichever child class is $this
return number_format($this->getRawValue(), 2);
}
public function add(Price $other) {
// Calls a protected method of whichever child class is $other
$this->value += $other->getRawValue();
}
}
class TaxFreePrice extends Price {
protected function getRawValue() {
return $this->value;
}
}
class PriceWithTax extends Price{
private const TAX_RATE=1.2;
protected function getRawValue() {
return $this->value * self::TAX_RATE;
}
}
$a = new TaxFreePrice(10);
$b = new PriceWithTax(10);
echo $a->getFormattedValue(), PHP_EOL;
echo $b->getFormattedValue(), PHP_EOL;
// Here, an instance of TaxFreePrice will access a protected member of PriceWithTax
$a->add($b);
echo $a->getFormattedValue(), PHP_EOL;
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
10.00
12.00
22.00