Все статьи >> ООП. Наследование классов в php (просмотров: 2008)

ООП. Наследование классов в php

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

Рассмотрим наследование на примере человека. Я – человек. И я наследую некоторые свойства класса Человек, например возможность говорить, интеллект, необходимость в воздухе, воде, пище и всяких витаминах. Эти свойства не уникальны для каждого отдельного человека, т.е. всем людям присуще то, что я перечислил. Мы еще можем заметить, что класс Человек наследует зависимость от воды, воздуха и пищи у класса Млекопитающие. А этот класс наследует эти свойства у класса Животные.

Благодаря наследованию мы можем очень много сэкономить на описании реального объекта. Например, спросите меня – что такое утка? Я отвечу: это птица, которая крякает. Я вроде бы сказал всего 4 слова, но полностью в этих четырех словах уместилась вся необходимая информация для описания утки, потому что сказав «птица, которая крякает», я дал вам знать, что утке присущи все свойства птицы плюс свойство «кряканье»  [icon smile ООП. Наследование классов в php]

Наследуем

Короче тем самым объектно-ориентированные языки позволяют создавать модели, очень близкие к реальному миру. Для примера студентов и аспирантов мы можем сказать, что аспирант – это не простой студент. Он обладает дополнительными свойствами, но одновременно он обладает и всеми свойствами студента. Поэтому мы можем унаследовать класс GraduateStudent (аспирант) от класса Student (студент) с помощью ключевого слова extends:

    class Student {
    }
    class GraduateStudent extends Student {
    }
?>

Тут класс Student будет называться базовым, а класс GraduateStudent – производным.

Наследование еще позволяет нам избавиться от повторения кода, потому что все открытые (public, protected) методы и свойства класса Student становятся доступными и в классе GraduateStudent. Помните, в статье ранее я говорил, что модификаторы доступа методов/свойств private и protected отличаются? Вот. Если у нас есть свойство (или метод) private в классе Student, то оно не будет доступно в классе GraduateStudent:

    class Student {
        private   $mark;
        protected $average;
    }

    class GraduateStudent extends Student {

        function someFn() {
            $this->mark = 5;      // Ошибка доступа!
            $this->average = 4.4; // А так правильно
        }

    }
?>

Кстати. Помните, что если свойство или метод в классе не имеют модификатора доступа, то по умолчанию они public? Видимо это было введено для совместимости с предыдущими версиями пхп, где модификаторов еще не было, а все члены класса были публичными.

Вспомним еще конструкторы и деструкторы. Так вот, если нам надо вызвать конструктор или деструктор базового класса, то надо это делать явно, через указатель parent:

    class MyClass {
        function __construct() {
            echo "Запущен конструктор базового класса";
        }
        function __destruct() {
            echo "Запущен деструктор базового класса";
        }
    }

    class MyClass1 extends MyClass {
        function __construct() {
            parent::__construct();
        }
        function __destruct() {
            parent::__destruct();
        } 
    }  

    $obj = new MyClass1(); // Выводит "Запущен конструктор базового класса"
    unset($obj);           // Выводит "Запущен деструктор базового класса"
?>

Сейчас это может показаться лишним, но в реальной практике это зачастую очень нужно. Я знаю это по собственному опыту написания программ на C#.

Абстрактные классы и методы

Это тоже новинка в PHP5. Абстрактные методы имеют только объявление и не имеют реализации. Класс, который содержит такие методы, должен быть обязательно объявлен как абстрактный:

    abstract class MyClass {
        abstract public function fn();
    }
?>

Т.е. если бы мы написали так…

    abstract class MyClass {
        abstract public function fn() {
        }
    }
?>

…интерпретатор пхп заругался бы на нас.

Абстрактные классы могут еще содержать и обычные (не абстрактные) элементы. Создать объект абстрактного класса мы не имеем права. Можно только определять новые классы от базового абстрактного класса и создавать объекты уже от производных классов.

А зачем тогда нужны абстрактные методы и классы? А чтобы описать объект, который будет реализован, но который еще не реализован.

А здесь я приведу пример, как использовать абстрактный метод базового класса в производном классе:

    abstract class MyClass {
        abstract public function fn();
    }

    class MyClass1 extends MyClass {
        public function fn() {
            echo “привет”; 
        }
    }

    $obj = new MyClass1;
    $obj->fn(); // Выводит “привет”
?>

Интерфейсы

В моем понимании интерфейс – нечто, с помощью чего мы можем управлять объектом. Например, возьмем телевизор. У него есть интерфейс – панель с кнопками спереди под экраном или справа (слева) от экрана. Ну пульт управления – это тоже интерфейс. Т.е. большинство из нас не знает, как сделан телевизор и как он работает, но мы знаем, как им можно управлять (переключать каналы, настраивать громкость, яркость и т.д.). То же самое было придумано и в программировании.

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

Основное отличие интерфейсов от абстрактных классов – в том, что в PHP 5 класс не может быть порожден от нескольких классов (и абстрактных в т.ч.), но зато может быть создан на основе любого числа интерфейсов. При этом в интерфейсе методы должны объявляться ключевым словом function без указания всяких спецификаторов (в т.ч. и abstract):

    interface Inter1 {
        function fn1();
    }

    interface Inter2 {
        function fn2();
    }

    class MyClass implements Inter1, Inter2 {
        public function fn1() {
            echo 1;
        }
        public function fn2() {
            echo 2;
        }
    }
    $obj = new MyClass;
    $obj->fn1(); // Выведет 1
    $obj->fn2(); // Выведет 2
?>

Также в ООП есть такое понятие, как множественное наследование. Суть его в том, что один и тот же класс может иметь несколько базовых классов. Но для PHP5 это не совсем справедливо. В PHP5 класс не может быть унаследован от нескольких базовых классов, но зато может реализовать сколько угодно интерфейсов, как показано в последнем примере.

Финальные методы и классы

Интересная возможность в пхп 5, на которую я наткнулся в ходе изучения ООП, – это возможность определять финальные методы и классы.

Метод, который мы определили с ключевым словом final, в дальнейшем мы не можем переопределить в классах, которые производны от нашего класса:

    class MyClass {
        final public function fn() {
            // Код метода
        }
    }
    class MyClass1 extends MyClass {
        // Следующий код вызывает ошибку 
        // переопределения финального метода
        // базового класса MyClass
        public function fn() {
            // Код метода 
        }
    }
?>

И еще: если мы используем final при определении самого класса, то не сможем больше породить от него другие классы:

    final class MyClass {
        // Код описания класса
    }

    // Следующий код вызывает ошибку
    // порождения от финального класса
    class MyClass1 extends MyClass {
        // Код описания класса
    }
?>

Тут заметим, что если класс определен как final, то и все методы этого класса автоматически станут финальными, и определять их явно как final уже не надо.

А как насчет свойств? Свойства класса определять финальными нельзя. Ну в этом не было бы смысла, думаю. Потому что, в отличие от методов, мы не можем переопределять свойства класса. Мы можем их только наследовать.

Выводы

На этом я почти заканчиваю рассмотрение объектно-ориентированного программирования в PHP5. Осталась только одна очень важная вещь – это полиморфизм. Но о ней я вскоре расскажу в другой статье. Надеюсь, я доступно объяснил то, что сам недавно изучил  [icon smile ООП. Наследование классов в php]


Автор: i-novice.net
 
 
Email:
не зарегистрированы?
Пароль:
забыли?
 
Астраханские магазины