Objektsarv

Från Wiki.linux.se
Hoppa till navigering Hoppa till sök

Objektarv

Arv är en väletablerad programmeringsprincip, och PHP använder denna princip i sitt objektmodell. Denna princip påverkar hur många klasser och objekt relaterar till varandra.

Till exempel, när en klass utökas, ärver underklassen alla publika och skyddade metoder, egenskaper och konstanter från föräldraklassen. Om inte en klass åsidosätter dessa metoder, kommer de att behålla sin ursprungliga funktionalitet.

Detta är användbart för att definiera och abstrahera funktionalitet, och tillåter implementering av ytterligare funktionalitet i liknande objekt utan att behöva omimplementera all delad funktionalitet.

Privata metoder i en föräldraklass är inte tillgängliga för en barnklass. Som ett resultat kan barnklasser återimplementera en privat metod själva utan hänsyn till normala arvsregler. Före PHP 8.0.0 tillämpades dock final- och statiska restriktioner på privata metoder. Från och med PHP 8.0.0 är den enda privata metodrestriktionen som upprätthålls privata final-konstruktörer, eftersom detta är ett vanligt sätt att "inaktivera" konstruktören när statiska fabriksmetoder används istället.

Synligheten för metoder, egenskaper och konstanter kan göras mer tillgänglig, t.ex. kan en skyddad metod markeras som offentlig, men de kan inte göras mer restriktiva, t.ex. genom att markera en offentlig egenskap som privat. Ett undantag är konstruktörer, vars synlighet kan begränsas, t.ex. kan en offentlig konstruktör markeras som privat i en barnklass.

Observera: Om inte autoladdning används måste klasserna definieras innan de används. Om en klass utökar en annan måste föräldraklassen deklareras innan barnklassens struktur. Denna regel gäller klasser som ärver andra klasser och gränssnitt.

Observera: Det är inte tillåtet att åsidosätta en läs-skriv-egenskap med en skrivskyddad egenskap eller vice versa.

<?php

class A {
    public int $prop;
}
class B extends A {
    // Olagligt: läs-skriv -> skrivskyddad
    public readonly int $prop;
}
?>

Exempel #1 Arvsexempel

<?php

class Foo
{
    public function printItem($string)
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
    
    public function printPHP()
    {
        echo 'PHP är fantastiskt.' . PHP_EOL;
    }
}

class Bar extends Foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}

$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Utdata: 'Foo: baz'
$foo->printPHP();       // Utdata: 'PHP är fantastiskt' 
$bar->printItem('baz'); // Utdata: 'Bar: baz'
$bar->printPHP();       // Utdata: 'PHP är fantastiskt'

?>

Returtypkompatibilitet med interna klasser ¶

Före PHP 8.1 deklarerade de flesta interna klasser eller metoder inte sina returtyper, och vilken returtyp som helst var tillåten när de utökades.

Från och med PHP 8.1.0 började de flesta interna metoder "tentativt" deklarera sina returtyper, i så fall bör returtypen för metoder vara kompatibel med föräldern som utökas; annars avges ett avvecklingsmeddelande. Observera att avsaknaden av en explicit returdeklaration också anses vara en signaturmismatch och därmed resulterar i ett avvecklingsmeddelande.

Om returtypen inte kan deklareras för en åsidosättande metod på grund av PHP-kompatibilitetsproblem mellan versioner, kan en `ReturnTypeWillChange`-attribut läggas till för att tysta avvecklingsmeddelandet.

Exempel #2 Den åsidosättande metoden deklarerar ingen returtyp

<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier) { return false; }
}
 
// "Avvecklat: Returtypen för MyDateTime::modify(string $modifier) bör vara kompatibel med DateTime::modify(string $modifier): DateTime|false, eller så bör attributet #[\ReturnTypeWillChange] användas för att tillfälligt undertrycka meddelandet" från och med PHP 8.1.0
?>

Exempel #3 Den åsidosättande metoden deklarerar fel returtyp

<?php
class MyDateTime extends DateTime
{
    public function modify(string $modifier): ?DateTime { return null; }
}
 
// "Avvecklat: Returtypen för MyDateTime::modify(string $modifier): ?DateTime bör vara kompatibel med DateTime::modify(string $modifier): DateTime|false, eller så bör attributet #[\ReturnTypeWillChange] användas för att tillfälligt undertrycka meddelandet" från och med PHP 8.1.0
?>

Exempel #4 Den åsidosättande metoden deklarerar fel returtyp utan ett avvecklingsmeddelande

<?php
class MyDateTime extends DateTime
{
    /**
     * @return DateTime|false
     */
    #[\ReturnTypeWillChange]
    public function modify(string $modifier) { return false; }
}
 
// Inget meddelande utlöses 
?>

Sidslut

Orginalhemsidan på Engelska :
PHP
Språkreferens
Språkreferens#Klasser_och_Objekt