ООП для “чайников”. Наследование, инкапсуляция, полиморфизм – три кита объектного ориентирования.

Три кита объектного ориентирования это: наследование, инкапсуляция и полиморфизм. Без четкого понимания этих вещей программисту тяжело написать хороший объектно-ориентированный код, использовать всю силу этого подхода, а главное устроится на хорошую работу.
В прошлый раз я рассказывал о классах, объектах, свойствах и методах, если с этими понятиями проблем не возникает, дальше тоже всё будет очень просто. Для наглядности я буду приводить короткие куски кода на PHP (на самом деле язык тут не важен, просто мне кажется это самый распространенный на сегодня синтаксис, хоть и более классическим для примеров ООП является java, мне кажется 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(). Это и есть наследование. Теперь инкапсуляция. Сам по себе этот термин означает «сокрытие». Инкапсуляция, это способ сделать невозможным изменения критичных для работы класса свойств или вызова внутренних методов. Например у нас есть требование: каждое животное должно иметь кличку, и кличка, в течении его жизни не должна меняться. Самое правильное в таком случае это принимать кличку в качестве параметра конструктора (метода выполняемого при создании класса), и хранить его во внутреннем, сокрытом свойстве. Например так:

сlass Animal {
	
	private $name;
	
	function __construct($name) {
		$this->name = $name;
	}
	
	function getName() {
		return $this->name;
	}	
	
	...
	
}

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

class Sheep extends Animal {

	function draw() {
		return 'something that looks like a sheep';
	}		
	
}

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

$animal = rand(0,1) ? new Cow('burenka') : new Sheep('kudryashka');
echo $animal->draw();

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

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

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

Comments

comments

14 thoughts on “ООП для “чайников”. Наследование, инкапсуляция, полиморфизм – три кита объектного ориентирования.”

  1. Стремная тема, это ООП. Вроде всё просто и понятно, а как возьмешься “для чайников” – хрен поймешь, как без кода объяснить. Но и примеры на языке давать нельзя, надо как-то без них пытаться начинающему мозги вправить. Я вот вообще недавно начал это писательское дело. Подозреваю, что тоже не сильно преуспел в понятности изложения подобных вещей.

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

    Ну очень понятная фраза для чайников :)))) Откуда оно знает, что имеется в виду под интерфейсом. Программный интерфейс, API-интерфейс или implements ISomething? :))))

  2. Да уж. Предыдущая запись про собак и кошек с присвоением имени и отчества хозяину была написана как-то понятнее…)

  3. но все же это лучше, чем Колин Мук на совершенно неподготовленную насквозь гуманитарную почву)

  4. ————-
    Согласен. Готов рассмотреть любые версии по упрощению языка.
    ————-
    Я хоть не мегаавторитет, но могу посоветовать отрешиться от какого бы то ни было конкретного языка и попытаться объяснить “на пальцах” и показать “на кошках”. Зверски трудно, но и результат, по идее, должен быть понятней даже какому-нить проджект менеджеру :))))))

  5. Я просто только вот написал нечто подобное (по ссылке на нике в разделе “теория”). только у меня одна статья про одно свойство ООП занимает, как у вас про все три. Уж не знаю, недостаток это, или наоборот, не стоит пытаться столь трудное для понимания неподготовленным умом быстро описать.

  6. Спасибо автору!
    Теперь все понятно!

  7. Большое спасибо автору! Все очень доходчиго объясняется.

  8. Спасибо!! благодаря автору сдал зачет по программированию :)

  9. Не так ясно как с собаками и кошками при объяснении класса и элземпляра класса. Но все же большое спасибо автору за его труд.

  10. Про полиморфизм так и не понял совсем, инкапсуляцию – частично. Но нигде пока более понятное объяснение не нашел.

  11. Я считаю, что писать надо в правильной терминологии, даже если это для чайников, пусть чайник развивается))

  12. Здравствуйте.
    Вопрос про инкапсуляцию. Правильно ли я понимаю, что если кличка “private”, то при создании объекта она будет наследоваться без изменений?

  13. Если private то он будет доступен только в рамках этого класса, из наследника доступа не будет, более того, в наследнике может быть свой private.

Leave a Reply