Mengapa begitu banyak orang bermasalah dengan prinsip ini? Jika kita mengambil bukan "muskil", tetapi definisi yang lebih sederhana, maka bunyinya seperti ini:
Kelas yang mewarisi harus melengkapi, bukan menimpa, perilaku kelas dasar.
Kedengarannya jelas dan cukup logis, kami tidak setuju. tapi bagaimana cara mencapai ini? Untuk beberapa alasan, banyak orang melewatkan informasi tentang prasyarat dan pascakondisi , yang menjelaskan dengan sempurna apa yang perlu dilakukan.
Dalam artikel ini, kami TIDAK akan mempertimbangkan contoh umum dari prinsip ini, yang sudah ada banyak bahan (contoh dengan persegi dan persegi panjang atau kontrol termostat ). Di sini kita akan membahas sedikit lebih detail tentang konsep-konsep seperti "Prasyarat" , "Kondisi setelah" , mempertimbangkan apa itu kovarians, kontravarian dan invarian , serta apa itu "kendala historis" atau "aturan sejarah".
Prasyarat tidak dapat diperkuat dalam subkelas
βͺοΈ Dengan kata lain, kelas anak tidak boleh membuat lebih banyak prasyarat daripada yang ditentukan di kelas dasar untuk melakukan beberapa perilaku bisnis. Berikut contohnya:
<?php
class Customer
{
protected float $account = 0;
public function putMoneyIntoAccount(int|float $sum): void
{
if ($sum < 1) {
throw new Exception(' 1$');
}
$this->account += $sum;
}
}
class MicroCustomer extends Customer
{
public function putMoneyIntoAccount(int|float $sum): void
{
if ($sum < 1) {
throw new Exception(' 1$');
}
//
if ($sum > 100) {
throw new Exception(' 100$');
}
$this->account += $sum;
}
}
β . !
«», , .
, , .
, , Bar->process()
, .
<?php
class Foo
{
public function process(int|float $value)
{
// some code
}
}
class Bar extends Foo
{
public function process(int|float|string $value)
{
// some code
}
}
, VIPCustomer
putMoneyIntoAccount
( ) Money
, ( Dollars
).
<?php
class Money {}
class Dollars extends Money {}
class Customer
{
protected Money $account;
public function putMoneyIntoAccount(Dollars $sum): void
{
$this->account = $sum;
}
}
class VIPCustomer extends Customer
{
public function putMoneyIntoAccount(Money $sum): void
{
$this->account = $sum;
}
}
, , .
βοΈ , . .
<?php
class Customer
{
protected Dollars $account;
public function chargeMoney(Dollars $sum): float
{
$result = $this->account - $sum->getAmount();
if ($result < 0) { //
throw new Exception();
}
return $result;
}
}
class VIPCustomer extends Customer
{
public function chargeMoney(Dollars $sum): float
{
$result = $this->account - $sum->getAmount();
if ($sum < 1000) { //
$result -= 5;
}
//
return $result;
}
}
β , . !
- «», (?!), .
. render()
, JpgImage
, Image
, Renderer
.
<?php
class Image {}
class JpgImage extends Image {}
class Renderer
{
public function render(): Image
{
}
}
class PhotoRenderer extends Renderer
{
public function render(): JpgImage
{
}
}
βοΈ . . :)
.
- .
β , . , .
.
<?php
class Wallet
{
protected float $amount;
//
}
(Β« Β»):
.
, . , .
<?php
class Deposit
{
protected float $account = 0;
public function __construct(float $sum)
{
if ($sum < 0) {
throw new Exception(' ');
}
$this->account += $sum;
}
}
class VipDeposit extends Deposit
{
public function getMoney(float $sum)
{
$this->account -= $sum;
}
}
β Deposit
. VipDeposit
, account
, Deposit
. .
.
, , , , .
Perlu disebutkan untuk berusaha menyingkirkan kondisi pra / pasca. Idealnya, mereka harus didefinisikan sebagai parameter input / output dari metode (misalnya, dengan meneruskan objek nilai siap pakai ke tanda tangan dan mengembalikan objek valid tertentu ke output).
Semoga bermanfaat.