Объектно-ориентированное программирование на PHP

Мы можем представить нашу вселенную, состоящую из различных объектов, таких как солнце, земля, луна и т. Д. Точно так же мы можем представить нашу машину, состоящую из различных объектов, таких как колесо, рулевое управление, шестерня и т. Д. Таким же образом существуют концепции объектно-ориентированного программирования, которые принимают все как объект реализовать программное обеспечение с использованием различных объектов.

Объектно-ориентированные концепции

Прежде чем мы углубимся в детали, давайте определим важные термины, связанные с объектно-ориентированным программированием.

  • Class- Это тип данных, определяемый программистом, который включает как локальные функции, так и локальные данные. Вы можете думать о классе как о шаблоне для создания множества экземпляров одного и того же вида (или класса) объекта.

  • Object- Отдельный экземпляр структуры данных, определенной классом. Вы определяете класс один раз, а затем создаете множество объектов, которые ему принадлежат. Объекты также известны как экземпляры.

  • Member Variable- Это переменные, определенные внутри класса. Эти данные будут невидимы для внешнего класса, и к ним можно будет получить доступ через функции-члены. Эти переменные называются атрибутом объекта после создания объекта.

  • Member function - Это функции, определенные внутри класса, которые используются для доступа к данным объекта.

  • Inheritance- Когда класс определяется путем наследования существующей функции родительского класса, это называется наследованием. Здесь дочерний класс наследует все или несколько функций-членов и переменных родительского класса.

  • Parent class- Класс, унаследованный от другого класса. Это также называется базовым классом или суперклассом.

  • Child Class- Класс, наследуемый от другого класса. Это также называется подклассом или производным классом.

  • Polymorphism- Это объектно-ориентированная концепция, в которой одна и та же функция может использоваться для разных целей. Например, имя функции останется прежним, но она принимает другое количество аргументов и может выполнять разные задачи.

  • Overloading- тип полиморфизма, в котором некоторые или все операторы имеют разные реализации в зависимости от типов их аргументов. Точно так же функции могут быть перегружены другой реализацией.

  • Data Abstraction - Любое представление данных, в котором детали реализации скрыты (абстрагируются).

  • Encapsulation - относится к концепции, в которой мы инкапсулируем все данные и функции-члены вместе, чтобы сформировать объект.

  • Constructor - относится к особому типу функции, которая будет вызываться автоматически при формировании объекта из класса.

  • Destructor - относится к особому типу функции, которая будет вызываться автоматически всякий раз, когда объект удаляется или выходит за пределы области видимости.

Определение классов PHP

Общая форма определения нового класса в PHP следующая:

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

Вот описание каждой строки -

  • Особая форма class, за которым следует имя класса, который вы хотите определить.

  • Набор фигурных скобок, заключающий любое количество объявлений переменных и определений функций.

  • Объявление переменных начинается со специальной формы var, за которым следует обычное имя переменной $; им также может быть присвоено начальное постоянное значение.

  • Определения функций очень похожи на автономные функции PHP, но являются локальными для класса и будут использоваться для установки и доступа к данным объекта.

пример

Вот пример, который определяет класс типа Книги -

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

Переменная $this- это специальная переменная, которая относится к тому же объекту, т.е. сам.

Создание объектов в PHP

После того, как вы определили свой класс, вы можете создать любое количество объектов этого типа. Ниже приводится пример того, как создать объект, используяnew оператор.

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

Здесь мы создали три объекта, и эти объекты независимы друг от друга, и они будут существовать отдельно. Далее мы увидим, как получить доступ к функциям-членам и переменным-членам процесса.

Вызов функций-членов

После создания ваших объектов вы сможете вызывать функции-члены, связанные с этим объектом. Одна функция-член сможет обрабатывать только переменную-член связанного объекта.

В следующем примере показано, как установить название и цены для трех книг путем вызова функций-членов.

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

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

Теперь вы вызываете другие функции-члены, чтобы получить значения, установленные в приведенном выше примере -

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

Это даст следующий результат -

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Функции конструктора

Функции-конструкторы - это особый тип функций, которые вызываются автоматически при создании объекта. Итак, мы в полной мере пользуемся этим поведением, инициализируя многие вещи с помощью функций-конструкторов.

PHP предоставляет специальную функцию под названием __construct()для определения конструктора. Вы можете передать в функцию-конструктор любое количество аргументов.

В следующем примере будет создан один конструктор для класса Books, который инициализирует цену и название книги во время создания объекта.

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

Теперь нам не нужно вызывать функцию set отдельно для установки цены и названия. Мы можем инициализировать эти две переменные-члены только во время создания объекта. Проверьте следующий пример ниже -

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

Это даст следующий результат -

Physics for High School
  Advanced Chemistry
  Algebra
  10
  15
  7

Деструктор

Как и функция конструктора, вы можете определить функцию деструктора, используя функцию __destruct(). Вы можете освободить все ресурсы с помощью деструктора.

Наследование

