80 Interface e classi astratte

Un’interfaccia è un modello di classe che definisce dei metodi che una classe a cui si riferisce dovrà implementare.

L’interfaccia si definisce con la parola riservata interface e poi si definiscono i metodi da utilizzare, ecco un esempio:

interface Car {
    public function stop();
    public function start();
    public function marcia();
    public function parcheggio();
    public function accellera();
}

non è possibile creare un nuovo oggetto direttamente dall’interfaccia

$macchina = new Car();

Bisogna prima stanziare la classe che implementa l’interfaccia tramite la keywords implements

class Automobile implements Car() {
    
}

anche così otterrò un errore in quanto la classe dovrà implementare anche i metodi dichiarati nell’interface

class Automobile implements Car {
    public function stop(){}
    public function start(){}
    public function marcia(){}
    public function parcheggio(){}
    public function accellera(){}
}

se voglio passare dei parametri ai metodi della classe, allora dovranno essere previsti anche nei metodi dell’interfaccia

interface Car {
  public function marcia($p1);
}

class Automobile implements Car {
    public function marcia($v){
    }
}

Qual’ora volessimo tipizzare un parametro del metodo, dovrà essere tipizzato anche il relativo prototipo nell’interfaccia

interface Car {
  public function marcia(int $p1);
}

class Automobile implements Car {
    public function marcia(int $v){
    }
}

Classi astratte

Una classe astratta è un tipo di classe che determina la struttura delle classi che la editeranno.

Le classi astratte implementano metodi astratti. Una classe che possiede anche solo un metodo astratto al suo interno deve essere definita astratta. Per definire la classe e i metodi astratti si utilizza la keyword abstract

class Cars {
    abstract function velocita(int $v)
}

La classe astratta non può essere istanziata direttamente, ma dovrà essere prima estesa da un altra classe, infatti se creo un oggetto con la classe astratta Cars otterrò un errore, in primis perchè deve esere definita anche la classe come astratta, poi perchè manca la classe ereditante

class Cars {
    abstract function velocita(int $v) {}
}

$car = new Cars();

Per aggiungere la classe che eredita la classe astratta devo utilizzare la parola extends

class Cars {
    abstract function velocita(int $v);
}

class myCar extends Cars {
    
}

$car = new Cars();

anche adesso otterrò ancora un errore in quanto la classe ereditante myCars deve contenere il metodo astratto definito nella classe astratta Cars

abstract class Cars {
    abstract protected function velocita(int $v);
}

class myCar extends Cars {
    public function velocita(int $v)
    {
        // TODO: Implement velocita() method.
    }
}

$car = new Cars();

Il metodo astratto normalmente viene definito come protected, perchè comunque dovrà essere ereditato dalla classe concreta che estende. La classe astratta può contenere anche metodi non astratti che non devono essere dichiarati nella classe concreta.

La visibilità del metodo che estende quello astratto deve essere di pari valore o superiore di quello della classe astratta. Se definisco un metodo protected nella classe astratta non potrò estenderlo come private nella classe concreta. Il numero e il tipo di parametri di un metodo deve coincidere.

Le classi astratte sono molto simili alle interfaccie, la differenza è che le abstract class possono implementare metodi concreti.