Programação Orientada a Objetos em PHP

Podemos imaginar nosso universo feito de diferentes objetos como sol, terra, lua etc. Da mesma forma, podemos imaginar nosso carro feito de diferentes objetos como volante, direção, marcha etc. Da mesma forma, existem conceitos de programação orientada a objetos que assumem tudo como um objeto e implementar um software usando objetos diferentes.

Conceitos Orientados a Objetos

Antes de entrarmos em detalhes, vamos definir termos importantes relacionados à Programação Orientada a Objetos.

  • Class- Este é um tipo de dados definido pelo programador, que inclui funções locais, bem como dados locais. Você pode pensar em uma classe como um modelo para fazer muitas instâncias do mesmo tipo (ou classe) de objeto.

  • Object- Uma instância individual da estrutura de dados definida por uma classe. Você define uma classe uma vez e, em seguida, faz muitos objetos que pertencem a ela. Os objetos também são conhecidos como instância.

  • Member Variable- Estas são as variáveis ​​definidas dentro de uma classe. Esses dados ficarão invisíveis para o exterior da classe e podem ser acessados ​​por meio de funções de membro. Essas variáveis ​​são chamadas de atributo do objeto, uma vez que um objeto é criado.

  • Member function - Estas são as funções definidas dentro de uma classe e são usadas para acessar os dados do objeto.

  • Inheritance- Quando uma classe é definida herdando uma função existente de uma classe pai, isso é chamado de herança. Aqui, a classe filha herdará todas ou algumas funções-membro e variáveis ​​de uma classe pai.

  • Parent class- Uma classe que é herdada por outra classe. Isso também é chamado de classe base ou superclasse.

  • Child Class- Uma classe que herda de outra classe. Isso também é chamado de subclasse ou classe derivada.

  • Polymorphism- Este é um conceito orientado a objeto onde a mesma função pode ser usada para diferentes propósitos. Por exemplo, o nome da função permanecerá o mesmo, mas leva um número diferente de argumentos e pode realizar tarefas diferentes.

  • Overloading- um tipo de polimorfismo no qual alguns ou todos os operadores têm implementações diferentes dependendo dos tipos de seus argumentos. Da mesma forma, funções também podem ser sobrecarregadas com implementações diferentes.

  • Data Abstraction - Qualquer representação de dados em que os detalhes de implementação estão ocultos (abstraídos).

  • Encapsulation - refere-se a um conceito onde encapsulamos todos os dados e funções-membro juntos para formar um objeto.

  • Constructor - refere-se a um tipo especial de função que será chamada automaticamente sempre que houver uma formação de objeto de uma classe.

  • Destructor - refere-se a um tipo especial de função que será chamada automaticamente sempre que um objeto for excluído ou sair do escopo.

Definindo classes PHP

A forma geral para definir uma nova classe em PHP é a seguinte -

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

Aqui está a descrição de cada linha -

  • A forma especial class, seguido pelo nome da classe que você deseja definir.

  • Um conjunto de colchetes envolvendo qualquer número de declarações de variáveis ​​e definições de funções.

  • As declarações de variáveis ​​começam com o formulário especial var, que é seguido por um nome de variável $ convencional; eles também podem ter uma atribuição inicial a um valor constante.

  • As definições de função se parecem muito com funções PHP independentes, mas são locais para a classe e serão usadas para definir e acessar dados do objeto.

Exemplo

Aqui está um exemplo que define uma classe do tipo Books -

<?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/>";
      }
   }
?>

A variável $thisé uma variável especial e se refere ao mesmo objeto, ou seja. em si.

Criação de objetos em PHP

Depois de definir sua classe, você pode criar quantos objetos quiser desse tipo de classe. A seguir está um exemplo de como criar um objeto usandonew operador.

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

Aqui criamos três objetos e esses objetos são independentes uns dos outros e terão sua existência separadamente. A seguir, veremos como acessar funções-membro e processar variáveis-membro.

Funções de membro de chamada

Depois de criar seus objetos, você será capaz de chamar funções de membro relacionadas a esse objeto. Uma função de membro será capaz de processar a variável de membro do objeto relacionado apenas.

O exemplo a seguir mostra como definir o título e os preços dos três livros chamando as funções de membro.

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

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

Agora você chama outras funções-membro para obter os valores definidos por no exemplo acima -

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

Isso produzirá o seguinte resultado -

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Funções de construtor

Funções de construtor são tipos especiais de funções que são chamadas automaticamente sempre que um objeto é criado. Portanto, aproveitamos totalmente esse comportamento, inicializando muitas coisas por meio de funções construtoras.

PHP fornece uma função especial chamada __construct()para definir um construtor. Você pode passar quantos argumentos desejar para a função do construtor.

O exemplo a seguir criará um construtor para a classe Books e inicializará o preço e o título do livro no momento da criação do objeto.

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

Agora não precisamos chamar a função set separadamente para definir o preço e o título. Podemos inicializar essas duas variáveis ​​de membro apenas no momento da criação do objeto. Verifique o seguinte exemplo abaixo -

$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();

Isso produzirá o seguinte resultado -

Physics for High School
  Advanced Chemistry
  Algebra
  10
  15
  7

Destruidor

Como uma função construtora, você pode definir uma função destruidora usando a função __destruct(). Você pode liberar todos os recursos com um destruidor.

