Три кита ООП - Наследование, инкапсуляция, полиморфизм
Войти

Три кита ООП - Наследование, инкапсуляция, полиморфизм

Наследование, инкапсуляция, полиморфизм.

Три кита объектного ориентирования это: наследование, инкапсуляция и полиморфизм.

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php 

class Animal 
    
function draw 
        
return "just animal";
    
 
    function 
eat 
        
return "the animal is eating";
    

 
class 
Cow extends Animal 
    
function draw 
        
Return "something that looks like a cow";

?>

Как видите здесь Корова (Cow) унаследовала функционал от Животного (Animal), изменив реализацию метода draw (конкретизируя как корова на самом деле выглядит), и оставив реализацию метода eat(). Это и есть наследование.

Теперь инкапсуляция. Сам по себе этот термин означает «сокрытие». Инкапсуляция, это способ сделать невозможным изменения критичных для работы класса свойств или вызова внутренних методов.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 

сlass Animal 
 
    
private $name;
 
    function 
__construct$name 
        $this
->name $name;
    
 
    function 
getName 
        
return $this->name;
    
 
    ...
?>

Вот это и есть инкапсуляция. Нет способа изменить кличку снаружи класса, и вы можете быть уверены, что в любом случае, кличка у экземпляра класса будет именно та, что была задана при создании. Ну а теперь полиморфизм. Это тут тоже начнем с примера. Добавим класс Sheep (овца).

1
2
3
4
5
6
7
8
<?php 
 
class Sheep extends Animal 
 
    
function draw 
        
return 'something that looks like a sheep';
    
?>

Теперь, предположим что у нас есть класс какого-то животного (любого), и мы всегда можем узнать как оно выглядит, абсолютно независимо от его типа (другими словами с экземпляром какого класса мы имеем дело).

draw(); ?>

Данный пример будет случайным образом генерировать экземпляр Коровы и Овцы, и рисовать их. Нужно сказать что данный пример не совсем «чистый» полиморфизм. Дело в том что полиморфизм подразумевает собой реализацию одного и того же интерфейса в разных классах. Объясню: если бы мы не реализовали метод draw() в одном из классов, у нас переодически возникала бы ошибка обращения к несуществующему методу, а в языках со строгой типизицией, ошибка бы возникала еще на стадии компиляции. Чтобы избежать подобных казусов, нужно использовать итерфейсы (interface):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 

interface IDrawable 
 
    
function draw;
 

 
class 
Cow extends Animal implements IDrawable 
 
    
function draw 
        
return 'something that looks like a cow';
    
 

 
class 
Sheep extends Animal implements IDrawable 
 
    
function draw 
        
return 'something that looks like a sheep';
    
 
?>

Как только вы указали, что класс должен реализовывать интерфейс, компилятор или интерпретатор берет на себя обязательство проконтролировать что в классе реализованы методы, описанные в интерфейсе, что позволяет отлавливать ошибки еще до запуска приложения. Вот собственно и всё.



Ссылки по теме:

  1. habrahabr.ru
Теги:
php