I have some doubts about practical ways to violate the Liskov Substitution Principle regarding pre and post conditions.
I created examples in which I believe the first child respects LSP and the second violates it. But the Liskov article is very mathematical and now I am not so sure.
The first example is about pre conditions:
<?php
class TermCalculator
{
public function data(int $dias): DateTimeInterface
{
if ($dias > 0)
{
return (new DateTime())->modify("+$dias days");
}
throw new \InvalidArgumentException("Term needs to be above zero ");
}
}
class TermCalculatorCLT extends TermCalculator
{
public function data(int $dias): DateTimeInterface
{
if ($dias >= 0)
{
return (new DateTime())->modify("+$dias days");
}
throw new \InvalidArgumentException("Term needs to be above -1");
}
}
class TermCalculatorCPC extends TermCalculator
{
public function data(int $dias): DateTimeInterface
{
if (in_array($dias, range(1,30)))
{
return (new DateTime())->modify("+$dias days");
}
throw new \InvalidArgumentException("Term needs to be between 1 and 30 ");
}
}
Which child class above violates LSP by pre conditions?
These are two situations about post conditions:
<?php
class Account
{
protected float $balance;
public function __construct(float $balanceInicial)
{
$this->balance = $balanceInicial;
}
public function withdraw(float $value) : float
{
if (($this->balance - $value) >= 0)
{
$this->balance -= $value;
}
return $this->balance;
}
}
class AccountVip extends Account
{
private const TAXA = 10.00;
public function withdraw(float $value) : float
{
if (($this->balance - $value) >= self::TAXA)
{
$this->balance -= $value;
}
return $this->balance;
}
}
class AccountIlimited extends Account
{
public function withdraw(float $value) : float
{
$this->balance -= $value;
return $this->balance;
}
}
Which child class above violates LSP by post conditions?