Programmazione orientata agli oggetti in PHP

Possiamo immaginare il nostro universo fatto di oggetti diversi come il sole, la terra, la luna ecc. Allo stesso modo possiamo immaginare la nostra macchina fatta di oggetti diversi come il volante, lo sterzo, il cambio ecc. Allo stesso modo ci sono concetti di programmazione orientata agli oggetti che assumono tutto come un oggetto e implementare un software utilizzando diversi oggetti.

Concetti orientati agli oggetti

Prima di entrare nei dettagli, definiamo i termini importanti relativi alla programmazione orientata agli oggetti.

  • Class- Questo è un tipo di dati definito dal programmatore, che include funzioni locali e dati locali. Puoi pensare a una classe come a un modello per creare molte istanze dello stesso tipo (o classe) di oggetto.

  • Object- Una singola istanza della struttura dati definita da una classe. Definisci una classe una volta e poi crei molti oggetti che le appartengono. Gli oggetti sono noti anche come istanza.

  • Member Variable- Queste sono le variabili definite all'interno di una classe. Questi dati saranno invisibili all'esterno della classe e sarà possibile accedervi tramite le funzioni membro. Queste variabili sono chiamate attributo dell'oggetto una volta creato un oggetto.

  • Member function - Queste sono le funzioni definite all'interno di una classe e vengono utilizzate per accedere ai dati dell'oggetto.

  • Inheritance- Quando una classe viene definita ereditando la funzione esistente di una classe genitore, viene chiamata ereditarietà. Qui la classe figlia erediterà tutte o poche funzioni membro e variabili di una classe genitore.

  • Parent class- Una classe ereditata da un'altra classe. Questa è anche chiamata classe base o super classe.

  • Child Class- Una classe che eredita da un'altra classe. Questa è anche chiamata sottoclasse o classe derivata.

  • Polymorphism- Questo è un concetto orientato agli oggetti in cui la stessa funzione può essere utilizzata per scopi diversi. Ad esempio, il nome della funzione rimarrà lo stesso ma richiede un numero diverso di argomenti e può svolgere attività diverse.

  • Overloading- un tipo di polimorfismo in cui alcuni o tutti gli operatori hanno implementazioni diverse a seconda dei tipi dei loro argomenti. Allo stesso modo le funzioni possono anche essere sovraccaricate con implementazioni diverse.

  • Data Abstraction - Qualsiasi rappresentazione di dati in cui i dettagli di implementazione sono nascosti (astratti).

  • Encapsulation - si riferisce a un concetto in cui incapsuliamo tutti i dati e le funzioni membro insieme per formare un oggetto.

  • Constructor - si riferisce a un tipo speciale di funzione che verrà chiamata automaticamente ogni volta che c'è una formazione di oggetti da una classe.

  • Destructor - si riferisce a un tipo speciale di funzione che verrà chiamata automaticamente ogni volta che un oggetto viene eliminato o esce dall'ambito.

Definizione di classi PHP

La forma generale per definire una nuova classe in PHP è la seguente:

<?php
   class phpClass {
      var $var1;
      var $var2 = "constant string";
      
      function myfunc ($arg1, $arg2) {
         [..]
      }
      [..]
   }
?>

Ecco la descrizione di ogni riga:

  • La forma speciale class, seguito dal nome della classe che desideri definire.

  • Un insieme di parentesi graffe che racchiude un numero qualsiasi di dichiarazioni di variabili e definizioni di funzioni.

  • Le dichiarazioni di variabili iniziano con la forma speciale var, seguito da un nome di variabile $ convenzionale; possono anche avere un'assegnazione iniziale a un valore costante.

  • Le definizioni delle funzioni assomigliano molto alle funzioni PHP autonome ma sono locali alla classe e verranno utilizzate per impostare e accedere ai dati dell'oggetto.

Esempio

Ecco un esempio che definisce una classe di tipo Libri:

<?php
   class Books {
      /* Member variables */
      var $price;
      var $title;
      
      /* Member functions */
      function setPrice($par){
         $this->price = $par;
      }
      
      function getPrice(){
         echo $this->price ."<br/>";
      }
      
      function setTitle($par){
         $this->title = $par;
      }
      
      function getTitle(){
         echo $this->title ." <br/>";
      }
   }
?>

La variabile $thisè una variabile speciale e si riferisce allo stesso oggetto es. si.

Creazione di oggetti in PHP

Dopo aver definito la classe, puoi creare tutti gli oggetti che desideri di quel tipo di classe. Di seguito è riportato un esempio di come creare un oggetto utilizzandonew operatore.

$physics = new Books;
$maths = new Books;
$chemistry = new Books;

Qui abbiamo creato tre oggetti e questi oggetti sono indipendenti l'uno dall'altro e avranno la loro esistenza separatamente. Successivamente vedremo come accedere alla funzione membro e elaborare le variabili membro.

Chiamare le funzioni dei membri

