Курс "Объектно-ориентированное программирование"
  • Главная
  • 1 семестр (осень 2021)
    • Видео
    • Конспект лекций
      • Лекция 1
      • Лекция 2
      • Лекция 3
      • Лекция 4
      • Лекция 5
      • Лекция 6
      • Лекция 7
      • Лекция 8
      • Лекция 9
      • Лекция 10
      • Лекция 11
      • Лекция 12
      • Лекция 13
      • Лекция 14
      • Лекция 15
    • Лабораторные работы
      • Лабораторная работа 1
        • 1. Установка программного обеспечения, создание и запуск проекта
        • 2. Основы синатксиса Java
        • Задание на лабораторную работу
      • Лабораторная работа 2
        • Синтаксис создания классов
        • Задание на лабораторную работу
      • Лабораторная работа 3
        • Инкапсуляция
        • Язык моделирования UML
        • Задание на лабораторную работу
      • Лабораторная работа 4
        • Наследование и композиция
        • Наследование и композиция в UML
        • Задание на лабораторную работу
      • Лабораторная работа 5
        • Задание на лабораторную работу
      • Лабораторная работа 6
        • Абстрактные классы и интерфейсы в UML
        • Задание на лабораторную работу
  • 2 семестр (весна 2022)
    • Конспект лекций
      • Лекция 1-2
      • Лекция 3-4
      • Лекция 5
      • Лекция 6
      • Лекция 7-8
      • Лекция 9
      • Лекция 10
      • Лекция 11-12
      • Лекция 13-14
      • Лекция 15
  • Архив
    • Лекция 2
    • Архив
      • Заметки по абстракции
      • Конспект лекций
        • 1. Принцип Separation of Concerns, контроллер и представление
        • 2. Паттерн MVC
        • 3. Клиент-серверная архитектура. Создание простой RESTful веб-службы с помощью Spring Boot.
        • 4. Внедрение зависимостей (Dependency Injection)
        • 5. Интеграция приложения с СУБД
        • 6. Фреймворк Spring MVC
        • 7. Работа со Spring Security, часть 1
        • 8. Работа со Spring Security, часть 2
        • 9. Развертывание приложения в Heroku
      • Заочники (осень 2022)
      • Архив
        • Лекции
          • Draft
            • 5. Абстрактные классы и интерфейсы. Механизм обратного вызова
            • 6. Анонимные классы
          • Блок лекций 1
            • Дополнительные задания и литература
            • 1. Базовые сведения об ООП
            • 1. Обобщенные типы. Автоупаковка и автораспаковка.
            • 2. Знакомство с языком Java
          • Блок лекций 2
            • 5. Абстрактные классы и интерфейсы. Механизм обратного вызова.
            • 6. Анонимные объекты, классы, методы. Лямбда-выражения.
            • 7. Аргументы переменной длины. Принцип абстракции. Дополнительные принципы ООП.
          • Блок лекций 3
            • 2. Коллекции объектов.
            • 3. Паттерн Итератор. Компараторы. Потоки в Java (Streams API)
          • Блок лекций 4
            • 1. Исключения в Java. Обработка исключений.
          • Блок лекций 5
            • Статические поля и методы
            • Вложенные и внутренние классы
            • Перечисления
          • Блок лекций 6
            • 2. Интеграция приложения с СУБД
        • Лабораторные работы
          • 2. Основы синтаксиса
            • Python
            • C#
          • Лабораторная работа 3
            • 1. Инкапсуляция
            • 2. Перегрузка методов
            • Задание на лабораторную работу
            • Теоретические вопросы
          • Лабораторная работа 4
            • Задание на лабораторную работу
            • Теоретические вопросы
          • Лабораторная работа 6
            • Задание на лабораторную работу
            • Теоретические вопросы
          • Лабораторная работа 7
            • Задание на лабораторную работу
            • Теоретические вопросы
          • Лабораторная работа 8
          • Лабораторная работа 9
          • Лабораторная работа 10
            • Задание на лабораторную работу
          • Лабораторная работа 11
            • Задание на лабораторную работу
          • Лабораторная работа 12
            • Пример выполнения лабораторной работы
            • Задание на лабораторную работу
        • Практические работы
          • Практическая работа 1
          • Практическая работа 2
        • Материалы по Java Spring
          • 1. Клиент-серверная архитектура. Создание простой RESTful веб-службы с помощью Spring Boot.
          • 4. Работа со Spring MVC, часть 1
          • 5. Работа со Spring MVC, часть 2
      • Конспект лекций
        • 1. История развития языков программирования
        • 2. Базовые термины ООП
        • 3. Понятие класса и объекта
        • 4. Создание объектов. Конструктор.
        • 5. Основные принципы ООП. Инкапсуляция.
        • 6. Перегрузка методов
        • 7. Повторное использование кода. Композиция и наследование
        • 8. Полиморфизм
        • 9. Абстрактные классы и интерфейсы
        • 10. Анонимные классы, интерфейсы, методы. Лямбда-выражения
        • 11. Принцип абстракции. Дополнительные принципы ООП
        • 12. Обобщенные типы. Автоупаковка и автораспаковка
        • 13. Коллекции
        • 14. Паттерн "Итератор". Компараторы. Фреймворк Streams API.
        • 15. Исключения в Java. Обработка исключений
        • 16. Принципы разработки графического интерфейса. Фреймворк JavaFX
        • 17. События в JavaFX
        • 20. Перечисления
      • Лабораторные работы
        • Лабораторная работа 2
          • 1. Синтаксис создания классов
          • 2. Язык моделирования UML
          • Задание на лабораторную работу
          • Теоретические вопросы
        • Лабораторная работа 3
          • 1. Инкапсуляция
          • 2. Перегрузка методов
          • Задание на лабораторную работу
        • Лабораторная работа 4
          • Наследование и композиция
          • Наследование и композиция в диаграмме классов UML
          • Задание на лабораторную работу
        • Лабораторная работа 5
          • Задание на лабораторную работу
          • Теоретические вопросы
        • Лабораторная работа 6
          • Задание (старое)
          • Теоретические вопросы
        • Лабораторная работа 8
          • Задание на лабораторную работу
        • Лабораторная работа 9
          • Задание на лабораторную работу
      • Видеолекции
      • Видеолекции
