
- •1. Событийно-управляемое приложение: событие, типы событий, сообщение, обработчик, механизм обмена сообщениями, очередь сообщений.
- •3. Жизненный цикл объектов: создание, уничтожение, конструкторы, деструкторы. Автоматическое управление памятью. Утечка памяти. Создание объектов с помощью различных конструкторов.
- •4. Наследование, типы видимости, типы наследования. Композиция, агрегация, ассоциация, зависимость. Композиция или наследование, в чём отличие и в чём похожесть.
- •6. Полиморфизм: переопределение и перекрытие методов. Вызов унаследованных методов. Варианты реализации в разных языках. Виртуальный деструктор.
- •7. Приведение типов. Правила, цель, стандартные приемы. Самостоятельная реализация, варианты реализации в разных языках.
- •8.Grasp-паттерны: информационный эксперт, низкая связность, высокое зацепление. Антипаттерны.
- •Золотой молоток (Golden hammer)
- •9. Бесклассовое (прототипно-ориентированное) ооп
- •10. Множественное наследование, интерфейсы и примеси (mixins).
- •11. Делегирование, объектная шизофрения.
- •13. Solid – принципы: sol.
- •14. Solid – принципы: id.
- •15. Объектная интроспекция и рефлексия.
- •16. Язык uml (диаграммы классов, состояний, последовательностей).
- •17. Архитектура Model–View–Controller (mvc) и её варианты. Самый простой способ её нарушить и исправить.
- •17. Одинарная и двойная диспетчеризация.
- •17. Покажите, как с помощью паттерна Prototype можно создавать копии любых объектов, не зная о конкретном классе каждого объекта.
- •18. Требуется создать такой класс, для которого в приложении не может существовать больше одного экземпляра. Опишите ситуацию, в которой это может потребоваться и решение с помощью паттерна Singleton
- •20. Покажите, как с помощью паттерна Decorator динамически (во время выполнения программы) видоизменять поведение объектов.
- •22. Инкапсулируйте любое действие в программе в отдельный объект, и покажите, как паттерн Command позволяет при этом манипулировать такими объектами и реализовывать отмену действий.
- •25. Покажите, как с помощью паттерна Observer можно реализовать динамическую (в момент работы программы) подписку одних объектов на уведомления об изменении других объектов.
- •26. Покажите, как с помощью паттерна Strategy реализуются различные варианты реализации одной и той же функциональности объекта.
- •30. Требуется в имеющейся функциональной иерархии объектов динамически изменять внутреннюю реализацию любого объекта. Покажите, как это может быть сделано с помощью паттерна Bridge.
- •31. Покажите, каким образом с помощью паттерна Visitor можно добавить новую функциональность целой иерархии потомков одного базового класса, не изменив ни одного класса этой иерархии.
6. Полиморфизм: переопределение и перекрытие методов. Вызов унаследованных методов. Варианты реализации в разных языках. Виртуальный деструктор.
Полиморфизм — возможность работать с несколькими типами так, как будто это один тип, при этом поведение типов будет отличаться в зависимости от их реализаци. Концепция полиморфизма выражается в идее “один интерфейс — множество реализаций”. Полиморфизм позволяет манипулировать объектами единым образом с помощью создания для них общего интерфейса. контейнер
Полиморфизм обеспечивается использованием производных классов и переопределением в них виртуальных функций базового класса.
Переопределение метода – повторное определение метода, который есть в предке, в потомке. Перекрытие метода – переопределение виртуального метода.
Виртуальная функция — функция, которую предполагается переопределить в производных классах. При ссылке на объект производного класса с помощью указателя на базовых класс можно вызывать виртуальную функцию для этого объекта и выполнить версию функции производного класса. Виртуальные функции обеспечивают вызов соответствующей функции для объекта независимо от выражения, используемого для вызова функции.
class Animal{ virtual void sound(){printf(“!!”);} }; class Cat : public Animal{ void sound(){printf(“Mew”);} }; class Dog : public Animal{ void sound(){printf(“Wow”);} }; Animal a = new Cat; Animal a1 = new Dog; a->sound() //mew a1->sound() //wow
Наследование как возможность воспользоваться уже готовым классом, но дополнить и расширить его, и все вытекающие отсюда способы заменить и расширить существующую функциональность – например, вызов унаследованных методов предка;
Для невиртуальных методов адрес вызова одинаков и известен заранее на момент компиляции (раннее связывание). Для виртуального метода адрес реального вызова на момент компиляции неизвестен и берется из таблицы в момент вызова метода (позднее связывание).
Виртуальными должны быть все деструкторы. Заметьте, кстати, что в случае виртуального деструктора вызывается не только он, но и все деструкторы предков в обратном порядке, как положено. Итак, общее правило: виртуальный деструктор в базовом классе обязательно нужен тогда, когда вы создаёте объекты классов-потомков и храните их в переменных классов-предков. В этом случае при удалении объекта-потомка, лежащего в переменной класса-предка, вызовется полная корректная последовательность деструкторов, а не только деструктор класса-предка.
Абстрактный класс – класс у которого хоть один метод абстрактный. В С++ virtual void foo() = NULL;
Объекты абстрактного класса создавать нельзя. Потомки должна переопределять все абстрактные методы, иначе они тоже абстрактные.
7. Приведение типов. Правила, цель, стандартные приемы. Самостоятельная реализация, варианты реализации в разных языках.
Приведение типа — преобразование значения одного типа в значение другого типа.
Выделяют приведения явные и неявные. Явное приведение задается программистом в коде, например, при помощи специальных конструкций языка. Неявное приведение выполняется компилятором при, например, вычислении арифметических выражений.
Явное приведение может быть безопасным (с проверкой) или небезопасным (без проверки). Пример небезопасного:
Animal a = new Cat();
((Cat) a).chase();
Для безопасного приведения типов можно использовать механизмы используемого языка или ручную проверку типов:
● с помощью виртуального метода getClassName(), недостаток которого состоит в том, что он не учитывает иерархию классов; if (a->getClassName() == “Cat”) ((Cat*)a)->catch();
● с помощью виртуального метода isA(String _who), который этого недостатка лишен. bool isA(string who){ return (who == getClassName() || Base::isA(who)); //Base - имя класса ближайшего предка
В C++ можно использовать, например, dynamic_cast:
Cat* c = dynamic_cast<Cat *>(a); if (c!= NULL) c->catch();
Если приведение успешно, то вернется указатель нужного типа, иначе NULL.
Цель приведение типов — например, использование специфических методов дочерних классов при хранении объектов в хранилище родительского типа.