Dopo aver creato i tuoi oggetti, sarai in grado di chiamare le funzioni membro relative a quell'oggetto. Una funzione membro sarà in grado di elaborare la variabile membro solo dell'oggetto correlato.

L'esempio seguente mostra come impostare il titolo e i prezzi per i tre libri chiamando le funzioni membro.

$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );

$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );

Ora chiami un altro membro delle funzioni per ottenere i valori impostati nell'esempio precedente -

$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();

Questo produrrà il seguente risultato:

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Funzioni del costruttore

Le funzioni del costruttore sono un tipo speciale di funzioni che vengono chiamate automaticamente ogni volta che viene creato un oggetto. Quindi sfruttiamo appieno questo comportamento, inizializzando molte cose tramite le funzioni del costruttore.

PHP fornisce una funzione speciale chiamata __construct()per definire un costruttore. Puoi passare tutti gli argomenti che desideri nella funzione di costruzione.

L'esempio seguente creerà un costruttore per la classe Libri e inizializzerà prezzo e titolo per il libro al momento della creazione dell'oggetto.

function __construct( $par1, $par2 ) {
   $this->title = $par1;
   $this->price = $par2;
}

Ora non è necessario chiamare la funzione set separatamente per impostare prezzo e titolo. Possiamo inizializzare queste due variabili membro solo al momento della creazione dell'oggetto. Controllare il seguente esempio di seguito:

$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );

/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();

$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();

Questo produrrà il seguente risultato:

Physics for High School
  Advanced Chemistry
  Algebra
  10
  15
  7

Distruttore

Come una funzione di costruzione, puoi definire una funzione distruttore usando function __destruct(). Puoi rilasciare tutte le risorse con un distruttore.

Eredità

Le definizioni di classe PHP possono opzionalmente ereditare da una definizione di classe genitore utilizzando la clausola extends. La sintassi è la seguente:

class Child extends Parent {
   <definition body>
}

L'effetto dell'ereditarietà è che la classe figlia (o sottoclasse o classe derivata) ha le seguenti caratteristiche:

  • Ha automaticamente tutte le dichiarazioni delle variabili membro della classe genitore.

  • Ha automaticamente tutte le stesse funzioni membro del genitore, che (per impostazione predefinita) funzionerà allo stesso modo di quelle funzioni nel genitore.

L'esempio seguente eredita la classe Books e aggiunge più funzionalità in base al requisito.

class Novel extends Books {
   var $publisher;
   
   function setPublisher($par){
      $this->publisher = $par;
   }
   
   function getPublisher(){
      echo $this->publisher. "<br />";
   }
}

Ora, a parte le funzioni ereditate, la classe Novel mantiene due funzioni membro aggiuntive.

Funzione di override

Le definizioni di funzione nelle classi figlio sovrascrivono le definizioni con lo stesso nome nelle classi padre. In una classe figlia, possiamo modificare la definizione di una funzione ereditata dalla classe genitore.

Nel seguente esempio le funzioni getPrice e getTitle vengono sovrascritte per restituire alcuni valori.

function getPrice() {
   echo $this->price . "<br/>";
   return $this->price;
}
   
function getTitle(){
   echo $this->title . "<br/>";
   return $this->title;
}

Membri pubblici

Se non diversamente specificato, le proprietà e i metodi di una classe sono pubblici. Vale a dire, è possibile accedervi in ​​tre possibili situazioni:

  • Dall'esterno della classe in cui è dichiarato

  • Dall'interno della classe in cui è dichiarato

  • Dall'interno di un'altra classe che implementa la classe in cui è dichiarata

Finora abbiamo visto tutti i membri come membri pubblici. Se desideri limitare l'accessibilità dei membri di una classe, definisci i membri della classe comeprivate o protected.

Membri privati

Designando un membro privato, ne limiti l'accessibilità alla classe in cui è dichiarato. Non è possibile fare riferimento al membro privato dalle classi che ereditano la classe in cui è dichiarato e non è possibile accedervi dall'esterno della classe.

Un membro della classe può essere reso privato utilizzando private parola chiave davanti al membro.

class MyClass {
   private $car = "skoda";
   $driver = "SRK";
   
   function __construct($par) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }
   
   function myPublicFunction() {
      return("I'm visible!");
   }
   
   private function myPrivateFunction() {
      return("I'm  not visible outside!");
   }
}

Quando la classe MyClass viene ereditata da un'altra classe che utilizza extends, myPublicFunction () sarà visibile, così come $ driver. La classe di estensione non avrà alcuna consapevolezza o accesso a myPrivateFunction e $ car, perché sono dichiarate private.

Membri protetti

Una proprietà o un metodo protetto è accessibile nella classe in cui è dichiarato, nonché nelle classi che estendono tale classe. I membri protetti non sono disponibili al di fuori di questi due tipi di classi. È possibile proteggere un membro della classe utilizzandoprotected parola chiave davanti al membro.