Powered by GitBook
On this page
  • От языка С к объектно-ориентированному программированию
  • Пример использования объектного подхода

Was this helpful?

Export as PDF
  1. Архив
  2. Архив
  3. Конспект лекций

2. Базовые термины ООП

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

Объект – структура, которая объединяет данные и методы, которые эти данные обрабатывают. Фактически, объект является основным строительным блоком объектно-ориентированных программ.

Класс – шаблон для объектов. Каждый объект является экземпляром (instance) какого-либо класса («безклассовых» объектов не существует). В рамках класса задается общий шаблон, структура, на основании которой создаются объекты. Данные, относящиеся к классу, называются полями класса, а программный код для их обработки называется методами класса. Поля и методы иногда называют общим термином – члены класса.

Разница между классом и объектом такая же, как между абстрактным понятием и реальным объектом.

Объект состоит из следующих частей:

  • имя объекта;

  • состояние (переменные состояния). Данные, содержащиеся в объекте, представляют его состояние. В терминологии ООП эти данные называются атрибутами. Например, атрибутами работника могут быть: имя, фамилия, пол, дата рождения, номер телефона. В разных объектах атрибуты имеют разное значение. Фактически, в объектах определяются конкретные значения тех переменных (полей класса), которые были заявлены при описании класса;

  • методы (операции) – применяются для выполнения операций с данными, а также для совершения других действий. Методы определяют, как объект взаимодействует с окружающим миром.

Объекты могут отправлять друг другу сообщения. Сообщение (message) - это практически то же самое, что и вызов функции в обычном программировании. В ООП обычно употребляется выражение "послать сообщение" какому-либо объекту. Понятие "сообщение" в ООП можно объяснить с точки зрения ООП: мы не можем напрямую изменить состояние объекта и должны как бы послать сообщение объекту, что мы хотим как-то изменить его состояние. Очень важно понять, что объект сам меняет свое состояние, а мы можем только попросить его об этом с помощью отсылки сообщения.

В объектно-ориентированной программе весь код должен находиться внутри классов!

В классе описываются, какого типа данные относятся к классу, а также то, какие методы применяются к этим данным. Затем, в программе на основе того или иного класса создается экземпляр класса (объект), в котором указываются конкретные значения полей и выполняются необходимые действия над ними.

От языка С к объектно-ориентированному программированию