Herança

As definições de classe PHP podem opcionalmente herdar de uma definição de classe pai usando a cláusula extends. A sintaxe é a seguinte -

class Child extends Parent {
   <definition body>
}

O efeito da herança é que a classe filha (ou subclasse ou classe derivada) tem as seguintes características -

  • Possui automaticamente todas as declarações de variáveis ​​de membro da classe pai.

  • Possui automaticamente todas as mesmas funções de membro do pai, que (por padrão) funcionarão da mesma maneira que as funções do pai.

O exemplo a seguir herda a classe Books e adiciona mais funcionalidade com base no requisito.

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

Agora, além das funções herdadas, a classe Novel mantém duas funções-membro adicionais.

Substituição de função

As definições de funções nas classes filhas substituem as definições com o mesmo nome nas classes pais. Em uma classe filha, podemos modificar a definição de uma função herdada da classe pai.

No exemplo a seguir, as funções getPrice e getTitle são substituídas para retornar alguns valores.

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

Membros Públicos

A menos que você especifique o contrário, as propriedades e métodos de uma classe são públicos. Ou seja, podem ser acessados ​​em três situações possíveis -

  • De fora da classe em que é declarado

  • De dentro da classe em que é declarado

  • De dentro de outra classe que implementa a classe em que está declarado

Até agora, vimos todos os membros como membros públicos. Se você deseja limitar a acessibilidade dos membros de uma classe, você define os membros da classe comoprivate ou protected.

Membros privados

Ao designar um membro como privado, você limita sua acessibilidade à classe em que está declarado. O membro privado não pode ser referido a partir de classes que herdam a classe na qual ele foi declarado e não pode ser acessado de fora da classe.

Um membro da classe pode se tornar privado usando private palavra-chave na frente do 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 a classe MyClass é herdada por outra classe usando extends, myPublicFunction () ficará visível, assim como $ driver. A classe de extensão não terá nenhum conhecimento ou acesso a myPrivateFunction e $ car, porque eles foram declarados privados.

Membros protegidos

Uma propriedade ou método protegido está acessível na classe em que é declarado, bem como nas classes que estendem essa classe. Membros protegidos não estão disponíveis fora desses dois tipos de classes. Um membro da classe pode ser protegido usandoprotected palavra-chave na frente do membro.

Aqui está uma versão diferente de 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!");
   }
}

Interfaces

As interfaces são definidas para fornecer nomes de funções comuns aos implementadores. Diferentes implementadores podem implementar essas interfaces de acordo com seus requisitos. Você pode dizer que as interfaces são esqueletos que são implementados por desenvolvedores.

A partir do PHP5, é possível definir uma interface, como esta -

interface Mail {
   public function sendMail();
}

Então, se outra classe implementou essa interface, como esta -

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

Constantes

Uma constante é mais ou menos como uma variável, pois contém um valor, mas na verdade é mais como uma função porque uma constante é imutável. Depois de declarar uma constante, ela não muda.

Declarar uma constante é fácil, como é feito nesta versão de MyClass -

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

Nesta classe, requiredMargin é uma constante. Ele é declarado com a palavra-chave const e, em nenhuma circunstância, pode ser alterado para algo diferente de 1.7. Observe que o nome da constante não tem um $ à esquerda, como ocorre com os nomes das variáveis.

Classes abstratas

Uma classe abstrata é aquela que não pode ser instanciada, apenas herdada. Você declara uma classe abstrata com a palavra-chaveabstract, assim -

Ao herdar de uma classe abstrata, todos os métodos marcados como abstratos na declaração de classe do pai devem ser definidos pelo filho; além disso, esses métodos devem ser definidos com a mesma visibilidade.

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

Observe que as definições de função dentro de uma classe abstrata também devem ser precedidas pela palavra-chave abstract. Não é legal ter definições de função abstratas dentro de uma classe não abstrata.

Palavra-chave estática

Declarar os membros da classe ou métodos como estáticos os torna acessíveis sem a necessidade de uma instanciação da classe. Um membro declarado como estático não pode ser acessado com um objeto de classe instanciado (embora um método estático possa).

Experimente o seguinte exemplo -

<?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";
?>

Palavra-chave final

PHP 5 introduz a palavra-chave final, que evita que classes filhas substituam um método prefixando a definição com final. Se a própria classe está sendo definida como final, ela não pode ser estendida.

O exemplo a seguir resulta em erro fatal: não é possível substituir o método final 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>";
      }
   }
?>

Chamando construtores pais

Em vez de escrever um construtor inteiramente novo para a subclasse, vamos escrevê-lo chamando o construtor do pai explicitamente e, em seguida, fazendo o que for necessário além da instanciação da subclasse. Aqui está um exemplo simples -

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);
   }
}

Neste exemplo, temos uma classe pai (Name), que possui um construtor de dois argumentos, e uma subclasse (NameSub1), que possui um construtor de três argumentos. O construtor de NameSub1 funciona chamando seu construtor pai explicitamente usando a sintaxe :: (passando dois de seus argumentos) e, em seguida, definindo um campo adicional. Da mesma forma, NameSub1 define sua função não construtora toString () em termos da função pai que ele substitui.

NOTE- Um construtor pode ser definido com o mesmo nome que o nome de uma classe. É definido no exemplo acima.