Учебники

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

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

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

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

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

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

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

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

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

  • Родительский класс — класс, унаследованный от другого класса. Это также называется базовым классом или суперклассом.

  • Дочерний класс — класс, который наследуется от другого класса. Это также называется подклассом или производным классом.

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

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

  • Абстракция данных — любое представление данных, в котором скрыты (абстрагированы) детали реализации.

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

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

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

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

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

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

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

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

Родительский класс — класс, унаследованный от другого класса. Это также называется базовым классом или суперклассом.

Дочерний класс — класс, который наследуется от другого класса. Это также называется подклассом или производным классом.

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

Перегрузка — это тип полиморфизма, при котором некоторые или все операторы имеют разные реализации в зависимости от типов их аргументов. Аналогично функции также могут быть перегружены с другой реализацией.

Абстракция данных — любое представление данных, в котором скрыты (абстрагированы) детали реализации.

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

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

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

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

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

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

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

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

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

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

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

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

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

Объявления переменных начинаются со специальной формы 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

Destructor

Как и функция конструктора, вы можете определить функцию деструктора, используя функцию __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, вы ограничиваете его доступность классом, в котором он объявлен. На закрытый член нельзя ссылаться из классов, которые наследуют класс, в котором он объявлен, и к нему нельзя получить доступ извне класса.

Член класса может быть сделан приватным с помощью частного ключевого слова перед участником.

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, потому что они объявлены закрытыми.

Защищенные участники

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

Вот другая версия 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. Недопустимо иметь определения абстрактных функций внутри неабстрактного класса.

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

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

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

<?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. Если сам класс определяется как 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 () в терминах родительской функции, которую она переопределяет.

ПРИМЕЧАНИЕ. — Конструктор может быть определен с тем же именем, что и имя класса. Это определено в приведенном выше примере.