1. Теперь за форумную активность начисляются биткоины и другие криптоденьги. Подробнее.
    Скрыть объявление
  2. Появилась архивная версия форума arhiv.xaker.name, где собраны темы с 2007 по 2012 год.
    Скрыть объявление

Классы и объекты PHP, основы

Тема в разделе "PHP, Perl и др.", создана пользователем Хулиган, 27 янв 2014.

  1. Хулиган
    Хулиган Команда форума Продвинутый
    Симпатии:
    242
    Инициализация класса (создание объекта)​

    Объект класса - представитель класса, который имеет свое уникальное состояние и поведение.
    Для объявления объекта необходимо использовать оператор new:

    Объект = new Имя_класса;

    PHP:
    $myObj = new newClass();
    Свойства класса​

    Свойство – это переменные, хранимые в классе; перед именем свойства ставится один из следующих модификаторов (public, protected, private). Также есть ключевое слово var, но его время ушло (остался в 4-й версии PHP).

    Описание свойств

    PHP:
    class newClass {
        public 
    $property1;
        protected 
    $property2 "value2";
        private 
    $property3;
    }
    Доступ к свойствам класса​

    Доступ к свойствам класса за пределами класса реализуется так: объект->имя_свойства; (знак доллара у свойства не ставится!)

    PHP:
    $myObj = new newClass();
    $myObj->property1;
    Изменение значения свойств​


    PHP:
    $myObj->property2 "Тут меняем значение";
    Методы класса​

    Метод – это функция, определенная внутри класса. У функции по умолчанию стоит модификатор public (то есть его можно не писать перед функцией).

    Описание методов​


    PHP:
    class newClass {
        function 
    myMethod($var1,$var2){ // по умолчанию это
                                        // общедоступный метод (public)
            // операторы
        
    }
    }
    Вызов метода​


    PHP:
    $myObj = new newClass();
    $myObj->myMethod('v1','v2');

    $this
    Доступ к свойству класса внутри класса реализуется при помощи оператора($this):
    $this-> имя_свойства; (знак доллара у свойства не ставится!)

    Доступ к методу класса из другого метода класса также осуществляется с помощью ключевого слова $this.

    PHP:
    class newClass {
        public 
    $property1;
        function 
    myMethod(){
            echo(
    $this->property1); // Вывод значения свойства
        
    }
        function 
    callMethod(){
            
    $this->myMethod();  // Вызов метода
        
    }
    }

    Конструкторы и деструкторы​

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

    Деструктор – специальный метод, который автоматически вызывается при удалении объекта. P.s. Порядок удаления объектов не определен, но стоит отметить, что объекты удалятся по завершении кода (порядок удаления объектов определить нельзя), и вызовется метод __destruct. Объект можно удалить принудительно: unset(имя_объекта).

    PHP:
    class newClass {
        public 
    $property;

        function 
    __construct($var){
            
    $this->property $var;
            echo 
    "Вызываем конструктор";
        }

        function 
    __destruct(){
            echo 
    "Вызываем деструктор";
        }
    }

    $obj = new newClass("Значение"); //Вызываем конструктор
    unset($obj); //Вызываем деструктора (принудительно)
    Псевдо-константы __METHOD__ и __CLASS__
    Псевдо-константы __METHOD__ и __CLASS__ . Вместо __METHOD__ будет подставлено: имя_класса::имя_метода; __CLASS__ будет подставлено имя_класса.

    PHP:
    class newClass {
        function 
    myMethod(){
            echo 
    __METHOD__;
        }
        function 
    getClassName(){
            echo 
    __CLASS__;
        }
    }
    $obj = new newClass();
    $obj->myMethod();// newClass::myMethod
    $obj->getClassName();// newClass

    Новые принципы работы с объектами​

    Объекты передаются по ссылке, а не по значению

    PHP:
    class newClass {
        public 
    $property;
    }
    $myObj = new newClass();
    $myObj->property 1;
    $myObj2 $myObj;
    $myObj2->property 2;
    print(
    $myObj->property); // Выведет 2
    print($myObj2->property); // Выведет 2
    Клонирование объекта​

    При клонировании (clone) конструктор не вызывается. Существует специальный метод __clone, который вызывается при клонировании объекта.

    Явное копирование объектов

    PHP:
    class newClass {
        public 
    $property;
    }

    $myObj = new newClass();
    $myObj->property 1;
    $myObj2 = clone $myObj// создаем копию объекта, в 4-й версии php было так: $myObj2 = &$myObj;
    // в 5-й версии PHP & с объектами не работает
    $myObj2->property 2;
    print(
    $myObj->property); // Печатает 1
    print($myObj2->property); // Печатает 2
    Наследование(полиморфизм)​

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

    PHP:
    class Machine {
        public 
    $numWheels 4;
        function 
    printWheels() { echo $this->numWheels; }
    }

    class 
    Toyota extends Machine {
        public 
    $country 'Japan';
        function 
    printCountry() { echo $this->country; }
    }

    $myMachine = new Toyota();
    $myMachine->printWheels();
    $myMachine->printCountry();
    Перегрузка методов​

    Перегрузка методов – в классе, который наследует другой класс, можно описать такой же метод, который есть в родительском классе, причем вновь описанный метод перезапишет метод родительского класса. Пример:

    PHP:
    class Machine {
        public 
    $numWheels 4;
        function 
    printWheels() { echo $this->numWheels; }
    }
    class 
    Toyota extends Machine {

        public 
    $country 'Japan';
        function 
    printCountry() { echo $this->country; }

        function 
    printWheels() {
            echo 
    "Перегруженный метод printWheels() ";
        }
    }
    $myMachine = new Toyota();
    $myMachine->printWheels();
    Parent​

    parent::имя_метода, данная конструкция позволяет обратиться к родительскому методу.

    PHP:
    class Machine {
        public 
    $numWheels 4;
        function 
    printWheels() { echo $this->numWheels; }
    }
    class 
    Toyota extends Machine {
        public 
    $country 'Japan';

        function 
    printWheels() {
            echo 
    "Перегруженный метод printWheels() ";
            
    parent:: printWheels();
        }
    }

    $myMachine = new Toyota();
    $myMachine->printWheels();
    Модификаторы доступа: public, protected, private

    public (общедоступный) - позволяет иметь доступ к свойствам и методам классам из любого места

    protected (защищенный) - позволяет иметь доступ и родительскому (в котором определен сам член класса), и наследуемым классам

    private (закрытый) - ограничивает область видимости так, что доступ к нему имеет только тот класс, в котором объявлен сам элемент

    Модификаторы доступа: как это работает?​


    PHP:
    $obj = new newClass();
                    echo 
    $obj->public//ДА
                    
    echo $obj->protected//НЕТ!
                    
    echo $obj->private//НЕТ
                    
    $obj->myMethod();
    PHP:
    class newClass {
                        public 
    $public 1;
                        protected 
    $protected 2;
                        private 
    $private 3;
                        function 
    myMethod(){
                            echo 
    $this->public//ДА
                            
    echo $this->protected//ДА
                            
    echo $this->private//ДА
                        
    }
                    }
    PHP:
    $obj1 = new NewClass();
                    echo 
    $obj1->public//ДА
                    
    echo $obj1->protected//НЕТ!
                    
    echo $obj1->private//НЕТ
                    
    $obj1->newMethod();
    PHP:
    class NewClass extends newClass {
                        function 
    newMethod(){
                            echo 
    $this->protected//ДА
                            
    echo $this->private//НЕТ
                            
    $this->myMethod();
                        }
                    }
    Обработка исключений​

    У нас есть кусок кода, в котором может произойти какая-нибудь ошибка; данный кусок кода помещается в блок под названием try; в том месте, где-может произойти ошибка, ставится ключевое слово throw; для отлова произошедшей ошибки описывается блок catch (ловушка), туда приходит ошибка, с которой мы можем работать.

    PHP:
    try {
        
    $a 1;
        
    $b 0;
        if(
    $b == 0) throw new Exception("Деление на 0!");
        echo 
    $a/$b;
    }
    catch(
    Exception $e){
        echo 
    "Произошла ошибка - ",
        
    $e->getMessage(), // Выводит сообщение  " в строке ",
        
    $e->getLine(), // Выводит номер строки " файла ",
        
    $e->getFile(); // Выводит имя файла
    }
    Создание собственных исключений

    PHP:
    сlass MathException extends Exception {
        function 
    __construct($message) {
            
    parent::__construct($message);
        }
    }
    try {
        
    $a 1;
        
    $b 0;
        
    // MathException - имя класса  для создания собственного исключения
        
    if ($b == 0) throw new MathException("Деление на 0!");
        echo 
    $a $b;
    } catch (
    MathException $e) {
        echo 
    "Произошла математическая ошибка ",
        
    $e->getMessage(),
        
    " в строке "$e->getLine(),
        
    " файла "$e->getFile();
    }
    Перебор свойств объекта​


    PHP:
    class Person {
        public 
    $name;
        public 
    $yearOfBorn;
        function 
    __construct($name$yearOfBorn){
            
    $this->name $name;
            
    $this->yearOfBorn $yearOfBorn;
        }
    }
    $billGates = new Person(‘Bill Gates’,1955);
    foreach(
    $billGates as $name=>$value){
        print(
    $name..$value.
    );
    }
    Константы класса​

    Константы – это константы класса, то есть они не принадлежат ни одному объекту. За пределами кода к константе можно обратиться следующим образом: имя_класса::имя_константы. Если мы хотим обратиться к константе в пределах класса, то нужно использовать ключевое слово self: self::имя_константы.


    PHP:
    class Person {
        const 
    HANDS 2;
        function 
    printHands(){
            print (
    self::HANDS);// NOT $this! Обращаемся к константе внутри класса
        
    }
    }
    print (
    'Количество рук: '.Person::HANDS); // Обращаемся к константе за пределами класса
    Абстрактные методы и классы​

    Абстрактный класс в php - это так называемый базовый класс, не предназначенный для создания его экземпляров (объектов). Основной смысл и назначение абстрактных классов заключается в расширении возможностей его дочерних классов.

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

    В абстрактном классе могут быть абстрактные методы (перед function стоит ключевое слово abstract). Абстрактный метод – это метод без реализации (отсутствуют фигурный скобки).

    Абстрактный метод обязательно должен быть описан (перезагружен) в классе-наследнике. Преимущество в использовании абстрактных методов: для каждого класса-наследника можно описать свое уникальное поведение абстрактного метода.

    PHP:
    abstract class Machine {  // абстрактный класс
        
    public $petrol;
        function 
    startEngine(){
            print(
    'Двигатель зав?лся!');
        }
        abstract function 
    stopEngine();
    }
    class 
    InjectorMachine extends Machine {
        public function 
    stopEngine(){
            print(
    'Двигатель остановился!');
        }
    }
    $myMegaMachine = new Machine();//Ошибка!
    $myMegaMachine = new InjectorMachine();
    $myMegaMachine->startEngine();
    $myMegaMachine->stopEngine();
    Интерфейсы​

    Существует еще один тип абстрактного класса – интерфейс. Интерфейс – это абстрактный класс, который содержит только абстрактные методы. Перед таким классом вместо слова abstract пишется interface. От интерфейса наследование происходит не через ключевое слово extends, а через ключевое слово implements.

    PHP:
    interface Hand {
        function 
    useKeyboard();
        function 
    touchNose();
    }
    interface 
    Foot {
        function 
    runFast();
        function 
    playFootball();
    }

    class 
    Person implements Hand
    {
        public function 
    useKeyboard(){
            echo 
    'Use keyboard!';
        }
        public function 
    touchNose(){
            echo 
    'Touch nose!';
        }
        public function 
    runFast(){
            echo 
    'Run fast!';
        }
        public function 
    playFootball(){
            echo 
    'Play football!';
        }
    }
    $vasyaPupkin = new Person();
    $vasyaPupkin->touchNose();
    Финальные методы и классы​

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

    PHP:
    class Mathematics {
        final function 
    countSum($a,$b){
            print(
    'Сумма: ' $a $b);
        }
    }
    class 
    Algebra extends Mathematics {
        
    // Возникнет ошибка
        
    public function countSum($a,$b){
            
    $c $a $b;
            print(
    "Сумма $a и $b$c");
        }
    }
    PHP:
    final class Breakfast // финальный класс
        
    function eatFood($food){
            print(
    "Скушали $food!");
        }
    }
    // Возникнет ошибка
    class McBreakfast extends Breakfast
    {
        
    // Описание класса
    }
    Статические свойства и методы класса​

    Статические методы и свойства класса (плюс константы класса) принадлежат классу, то есть они общие для всех объектов класса. К ним нельзя обратиться посредством ‛стрелки‛, а только через :: (внутри класса используется: self::$имя_свойства; за пределами класса: имя_класса::$имя_свойства). Статическое свойство, как и метод, объявляется через ключевое слово static. Как вы догадываетесь, внутри статического метода this использовать нельзя (такие методы не связаны с объектами).

    PHP:
    class CookieLover {
        static 
    $loversCount 0// это статическое свойство, и компилятор не
                                 // будет его удалять после завершения работы  функции __construct

        
    function __construct(){
            ++
    self::$loversCount;
        }

        static function 
    welcome(){
            echo 
    'Добро пожаловать в клуб любителей булочек!';
            
    //Никаких $this внутри статического метода!
        
    }
    }

    $vasyaPupkin = new CookieLover();
    $frosyaBurlakova = new CookieLover();
    print (
    'Текущее количество любителей булочек: '.CookieLover::$loversCount);
    print (
    CookieLover::welcome());
    Ключевое слово instanceof​

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

    PHP:
    class Person {}
    $myBoss = new Person();
    if(
    $myBoss instanceOf Person) print('Мой Босс – человек!');
    // вернет true, если класс Person есть в предках объекта $myBoss

    class Woman extends Person {}
    $englishQueen = new Woman();

    if(
    $englishQueen instanceOf Person) print('Английская королева – тоже человек!');

    interface 
    LotsOfMoney {}
    class 
    ReachPeople implements LotsOfMoney {}
    $billGates = new ReachPeople();

    if(
    $billGates instanceOf LotsOfMoney) print('У Билла Гейтса много денег!');
    Функция __autoload()​

    Если PHP натыкается на несуществующий класс, при инициализации объекта, то он ищет функцию __autoload, передавая в функцию __autoload имя неназванного класса. И PHP вызовет эту функцию перед выводом ошибки об отсутствии класса.

    PHP:
    function __autoload($cl_name){ // $cl_name - имя не найденного класса
        
    print('Попытка создать объект класса '.$cl_name);
    }
    $obj = new undefinedClass();
    Методы доступа к свойствам объекта​

    Метод __set() будет выполнен при записи данных в недоступные свойства (которых нет в классе).

    Метод __get() будет выполнен при чтении данных из недоступных свойств (которых нет в классе).

    PHP:
    class newClass {
        private 
    $properties;
        function 
    __get($name){
            print(
    "Чтение значения свойства $name");
            return 
    $this->properties[$name];
        }
        function 
    __set($name,$value){ // в нашем случае $name это property, $value равно 1
            
    print("Задание нового свойства $name = $value");
            
    $this->properties[$name] = $value;
        }
    }

    $obj = new newClass;
    $obj->property 1// Запись нового свойства
    $a $obj->property// Чтение значения свойства
    print $a// 1
    Перегрузка вызова несуществующих методов​

    Если мы обращаемся к методу которого нет, то PHP ищет метод __call (1-й параметр – это имя несуществующего метода, 2-й – массив аргументов).

    PHP:
    class newClass {
        function 
    __call($name$params){
            print(
    "Попытка вызова метода $name со следующими параметрами: ");
            
    print_r($params);
        }
    }

    $obj = new newClass();
    $obj->megaMethod(1,2,3,"четыре");
    Метод __toString()​

    Метод __toString() позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку. Например, что напечатает echo $obj;. Этот метод должен возвращать строку, иначе выдастся неисправимая ошибка E_RECOVERABLE_ERROR.

    PHP:
    class newClass {
        function 
    __toString(){
            return 
    'Вызван метод __toString()';
        }
    }

    $obj = new newClass();
    // Вызван метод __toString()
    echo $obj;
    (c) dnzl​
     
    27 янв 2014
    1 человеку нравится это.
  2. Hookman
    Hookman Developer Глобальный модератор
    Симпатии:
    241
    Говорить что интерфейс это тип абстрактного класса считаю грубейшей ошибкой.

    Интерфейс определяет какие методы должен реализовывать класс который его имплементирует, и в то же время не содержит реализации этих методов. Любой класс может имплементировать несколько интерфейсов.
    PHP:
    // Серверу не важно какой именно клиент, ему важно чтобы у него были методы интерфейса, чтобы его опросить
    $server->ask(Askable $client);
    Абстрактный класс определяет базовую структуру всех дочерних классов, может содержать как абстрактные методы, так и реализованные.
    PHP:
    //Имя любой машины будет передаваться в конструкторе у любого из потомков, поэтому метод getName можно реализовать уже в базовом классе. А скорость, положим, будет определяться у каждого потомка по-своему.
    abstract class Car {
        abstract public function 
    getSpeed();
        
    publict function getName()
        { echo 
    $this->name; }
    }
    Абстрактный класс является начальным структурным элементом иерархии классов, а интерфейс позволяет строить абстрактные договоренности в вашем API.

    Почитайте про проблемы множественного наследования и откуда всялись интерфейсы. Так же советую ознакомиться с принципом Inversion of Control
     
    Последнее редактирование: 17 фев 2014
    12 фев 2014

Поделиться этой страницей

Загрузка...