Ecco una versione diversa di MyClass -

class MyClass {
   protected $car = "skoda";
   $driver = "SRK";

   function __construct($par) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }
   
   function myPublicFunction() {
      return("I'm visible!");
   }
   
   protected function myPrivateFunction() {
      return("I'm  visible in child class!");
   }
}

Interfacce

Le interfacce sono definite per fornire nomi di funzioni comuni agli implementatori. Diversi implementatori possono implementare queste interfacce in base ai loro requisiti. Puoi dire che le interfacce sono scheletri implementati dagli sviluppatori.

A partire da PHP5, è possibile definire un'interfaccia, come questa:

interface Mail {
   public function sendMail();
}

Quindi, se un'altra classe implementasse quell'interfaccia, come questa -

class Report implements Mail {
   // sendMail() Definition goes here
}

Costanti

Una costante è un po 'come una variabile, in quanto contiene un valore, ma in realtà è più simile a una funzione perché una costante è immutabile. Una volta dichiarata una costante, non cambia.

Dichiarare una costante è facile, come si fa in questa versione di MyClass -

class MyClass {
   const requiredMargin = 1.7;
   
   function __construct($incomingValue) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }
}

In questa classe, requiredMargin è una costante. Viene dichiarato con la parola chiave const e in nessun caso può essere modificato in qualcosa di diverso da 1.7. Nota che il nome della costante non ha una $ iniziale, come fanno i nomi delle variabili.

Classi astratte

Una classe astratta è quella che non può essere istanziata, ma solo ereditata. Dichiari una classe astratta con la parola chiaveabstract, come questo -

Quando si eredita da una classe astratta, tutti i metodi contrassegnati come astratti nella dichiarazione della classe del genitore devono essere definiti dal figlio; inoltre, questi metodi devono essere definiti con la stessa visibilità.

abstract class MyAbstractClass {
   abstract function myAbstractFunction() {
   }
}

Si noti che anche le definizioni di funzione all'interno di una classe astratta devono essere precedute dalla parola chiave abstract. Non è legale avere definizioni di funzioni astratte all'interno di una classe non astratta.

Parola chiave statica

Dichiarare membri o metodi della classe come statici li rende accessibili senza bisogno di un'istanza della classe. Non è possibile accedere a un membro dichiarato statico con un oggetto di classe istanziato (sebbene un metodo statico possa farlo).

Prova il seguente esempio:

<?php
   class Foo {
      public static $my_static = 'foo';
      
      public function staticValue() {
         return self::$my_static;
      }
   }
	
   print Foo::$my_static . "\n";
   $foo = new Foo();
   
   print $foo->staticValue() . "\n";
?>

Parola chiave finale

PHP 5 introduce la parola chiave final, che impedisce alle classi figlie di sovrascrivere un metodo anteponendo alla definizione il prefisso final. Se la classe stessa viene definita finale, non può essere estesa.

L'esempio seguente genera un errore irreversibile: Impossibile sovrascrivere il metodo finale BaseClass :: moreTesting ()

<?php

   class BaseClass {
      public function test() {
         echo "BaseClass::test() called<br>";
      }
      
      final public function moreTesting() {
         echo "BaseClass::moreTesting() called<br>";
      }
   }
   
   class ChildClass extends BaseClass {
      public function moreTesting() {
         echo "ChildClass::moreTesting() called<br>";
      }
   }
?>

Chiamare i costruttori principali

Invece di scrivere un costruttore completamente nuovo per la sottoclasse, scriviamolo chiamando esplicitamente il costruttore del genitore e poi facendo tutto ciò che è necessario in aggiunta per l'istanza della sottoclasse. Ecco un semplice esempio:

class Name {
   var $_firstName;
   var $_lastName;
   
   function Name($first_name, $last_name) {
      $this->_firstName = $first_name;
      $this->_lastName = $last_name;
   }
   
   function toString() {
      return($this->_lastName .", " .$this->_firstName);
   }
}
class NameSub1 extends Name {
   var $_middleInitial;
   
   function NameSub1($first_name, $middle_initial, $last_name) {
      Name::Name($first_name, $last_name);
      $this->_middleInitial = $middle_initial;
   }
   
   function toString() {
      return(Name::toString() . " " . $this->_middleInitial);
   }
}

In questo esempio, abbiamo una classe genitore (Name), che ha un costruttore a due argomenti e una sottoclasse (NameSub1), che ha un costruttore a tre argomenti. Il costruttore di NameSub1 funziona chiamando il suo costruttore padre in modo esplicito usando la sintassi :: (passando due dei suoi argomenti insieme) e quindi impostando un campo aggiuntivo. Allo stesso modo, NameSub1 definisce la sua funzione toString () non costruttore in termini di funzione padre che sovrascrive.

NOTE- Un costruttore può essere definito con lo stesso nome del nome di una classe. È definito nell'esempio precedente.