Определения классов PHP могут при желании наследоваться от определения родительского класса с помощью предложения extends. Синтаксис следующий -

class Child extends Parent {
   <definition body>
}

Эффект наследования заключается в том, что дочерний класс (или подкласс, или производный класс) имеет следующие характеристики:

  • Автоматически имеет все объявления переменных-членов родительского класса.

  • Автоматически имеет все те же функции-члены, что и родительский, которые (по умолчанию) будут работать так же, как эти функции в родительском.

Следующий пример наследует класс Books и добавляет дополнительные функции в зависимости от требований.

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

Теперь, помимо унаследованных функций, класс Novel сохраняет две дополнительные функции-члены.

Переопределение функции

Определения функций в дочерних классах переопределяют определения с тем же именем в родительских классах. В дочернем классе мы можем изменить определение функции, унаследованной от родительского класса.

В следующем примере функции getPrice и getTitle переопределяются для возврата некоторых значений.

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

Публичные члены

Если не указано иное, свойства и методы класса являются общедоступными. То есть к ним можно получить доступ в трех возможных ситуациях:

  • Извне класса, в котором он объявлен

  • Изнутри класса, в котором он объявлен

  • Изнутри другого класса, который реализует класс, в котором он объявлен

До сих пор мы видели всех участников как публичных. Если вы хотите ограничить доступность членов класса, вы определяете члены класса какprivate или же protected.

Частные участники

Обозначая член как закрытый, вы ограничиваете его доступность классом, в котором он объявлен. На закрытый член нельзя ссылаться из классов, наследующих класс, в котором он объявлен, и к нему нельзя получить доступ извне.

Член класса можно сделать закрытым с помощью private ключевое слово перед членом.

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

Когда класс MyClass наследуется другим классом с помощью extends, myPublicFunction () будет видимым, как и $ driver. Расширяющийся класс не будет иметь доступа к myPrivateFunction и $ car, поскольку они объявлены закрытыми.

Защищенные члены

Защищенное свойство или метод доступны в классе, в котором они объявлены, а также в классах, расширяющих этот класс. Защищенные члены недоступны вне этих двух типов классов. Член класса может быть защищен с помощьюprotected ключевое слово перед членом.

Вот другая версия 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!");
   }
}

Интерфейсы

Интерфейсы определены для предоставления разработчикам общих имен функций. Различные разработчики могут реализовать эти интерфейсы в соответствии со своими требованиями. Можно сказать, интерфейсы - это скелеты, которые реализуют разработчики.

Начиная с PHP5, можно определить интерфейс, например:

interface Mail {
   public function sendMail();
}

Затем, если другой класс реализовал этот интерфейс, например:

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

Константы

Константа чем-то похожа на переменную тем, что содержит значение, но на самом деле больше похожа на функцию, поскольку константа неизменна. После объявления константы она не меняется.

Объявить одну константу легко, как это сделано в этой версии MyClass -

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

В этом классе requiredMargin является константой. Он объявлен с ключевым словом const и ни при каких обстоятельствах не может быть изменен на что-либо иное, кроме 1.7. Обратите внимание, что имя константы не имеет начального символа $, как имена переменных.

Абстрактные классы

Абстрактный класс - это класс, который нельзя создать, а только унаследовать. Вы объявляете абстрактный класс с ключевым словомabstractвот так -

При наследовании от абстрактного класса все методы, отмеченные как абстрактные в объявлении родительского класса, должны быть определены потомком; кроме того, эти методы должны быть определены с одинаковой видимостью.

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

Обратите внимание, что определениям функций внутри абстрактного класса также должно предшествовать ключевое слово abstract. Недопустимо иметь определения абстрактных функций внутри не абстрактного класса.

Статическое ключевое слово

Объявление членов или методов класса статическими делает их доступными без необходимости создания экземпляра класса. К члену, объявленному как static, нельзя получить доступ с помощью созданного объекта класса (хотя статический метод может).

Попробуйте следующий пример -

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

Последнее ключевое слово

PHP 5 вводит ключевое слово final, которое не позволяет дочерним классам переопределять метод, добавляя к определению префикс 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>";
      }
   }
?>

Вызов родительских конструкторов

Вместо того, чтобы писать совершенно новый конструктор для подкласса, давайте напишем его, явно вызвав родительский конструктор, а затем сделав все, что необходимо в дополнение к созданию экземпляра подкласса. Вот простой пример -

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

В этом примере у нас есть родительский класс (Name), который имеет конструктор с двумя аргументами, и подкласс (NameSub1), который имеет конструктор с тремя аргументами. Конструктор NameSub1 функционирует путем явного вызова своего родительского конструктора с использованием синтаксиса :: (передавая два своих аргумента) и затем устанавливая дополнительное поле. Аналогичным образом NameSub1 определяет свою неконструкторскую функцию toString () в терминах родительской функции, которую он переопределяет.

NOTE- Конструктор может быть определен с тем же именем, что и имя класса. Это определено в примере выше.