Ответы пользователя по тегу ООП
  • Наследование в ООП - стоит ли широко применять?

    Foror
    @Foror
    Графоман
    Есть области, где без наследования не обойтись, например, в разработке GUI, когда у классов есть очень много общего - события от мыши, размеры, координаты и т.д. В программировании игр, тоже самое, у игровых персонажей есть куча общего, поэтому такие вещи лучше делать через наследование.

    Но это нужно уметь совмещать с композицией, т.е. не пихать в родительский класс всё подряд, а выносить в отдельные классы. Тем самым код родительского класса будет проще и наследование будет проще пониматься. Например, если у монстров есть поведение - AI, то нет нужды пихать методы AI в класс монстра, лучше создать для этого отдельный класс AI и сделать его отдельным полем в классе монстра.

    А еще лучше AI сделать как внешний сервис, который ожидает на входе игровые объекты. Тем самым класс монстра даже и знать не будет о существовании AI, и тем самым код будет проще в понимании.
    Ответ написан
    1 комментарий
  • Какие есть способы обучения объектно ориентированному програмированию?

    Foror
    @Foror
    Графоман
    В догонку - Архитектура корпоративных систем, Фаулера
    Ответ написан
    Комментировать
  • Какие есть способы обучения объектно ориентированному програмированию?

    Foror
    @Foror
    Графоман
    Объектно-ориентированный анализ и проектирование с примерами приложений Гради Буч rutracker.org/forum/viewtopic.php?t=3343958
    Ответ написан
  • В чем суть интерфейсов в программировании?

    Foror
    @Foror
    Графоман
    Для начала нужно сразу понять, что интерфейс это частный случай класса. Но в Java оно имеет отдельное ключевое слово, а в C++ это просто класс без реализации. Поэтому интерфейс просто задает некий стандарт для работы с кучей разнообразных реализаций.

    Например, интерфейс Iterable говорит, что классы реализующие данный интерфейс имеют элементы и их можно перебирать в цикле вызывая метод next(). А значит, если создаете какой-то контейнер или коллекцию, то можно реализовать Iterable. Не выдумывая свои методы для работы с контейнером. Тем самым появляется некий общий стандарт - интерфейс для работы с контейнерами.

    А если вы делаете игру, то можете создать интерфейс Unit, тем самым задав классам определенное поведение. Например, unit должен обязательно иметь метод atack(), isDead() и т.д.

    А дальше, в цикле делаете проверку всех юнитов:
    loop(...) {
    if (unit.isDead())
    removeFromMap(unit);
    }

    Ну и конечно Unit может быть и просто классом или абстрактным классом, в котором реализованы atack и isDead, а может быть только isDead, потому что attack у каждого типа юнита индивидуально и требует собственной реализации. Т.е. приходим к тому, что интерфейс это также частный случай абстрактного класса.

    Т.е. тут уже вступает в действие полиформизм, т.е. интерфейсы по сути дают полиформизм. Ну, а в Java они еще позволяют делать множественное наследование или другими словами задать классу несколько свойств поведения, например Unit может быть также и Iterable, тем самым можно дать юнитам инвентарь и перебирать элементы в нем.

    И соответсвенно если Unit у вас будет классом или абстрактным классом, то унаследовав Unit в Java, вы просто не сможете дать наследнику еще и Iterable поведение, если Iterable будет тоже классом.

    OrcWarrior implements Unit, Iterable - так можно

    OrcWarrior extends Unit, Iterable - так в Java нельзя, но можно в С++, а Unit и Iterable тогда всегда будут объявляться как class...

    Из-за этого, в Java приветствуется не наследование, а композиция. Т.е. нафига каждый раз реализовывать Unit.isDead, если он стандартный? Поэтому, создается скажем класс UnitAI и делается следующее:

    class OrcWarrior implements Unit, Iterable {
    UnitAI ai;

    UnitAI getAI(){
    return ai;
    }
    }

    class UnitAI {

    boolean isDead() {
    ....
    }
    }

    interface Unit {
    void attack();
    UnitAI getAI();
    }

    Вот это называется композиция, т.е. в OrcWarrior, HumanWarrior вы подмешиваете UnitAI, в котором уже реализовано isDead, и тем самым не нужно каждый раз его реализовывать одним и тем же кодом. В С++ такого можно не делать, там есть поддержка множественного наследование, но оно имеет свои минусы. Впрочем, как и композиция имеет плюсы/минусы.
    Ответ написан
    Комментировать