Давайте попробуем понять, что такое объект и класс с помощью языка программирования C.

Представим себе, что мы пишем программу для книжной лавки на языке C. В какой-то момент мы сталкиваемся с необходимостью хранить информацию о множестве книг: название книги, кто автор книги, год издания и стоимость книги. Как нам это запрограммировать?

Мы можем воспользоваться массивами и хранить данные о книгах в нескольких массивах.

    int book_year[100];
    int book_pages[100];
    char book_author[100][50];
    char book_title[100][100];
    float book_price[100];

Теперь мы можем обратиться к i-му номеру каждого массива для получения информации об i-ой книге.

printf("%s-%s %d page", book_author[3], book_title[3], book_pages[3]);

Какими недостатками обладает данный способ работы с данными? Такой подход может приводить к многочисленным ошибкам (например, ошибки при работе с индексами массивов), такие данные тяжело модифицировать (удаление книги приводит к необходимости смещать влево часть элементов массивов), такой код неудобно читать, поддерживать и модифицировать.

Но самое главное - мы мыслим в контексте структуры компьютера, а не решаемой задачи. Для нас книга - это некий единый объект, который имеет некоторые параметры (атрибуты): название, количество страниц и так далее. Мы же представляем атрибуты этого объекта в виде отдельных записей в разных массивах, потому что на языке C мы вынуждены мыслить в терминах имеющихся структур данных (массивов, очередей, деревьев), а не в терминах отдельных объектов и их взаимоотношений. Это затрудняет понимание решаемой задачи (управление книжной лавкой и продажей книг), увеличивает количество ошибок в программе и на некотором этапе мы вообще перестаем понимать, что происходит в программе.

Для хотя бы какого-то решения этой проблемы и облегчения труда программиста, на некотором этапе в язык C было введено понятие структуры (ключевое слово struct), которое вы должны были изучать в курсе "Алгоритмизация и программирование".

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

Сначала мы должны описать структуру (новый тип данных).

struct Book {
    char author[50];
    char title[100];
    int year;
    int pages;
    float price;
};

Таким образом, некоторое понятие реального мира (то есть, книга вообще, как понятие) в программе описан структурой Book. Экземпляр этого понятия (какая-то конкретная книга) в программе будет представлен экземпляром структуры - переменной типа Book. Мы объявляем экземпляр структуры, после чего мы сможет заполнить поля структуры и работать с ней дальше в программе.

int main() {

    // Объявляем экземпляр структуры
    struct Book book1;

    // Заполняем поля экземпляра
    strcpy(book1.author,"Иванов А.А");
    strcpy(book1.title,"Программирование на Java");
    book1.pages = 255;
    book1.price = 350.25;
    book1.year = 2018;

    // Теперь мы можем работать с созданным экземпляром структуры
    printf("%s - %s, %d страниц", book1.author, book1.title, book1.pages);

    return 0;
}

Использование структур решает проблему лишь частично. Мы сгруппировали данные, но функции для работы с нашей структурой находятся вне структуры.

Объект реального мира обладает не только атрибутами (автор книги, название книги, количество страниц и так далее), но и определенным поведением (книгу можно продать, купить, переместить на склад и так далее). При разработке сложных программных систем необходимо группировать не только данные, но и функции, которые работают с этими данными.

Пример использования объектного подхода

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

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

Опишем класс для фигуры «Треугольник». Какие характеристики могут быть у класса «Треугольник»? От чего зависит набор характеристик? В принципе, любой объект является бесконечно сложным и для его описания понадобится бесконечно большое количество характеристик. Но для нашего простого графического редактора важными будут следующие параметры: координаты трех точек и цвет фигуры.

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

Для указания класса в Java используется ключевое слово class, после чего идет название класса, далее мы ставим фигурные скобки и всё, что будет написано внутри фигурных скобок (переменные и функции) будет относиться к этому классу.

class Triangle {
    
}

Какие переменные и типы данных будут моделировать координаты точек и цвет? Для моделирования цвета воспользуемся обычным целым числом (очень часто цвета моделируются обычным целочисленным значением).

class Triangle {
    
    // Цвет треугольника
    int color;
}

Теперь попробуем подумать, а как нам смоделировать координаты трех точек? Если бы мы программировали на языке C, мы бы написали что-то вроде

class Triangle {

    // Цвет треугольника
    int color;

