Главная страница
Навигация по странице:

  • ПОЛИМОРФИЗМ С КОМПОЗИЦИЕЙ __________________________________________________

  • Абстрагирование

  • Инкапсуляция.

  • Наследование.

  • Разница между интерфейсом и реализацией

  • Рис. 2.1.

  • Объектно-ориентированный подход. Объектно_ориентированный_подход. Объектно ориентированный подход Мэтт Вайсфельд 5е международное издание ббк 32. 973. 2018


    Скачать 5.43 Mb.
    НазваниеОбъектно ориентированный подход Мэтт Вайсфельд 5е международное издание ббк 32. 973. 2018
    АнкорОбъектно-ориентированный подход
    Дата31.03.2023
    Размер5.43 Mb.
    Формат файлаpdf
    Имя файлаОбъектно_ориентированный_подход.pdf
    ТипДокументы
    #1028905
    страница6 из 25
    1   2   3   4   5   6   7   8   9   ...   25
    48
    Shape содержит метод
    Draw
    ,
    Circle переопределит этот метод и обеспечит соб- ственный метод
    Draw()
    . Переопределение, в сущности, означает замену реали- зации родительского класса на реализацию из дочернего класса.
    Допустим, у вас имеется массив из трех форм —
    Circle
    ,
    Square и
    Star
    . Даже если вы будете рассматривать их все как объекты
    Shape и отправите сообщение
    Draw каждому объекту
    Shape
    , то конечный результат для каждого из них будет разным, поскольку
    Circle
    ,
    Square и
    Star обеспечивают фактические реализации. Одним словом, каждый класс способен реагировать на один и тот же метод
    Draw не так, как другие, и рисовать соответствующую фигуру. Это и понимается под поли- морфизмом.
    Взгляните на следующий класс
    Shape
    :
    public abstract class Shape{
    private double area;
    public abstract double getArea();
    }
    Класс
    Shape включает атрибут с именем area
    , который содержит значение пло- щади фигуры. Метод getArea()
    включает идентификатор с именем abstract
    Когда метод определяется как abstract
    , подкласс должен обеспечивать реали- зацию для этого метода; в данном случае
    Shape требует, чтобы подклассы обе- спечивали реализацию getArea()
    . А теперь создадим класс с именем
    Circle
    , который будет наследовать от
    Shape
    (ключевое слово extends будет указывать на то, что
    Circle наследует от
    Shape
    ):
    public class Circle extends Shape{
    double radius;
    public Circle(double r) {
    radius = r;
    }
    public double getArea() {
    area = 3.14*(radius*radius);
    return (area);
    }
    }
    Здесь мы познакомимся с новой концепцией под названием конструктор.
    Класс
    Circle содержит метод с таким же именем —
    Circle
    . Если имя метода

    49
    Полиморфизм. .
    оказывается аналогичным имени класса и при этом не предусматривается возвращаемого типа, то это особый метод, называемый конструктором. Счи- тайте конструктор точкой входа для класса, где создается объект. Конструктор хорошо подходит для выполнения инициализаций и задач, связанных с за- пуском.
    Конструктор
    Circle принимает один параметр, представляющий радиус, и при- сваивает его атрибуту radius класса
    Circle
    Класс
    Circle также обеспечивает реализацию для метода getArea
    , изначально определенного как abstract в классе
    Shape
    Мы можем создать похожий класс с именем
    Rectangle
    :
    public class Rectangle extends Shape{
    double length;
    double width;
    public Rectangle(double l, double w){
    length = l;
    width = w;
    }
    public double getArea() {
    area = length*width;
    return (area);
    }
    }
    Теперь мы можем создавать любое количество классов прямоугольников, кру- гов и т. д. и вызывать их метод getArea()
    . Ведь мы знаем, что все классы прямо- угольников и кругов наследуют от
    Shape
    , а все классы
    Shape содержат метод getArea()
    . Если подкласс наследует абстрактный метод от суперкласса, то он должен обеспечивать конкретную реализацию этого метода, поскольку иначе он сам будет абстрактным классом (см. рис. 1.18, где приведена UML-диаграмма).
    Этот подход также обеспечивает механизм для довольно легкого создания дру- гих, новых классов.
    Таким образом, мы можем создать экземпляры классов
    Shape следующим путем:
    Circle circle = new Circle(5);
    Rectangle rectangle = new Rectangle(4,5);
    Затем, используя такую конструкцию, как стек, мы можем добавить в него классы
    Shape
    :
    stack.push(circle);
    stack.push(rectangle);

    Глава.1..Введение.в.объектно-ориентированные.концепции
    50
    Рис. 1.18. UML-диаграмма.Shape
    ЧТО ТАКОЕ СТЕК? _____________________________________________________________________
    Стек.—.это.структура.данных,.представляющая.собой.систему.«последним.пришел.—.
    первым.ушел»..Это.как.стопка.монет.в.форме.цилиндра,.которые.вы.складываете.
    одна.на.другую..Когда.вам.потребуется.монета,.вы.снимете.верхнюю.монету,.которая.
    при.этом.будет.последней.из.тех,.что.вы.положили.в.стопку..Вставка.элемента.в.стек.
    означает,.что.вы.добавляете.его.на.вершину.стека.(подобно.тому,.как.вы.кладете.
    следующую.монету.в.стопку)..Удаление.элемента.из.стека.означает,.что.вы.убирае- те.последний.элемент.из.стека.(подобно.снятию.верхней.монеты).
    Теперь переходим к увлекательной части. Мы можем очистить стек, и нам при этом не придется беспокоиться о том, какие классы
    Shape в нем находятся (мы просто будем знать, что они связаны с фигурами):
    while ( !stack.empty()) {
    Shape shape = (Shape) stack.pop();
    System.out.println ("Площадь = " + shape.getArea());
    }
    В действительности мы отправляем одно и то же сообщение всем
    Shape
    :
    shape.getArea()
    Однако фактическое поведение, которое имеет место, зависит от типа фигуры.
    Например,
    Circle вычисляет площадь круга, а
    Rectangle
    — площадь прямо- угольника. На самом деле (и в этом заключается ключевая концепция) мы от- правляем сообщение классам
    Shape и наблюдаем разное поведение в зависимо- сти от того, какие подклассы
    Shape используются.
    Этот подход направлен на обеспечение стандартизации определенного интер- фейса среди классов, а также приложений. Представьте себе приложение из

    51
    Композиция. .
    офисного пакета, которое позволяет обрабатывать текст, и приложение для работы с электронными таблицами. Предположим, что они оба включают класс с именем
    Office
    , который содержит интерфейс с именем print()
    . Этот print()
    необходим всем классам, являющимся частью офисного пакета. Любопытно, но несмотря на то, что текстовый процессор и табличная программа вызывают интерфейс print()
    , они делают разные вещи: один выводит текстовый документ, а другая — документ с электронными таблицами.
    ПОЛИМОРФИЗМ С КОМПОЗИЦИЕЙ __________________________________________________
    В.так.называемом.классическом.объектно-ориентированном.программировании.
    полиморфизм.традиционно.выполняется.наследованием..Но.есть.и.способ.выпол- нить.полиморфизм.с.применением.композиции..Мы.обсудим.такой.случай.в.главе.12.
    «Принципы.объектно-ориентированного.проектирования.SOLID».
    Композиция
    Вполне естественно представлять себе, что одни объекты содержат другие объ- екты. У телевизора есть тюнер и экран. У компьютера есть видеокарта, клавиа- тура и жесткий диск. Хотя компьютер сам по себе можно считать объектом, его жесткий диск тоже считается полноценным объектом. Фактически вы могли бы открыть системный блок компьютера, достать жесткий диск и подержать его в руке. Как компьютер, так и его жесткий диск считаются объектами. Просто компьютер содержит другие объекты, например жесткий диск.
    Таким образом, объекты зачастую формируются или состоят из других объек- тов — это и есть композиция.
    Абстрагирование
    Точно так же как и наследование, композиция обеспечивает механизм для соз- дания объектов. Я сказал бы, что фактически есть только два способа создания классов из других классов: наследование и композиция. Как мы уже видели, на- следование позволяет одному классу наследовать от другого. Поэтому мы можем абстрагировать атрибуты и поведения для общих классов. Например, как со- баки, так и кошки относятся к млекопитающим, поскольку собака является
    экземпляром млекопитающего так же, как и кошка. Благодаря композиции мы к тому же можем создавать классы, вкладывая одни классы в другие.
    Взглянем на отношение между автомобилем и двигателем. Преимущества раз- деления двигателя и автомобиля очевидны. Создавая двигатель отдельно, мы сможем использовать его в разных автомобилях, не говоря уже о других преиму- ществах. Однако мы не можем сказать, что двигатель является экземпляром автомобиля. Это будет просто неправильно звучать, если так выразиться (а по- скольку мы моделируем реальные системы, это нам и нужно). Вместо этого для

    Глава.1..Введение.в.объектно-ориентированные.концепции
    52
    описания отношений композиции мы используем словосочетание содержит
    как часть. Автомобиль содержит как часть двигатель.
    Отношения «содержит как часть»
    Хотя отношения наследования считаются отношениями «является экземпля-
    ром» по тем причинам, о которых мы уже говорили ранее, отношения компози- ции называются отношениями «содержит как часть». Если взять пример из приводившегося ранее раздела, то телевизор содержит как часть тюнер, а так- же экран. Телевизор, несомненно, не является тюнером, поэтому здесь нет ни- каких отношений наследования. В том же духе частью компьютера является видеокарта, клавиатура и жесткий диск. Тема наследования, композиции и того, как они соотносятся друг с другом, очень подробно разбирается в главе 7.
    Резюме
    При рассмотрении объектно-ориентированных технологий нужно много чего охватить. Однако по завершении чтения этой главы у вас должно сложиться хорошее понимание следующих концепций.
    ‰
    Инкапсуляция. Инкапсуляция данных и поведений в одном объекте имеет первостепенное значение в объектно-ориентированной разработке. Один объект будет содержать как свои данные, так и поведения и сможет скрыть то, что ему потребуется, от других объектов.
    ‰
    Наследование. Класс может наследовать от другого класса и использовать преимущества атрибутов и методов, определяемых суперклассом.
    ‰
    Полиморфизм. Означает, что схожие объекты способны по-разному отвечать на одно и то же сообщение. Например, у вас может быть система с множеством фигур.
    Однако круг, квадрат и звезда рисуются по-разному. Используя полимор- физм, вы можете отправить одно и то же сообщение (например,
    Draw
    ) объ- ектам, на каждый из которых возлагается обязанность по рисованию соот- ветствующей ему фигуры.
    ‰
    Композиция. Означает, что объект формируется из других объектов.
    В этой главе рассмотрены фундаментальные объектно-ориентированные кон- цепции, в которых к настоящему времени вы уже должны хорошо разбираться.

    Глава 2
    КАК МЫСЛИТЬ ОБЪЕКТНО
    В главе 1 вы изучили фундаментальные объектно-ориентированные концепции.
    В остальной части этой книги мы тщательнее разберем эти концепции и по- знакомимся с некоторыми другими. Для грамотного подхода к проектированию необходимо учитывать много факторов, независимо от того, идет ли речь об объектно-ориентированном проектировании или каком-то другом. В качестве основной единицы при объектно-ориентированном проектировании выступает класс. Желаемым конечным результатом такого проектирования является на- дежная и функциональная объектная модель, другими словами, полная система.
    Как и в случае с большинством вещей в жизни, нет какого-то одного правиль- ного или ошибочного подхода к устранению проблем. Обычно бывает много путей решения одной и той же проблемы. Поэтому, пытаясь выработать объ- ектно-ориентированное решение, не зацикливайтесь на том, чтобы постараться с первого раза все идеально спроектировать (кое-что всегда можно будет усо- вершенствовать). В действительности вам потребуется прибегнуть к мозговому штурму и позволить мыслительному процессу пойти в разных направлениях.
    Не старайтесь соответствовать каким-либо стандартам или соглашениям, пы- таясь решить проблему, поскольку важно лишь быть креативным.
    Фактически на самом старте процесса не стоит даже начинать задумываться о конкретном языке программирования. Первым пунктом повестки дня должно быть определение и решение бизнес-проблем. Займитесь сперва концептуаль- ным анализом и проектированием. Задумывайтесь о конкретных технологиях, только если они будут существенны для решения бизнес-проблем. Например, нельзя спроектировать беспроводную сеть без беспроводной технологии. Од- нако часто будет случаться так, что вам придется обдумывать сразу несколько программных решений.
    Таким образом, перед тем как приступать к проектированию системы или даже класса, следует поразмыслить над соответствующей задачей и повеселиться!
    В этой главе мы рассмотрим изящное искусство и науку объектно-ориентиро- ванного мышления.
    Любое фундаментальное изменение в мышлении не является тривиальным.
    Например, ранее много говорилось о переходе со структурной разработки на

    Глава.2..Как.мыслить.объектно
    54
    объектно-ориентированную. Один из побочных эффектов ведущихся при этом дебатов заключается в ошибочном представлении, что структурная и объектно- ориентированная разработки являются взаимоисключающими. Однако это не так. Как мы уже знаем из нашего исследования оберток, структурная и объ ектно- ориентированная разработки сосуществуют. Фактически, создавая объектно- ориентированное приложение, вы повсеместно используете структурные конструкции. Мне никогда не доводилось видеть программу, объектно-ориен- тированную или любую другую, которая не задействует циклы, операторы if и т. д. Кроме того, переход на объектно-ориентированное проектирование не потребует каких-либо затрат.
    Чтобы перейти с FORTRAN на COBOL или даже C, вам потребуется изучить новый язык программирования, однако для перехода с COBOL на C++, C# .
    NET, Visual Basic .NET, Objective-C или Java вам придется освоить новое мыш- ление. Здесь всплывает избитое выражение объектно-ориентированная пара-
    дигма. При переходе на объектно-ориентированный язык вам сначала потребу- ется потратить время на изучение объектно-ориентированных концепций и освоение соответствующего мышления. Если такая смена парадигмы не про- изойдет, то случится одна из двух вещей: либо проект не окажется по-настоящему объектно-ориентированным по своей природе (например, он будет задействовать
    C++ без использования объектно-ориентированных конструкций), либо он окажется полной объектно-неориентированной неразберихой.
    В этой главе рассматриваются три важные вещи, которые вы можете сделать для того, чтобы хорошо освоить объектно-ориентированное мышление:
    ‰
    знать разницу между интерфейсом и реализацией;
    ‰
    мыслить более абстрактно;
    ‰
    обеспечивать для пользователей минимальный интерфейс из возможных.
    Мы уже затронули некоторые из этих концепций в главе 1, а теперь разберемся в них более подробно.
    Разница между интерфейсом и реализацией
    Как мы уже видели в главе 1, один из ключей к грамотному проектированию — понимание разницы между интерфейсом и реализацией. Таким образом, при проектировании класса важно определить, что пользователю требуется знать, а что нет. Механизм сокрытия данных, присущий инкапсуляции, представляет собой инструмент, позволяющий скрывать от пользователей несущественные данные.
    Помните пример с тостером из главы 1? Тостер или любой электроприбор, если на то пошло, подключается к интерфейсу, которым является электриче- ская розетка (рис. 2.1). Все электроприборы получают доступ к необходимому

    55
    Разница.между.интерфейсом.и.реализацией. .
    элект ричеству через электрическую розетку, которая соответствует нужному интерфейсу. Тостеру не нужно что-либо знать о реализации или о том, как вырабатывается электричество. Для него важно лишь то, чтобы работающая на угле или атомная электростанция могла вырабатывать электричество, — этому электроприбору все равно, какая из станций будет делать это, при ус- ловии, что интерфейс работает соответствующим образом, то есть корректно и надежно.
    Рис. 2.1. Повторно.приведенный.пример.с.электростанцией
    ПРЕДОСТЕРЕЖЕНИЕ __________________________________________________________________
    Не.путайте.концепцию.интерфейса.с.терминами.вроде.«графический.интерфейс.
    пользователя».(GUI.—.Graphical.User.Interface)..Несмотря.на.то.что.графический.
    интерфейс.пользователя,.как.видно.из.его.названия,.представляет.собой.интерфейс,.
    используемый.здесь.термин.является.более.общим.по.своей.природе.и.не.ограни- чивается.понятием.графического.интерфейса.
    В качестве другого примера рассмотрим автомобиль. Интерфейс между вами и автомобилем включает такие компоненты, как руль, педаль газа, педаль тормоза и переключатель зажигания. Когда речь идет об управлении автомо- билем, для большинства людей, если отбросить вопросы эстетики, главным является то, как он заводится, разгоняется, останавливается и т. д. Реализация, чем, по сути, является то, чего вы не видите, мало интересует среднестатисти- ческого водителя. Фактически большинство людей даже не способно иденти- фицировать определенные компоненты, например каталитический преобра- зователь или сальник. Однако любой водитель узнает руль и будет в курсе, как его использовать, поскольку это общий интерфейс. Устанавливая стан- дартный руль в автомобилях, производители могут быть уверены в том, что люди из их потенциального круга покупателей смогут использовать выпуска- емую ими продукцию.
    Однако если какой-нибудь производитель решит установить вместо руля джой- стик, то большинство водителей будут разочарованы, а продажи таких автомо- билей могут оказаться низкими (подобная замена устроит разве что отдельных эклектиков, которым нравится «двигаться против течения»). С другой стороны, если мощность и эстетика не изменятся, то среднестатистический водитель

    Глава.2..Как.мыслить.объектно
    56
    ничего не заметит, даже если производитель изменит двигатель (часть реализа- ции) выпускаемых автомобилей.
    Отметим, что заменяемые двигатели должны быть идентичны, насколько это возможно во всех отношениях. Замена четырехцилиндрового двигателя на восьмицилиндровый изменит правила и, вероятно, не будет работать с другими компонентами, которые взаимодействуют с двигателем, точно так же как из- менение тока с переменного на постоянный будет влиять на правила в примере силовой установки.
    Двигатель является частью реализации, а руль — частью интерфейса. Изме- нения в реализации не должны оказывать влияния на водителя, в то время как изменения в интерфейсе могут это делать. Водитель заметил бы эстетические изменения руля, даже если бы тот функционировал так же, как и раньше. Не- обходимо подчеркнуть, что изменения в двигателе, заметные для водителя, нарушают это правило. Например, изменение, которое приведет к заметной потери мощности, в действительности будет изменением интерфейса.
    1   2   3   4   5   6   7   8   9   ...   25


    написать администратору сайта