    // Координаты точек треугольника
    int x1,y1,x2,y2,x3,y3;
}

Но давайте подумаем - координаты каждой точки логически связаны между собой и когда мы будем, например, перемещать треугольник или будем менять размер треугольника, будут одновременно меняться две переменные, которые моделируют одну точку. С точки зрения объектной модели, лучшим вариантом будет предусмотреть отдельную сущность, отдельный класс, который моделирует точку на двумерной плоскости. Таким образом, мы сгруппируем данные и код, который будет эти данные изменять (например, менять значение X и Y).

class Point2D {
    
    int x;
    int y;
}

Теперь вернемся к классу Triangle и укажем, что в качестве координат у нас будут выступать три объекта класса Point2D.

class Triangle {

    // Цвет треугольника
    int color;

    // Координаты трех точек
    Point2D point1;
    Point2D point2;
    Point2D point3;
}

Теперь давайте определимся с методами классов – то есть, к тому поведению, которое будут осуществлять объекты этих классов.

Какое поведение может быть у объекта класса «точка»? Совершенно точно это будет метод «изменить координаты». То есть, наша точка как отдельный объект может вести себя следующим образом – менять свои координаты. Давайте запрограммируем этот метод.

class Point2D {

    int x;
    int y;

    void changeCoordinates(int new_x, int new_y) {
        x = new_x;
        y = new_y;
    }
}

Теперь давайте подумаем, какое поведение будет у треугольника? Что с ним можно сделать? Ну, например, можно его перекрасить, можно его передвинуть в другое место на плоскости, можно его нарисовать на каком-то полотне и так далее. Давайте опишем некоторые из этих методов.

class Triangle {

    int color; // Цвет треугольника

    // Координаты трех точек
    Point2D point1;
    Point2D point2;
    Point2D point3;

    // Меняем цвет фигуры
    void changeColor(int new_color) {
        color = new_color;
    }

    // Меняем расположение фигуры
    // Для наглядности будем передавать входные параметры
    // в виде 6 целых чисел
    void move(int x1, int y1, int x2, int y2, int x3, int y3) {
        point1.changeCoordinates(x1, y1);
        point2.changeCoordinates(x2, y2);
        point3.changeCoordinates(x3, y3);
    }
}

Итак, мы описали треугольник, но мы определили только понятие «треугольник», у нас нет их физически, код класса - это просто описание. Если вы создали java-проект, у вас, по умолчанию, будет присутствовать класс Mainи функция main(). Пока что мы не будем объяснять, зачем нужен класс Main, а обратим внимание на метод main(). Этот метод является «точкой входа» в программу, с вызова этого метода начинается работа программы. Когда мы дойдем и выполним последнюю инструкцию внутри метода main(), приложение завершится.

Создадим внутри метода main() несколько объектов класса Triangle. Создание объектов мы будем рассматривать подробно в следующих лекциях, на данный момент мы просто скажем, что для создания объекта используется ключевое словоnew. После создания объекта, мы можем обращаться к объекту и вызывать методы у объектов (как мы вызывали функции в C).

public class Main {

    public static void main(String[] args) {

        // Создали один объект треугольника
        Triangle triangle1 = new Triangle();

        // Создали еще один объект треугольника
        Triangle triangle2 = new Triangle();

        // Для первого треугольника поменяли цвет
        triangle1.changeColor(10000);
        // Поменяли цвет для второго треугольника
        triangle2.changeColor(20000);

        // Создали объект первой точки треугольника
        // и назначили точке какие-то координаты
        triangle1.point1 = new Point2D();
        triangle1.point1.changeCoordinates(140,180);

        // Сделаем это же для первой точки второго треугольника
        triangle2.point1 = new Point2D();
        triangle2.point1.changeCoordinates(50,80);
    }
}

Важно! Вы должны понять, что у разных объектов значения переменных будут разные!

То есть, где-то в оперативной памяти у нас создано два разных объекта. Внутри первого есть объект класса Point2D, внутри этого объекта есть две переменные типа int, у которых будут значения 140 и 180. Внутри же второго треугольника будет свой объект Point2D, внутри которого будут совершенно другие две переменные типа int, у которых будут значения 50 и 80. Это же будет касаться переменных color в двух разных объектах (рис.1.5).

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

Previous1. История развития языков программированияNext3. Понятие класса и объекта

Last updated 4 years ago

Was this helpful?