0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#статьи</a></p>
1
<p><a>#статьи</a></p>
2
<ul><li>21 авг 2019</li>
2
<ul><li>21 авг 2019</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Почти всё современное программирование построено на принципах ООП, поэтому их должен понимать каждый разработчик. Узнайте основы из этой статьи.</p>
4
</ul><p>Почти всё современное программирование построено на принципах ООП, поэтому их должен понимать каждый разработчик. Узнайте основы из этой статьи.</p>
5
<p>Фото: Sonja Flemming / NBCUniversal / Getty Images</p>
5
<p>Фото: Sonja Flemming / NBCUniversal / Getty Images</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
6
<p>Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.</p>
7
<p>Это первая статья из серии, посвящённой объектно-ориентированному программированию. Она предназначена для тех, кто хочет понять суть этой парадигмы разработки, а не просто научиться использовать классы и объекты.</p>
7
<p>Это первая статья из серии, посвящённой объектно-ориентированному программированию. Она предназначена для тех, кто хочет понять суть этой парадигмы разработки, а не просто научиться использовать классы и объекты.</p>
8
<p>Цикл состоит из статей, посвящённых различным аспектам ООП:</p>
8
<p>Цикл состоит из статей, посвящённых различным аспектам ООП:</p>
9
<ul><li><a>что такое классы и объекты</a>;</li>
9
<ul><li><a>что такое классы и объекты</a>;</li>
10
<li><a>особенности работы с объектами</a>;</li>
10
<li><a>особенности работы с объектами</a>;</li>
11
<li><a>модификаторы доступа, инкапсуляция</a>;</li>
11
<li><a>модификаторы доступа, инкапсуляция</a>;</li>
12
<li><a>перегрузка методов</a>;</li>
12
<li><a>перегрузка методов</a>;</li>
13
<li><a>полиморфизм</a>;</li>
13
<li><a>полиморфизм</a>;</li>
14
<li><a>наследование и ещё немного полиморфизма</a>;</li>
14
<li><a>наследование и ещё немного полиморфизма</a>;</li>
15
<li><a>абстрактные классы и интерфейсы</a>;</li>
15
<li><a>абстрактные классы и интерфейсы</a>;</li>
16
<li><a>практикум</a>.</li>
16
<li><a>практикум</a>.</li>
17
</ul><p>Все примеры в этой серии написаны на языке<a>C#</a>. Для наглядности они будут связаны с разработкой игр, потому что именно в играх (хотя далеко не только в них) активно используются объекты.</p>
17
</ul><p>Все примеры в этой серии написаны на языке<a>C#</a>. Для наглядности они будут связаны с разработкой игр, потому что именно в играх (хотя далеко не только в них) активно используются объекты.</p>
18
<p>Перед тем как приступать к изучению ООП, убедитесь, что знакомы со следующими понятиями:</p>
18
<p>Перед тем как приступать к изучению ООП, убедитесь, что знакомы со следующими понятиями:</p>
19
<ul><li>переменные и типы данных,</li>
19
<ul><li>переменные и типы данных,</li>
20
<li>условные конструкции,</li>
20
<li>условные конструкции,</li>
21
<li>циклы,</li>
21
<li>циклы,</li>
22
<li>коллекции (желательно).</li>
22
<li>коллекции (желательно).</li>
23
</ul><p>Работа будет проходить в Visual Studio 2019, но вполне подойдёт и VS 2017.</p>
23
</ul><p>Работа будет проходить в Visual Studio 2019, но вполне подойдёт и VS 2017.</p>
24
<p>В конце каждой статьи будут задания, которые помогут закрепить тему. Выполнять их необязательно, но имейте в виду, что осилить ООП без практики просто невозможно. Если же вам лень выполнять задания, можете просто посмотреть наш вариант решения. Итак, поехали!</p>
24
<p>В конце каждой статьи будут задания, которые помогут закрепить тему. Выполнять их необязательно, но имейте в виду, что осилить ООП без практики просто невозможно. Если же вам лень выполнять задания, можете просто посмотреть наш вариант решения. Итак, поехали!</p>
25
<p>Введение в объектно-ориентированное программирование:</p>
25
<p>Введение в объектно-ориентированное программирование:</p>
26
<ul><li><a>Что такое ООП</a></li>
26
<ul><li><a>Что такое ООП</a></li>
27
<li><a>Какие у него плюсы и минусы</a></li>
27
<li><a>Какие у него плюсы и минусы</a></li>
28
<li><a>Что такое абстракция, инкапсуляция, наследование и полиморфизм</a></li>
28
<li><a>Что такое абстракция, инкапсуляция, наследование и полиморфизм</a></li>
29
<li><a>Объекты и классы: как их использовать</a></li>
29
<li><a>Объекты и классы: как их использовать</a></li>
30
<li><a>Как создать класс</a></li>
30
<li><a>Как создать класс</a></li>
31
<li><a>Как использовать поля и свойства класса</a></li>
31
<li><a>Как использовать поля и свойства класса</a></li>
32
<li><a>Как создать метод</a></li>
32
<li><a>Как создать метод</a></li>
33
<li><a>Что такое конструктор объекта</a></li>
33
<li><a>Что такое конструктор объекта</a></li>
34
<li><a>Домашнее задание</a></li>
34
<li><a>Домашнее задание</a></li>
35
<li><a>Что запомнить</a></li>
35
<li><a>Что запомнить</a></li>
36
</ul><p><strong>Объектно-ориентированное программирование (сокращённо ООП)</strong> - это парадигма разработки программного обеспечения, согласно которой приложения состоят из объектов.</p>
36
</ul><p><strong>Объектно-ориентированное программирование (сокращённо ООП)</strong> - это парадигма разработки программного обеспечения, согласно которой приложения состоят из объектов.</p>
37
<p>На <a>объектах</a>и <a>классах</a>строится всё ООП. Поэтому давайте чётко обозначим, чем они отличаются друг от друга.</p>
37
<p>На <a>объектах</a>и <a>классах</a>строится всё ООП. Поэтому давайте чётко обозначим, чем они отличаются друг от друга.</p>
38
<p><strong>Класс</strong> - это тип данных, созданный пользователем. Он содержит разные свойства и методы, как, например, тип String или Int.</p>
38
<p><strong>Класс</strong> - это тип данных, созданный пользователем. Он содержит разные свойства и методы, как, например, тип String или Int.</p>
39
<p><strong>Объект</strong> - это экземпляр класса, или его копия, которая находится в памяти компьютера. Например, когда вы создаёте переменную типа String и присваиваете ей значение "Строка", то в памяти создаётся экземпляр класса String.</p>
39
<p><strong>Объект</strong> - это экземпляр класса, или его копия, которая находится в памяти компьютера. Например, когда вы создаёте переменную типа String и присваиваете ей значение "Строка", то в памяти создаётся экземпляр класса String.</p>
40
<p>По-другому можно сказать, что объекты - это сущности, у которых есть свойства и поведение. Обычно объекты являются экземплярами какого-нибудь класса. Например, в игре может быть класс Character ("Персонаж"), а его экземплярами будут hero или npc.</p>
40
<p>По-другому можно сказать, что объекты - это сущности, у которых есть свойства и поведение. Обычно объекты являются экземплярами какого-нибудь класса. Например, в игре может быть класс Character ("Персонаж"), а его экземплярами будут hero или npc.</p>
41
Наш класс - это "скелет". С помощью него мы можем создать разных персонажей: героя или NPC<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Свойства - это данные, которые связаны с конкретным объектом:</p>
41
Наш класс - это "скелет". С помощью него мы можем создать разных персонажей: героя или NPC<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Свойства - это данные, которые связаны с конкретным объектом:</p>
42
<ul><li>здоровье,</li>
42
<ul><li>здоровье,</li>
43
<li>очки,</li>
43
<li>очки,</li>
44
<li>деньги,</li>
44
<li>деньги,</li>
45
<li>сила,</li>
45
<li>сила,</li>
46
<li>ловкость,</li>
46
<li>ловкость,</li>
47
<li>интеллект,</li>
47
<li>интеллект,</li>
48
<li>скорость,</li>
48
<li>скорость,</li>
49
<li>координаты.</li>
49
<li>координаты.</li>
50
</ul>У нашего экземпляра есть собственные свойства<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Поведение объекта определяется с помощью методов - специальных блоков кода, которые можно вызывать из разных частей программы. Например, у того же объекта Character могут быть следующие методы:</p>
50
</ul>У нашего экземпляра есть собственные свойства<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Поведение объекта определяется с помощью методов - специальных блоков кода, которые можно вызывать из разных частей программы. Например, у того же объекта Character могут быть следующие методы:</p>
51
<ul><li>идти,</li>
51
<ul><li>идти,</li>
52
<li>атаковать,</li>
52
<li>атаковать,</li>
53
<li>говорить,</li>
53
<li>говорить,</li>
54
<li>подобрать,</li>
54
<li>подобрать,</li>
55
<li>выбросить,</li>
55
<li>выбросить,</li>
56
<li>использовать.</li>
56
<li>использовать.</li>
57
</ul>Наш герой может делать разные вещи - например, атаковать, говорить и отдыхать<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Используя эти свойства и методы, можно значительно ускорить разработку, сделать код более читаемым. К тому же самому программисту проще составлять код, если он думает с помощью объектов.</p>
57
</ul>Наш герой может делать разные вещи - например, атаковать, говорить и отдыхать<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Используя эти свойства и методы, можно значительно ускорить разработку, сделать код более читаемым. К тому же самому программисту проще составлять код, если он думает с помощью объектов.</p>
58
<p>Разработчики не пишут какую-то функцию, которая будет делать что-то для программы в целом. Вместо этого они мысленно разделяют приложение на отдельные компоненты и продумывают их свойства и поведение.</p>
58
<p>Разработчики не пишут какую-то функцию, которая будет делать что-то для программы в целом. Вместо этого они мысленно разделяют приложение на отдельные компоненты и продумывают их свойства и поведение.</p>
59
<p>Такую парадигму используют многие популярные языки:</p>
59
<p>Такую парадигму используют многие популярные языки:</p>
60
<ul><li>C#,</li>
60
<ul><li>C#,</li>
61
<li>Java,</li>
61
<li>Java,</li>
62
<li>Python,</li>
62
<li>Python,</li>
63
<li>JavaScript,</li>
63
<li>JavaScript,</li>
64
<li>PHP,</li>
64
<li>PHP,</li>
65
<li>Kotlin,</li>
65
<li>Kotlin,</li>
66
<li>Swift,</li>
66
<li>Swift,</li>
67
<li>Objective-C,</li>
67
<li>Objective-C,</li>
68
<li>C++.</li>
68
<li>C++.</li>
69
</ul><p>У нас также есть<a>статья по ООП на Python</a>. Поэтому если вы не любите C#, то можете изучить главные принципы на Python.</p>
69
</ul><p>У нас также есть<a>статья по ООП на Python</a>. Поэтому если вы не любите C#, то можете изучить главные принципы на Python.</p>
70
ПлюсыМинусы<strong>Легко читается.</strong>Не нужно выискивать в коде функции и выяснять, за что они отвечают<strong>Потребляет больше памяти.</strong>Объекты потребляют больше оперативной памяти, чем примитивные типы данных<strong>Быстро пишется.</strong>Можно быстро создать сущности, с которыми должна работать программа<strong>Снижает производительность.</strong>Многие вещи технически реализованы иначе, поэтому они используют больше ресурсов<strong>Проще реализовать большой набор функций.</strong>Так как на написание кода уходит меньше времени, можно гораздо быстрее создать приложение с множеством возможностей<strong>Сложно начать.</strong>Парадигма ООП сложнее функционального программирования, поэтому на старт уходит больше времени<strong>Меньше повторений.</strong>Не нужно писать однотипные функции для разных сущностей<p>Всё объектно-ориентированное программирование строится на четырёх понятиях:</p>
70
ПлюсыМинусы<strong>Легко читается.</strong>Не нужно выискивать в коде функции и выяснять, за что они отвечают<strong>Потребляет больше памяти.</strong>Объекты потребляют больше оперативной памяти, чем примитивные типы данных<strong>Быстро пишется.</strong>Можно быстро создать сущности, с которыми должна работать программа<strong>Снижает производительность.</strong>Многие вещи технически реализованы иначе, поэтому они используют больше ресурсов<strong>Проще реализовать большой набор функций.</strong>Так как на написание кода уходит меньше времени, можно гораздо быстрее создать приложение с множеством возможностей<strong>Сложно начать.</strong>Парадигма ООП сложнее функционального программирования, поэтому на старт уходит больше времени<strong>Меньше повторений.</strong>Не нужно писать однотипные функции для разных сущностей<p>Всё объектно-ориентированное программирование строится на четырёх понятиях:</p>
71
<ul><li><a>абстракции</a>,</li>
71
<ul><li><a>абстракции</a>,</li>
72
<li><a>инкапсуляции</a>,</li>
72
<li><a>инкапсуляции</a>,</li>
73
<li><a>наследовании</a>,</li>
73
<li><a>наследовании</a>,</li>
74
<li><a>полиморфизме</a>.</li>
74
<li><a>полиморфизме</a>.</li>
75
</ul><p>Чтобы стало понятнее, представим, что у нас есть класс "Кошка". В нём присутствуют несколько атрибутов - например, "окрас", "порода" и "возраст", а также методов - например, "спать". И когда у нас есть класс, мы можем создать сколько угодно его экземпляров с разными свойствами. Например, мы можем добавить несколько пород кошек:</p>
75
</ul><p>Чтобы стало понятнее, представим, что у нас есть класс "Кошка". В нём присутствуют несколько атрибутов - например, "окрас", "порода" и "возраст", а также методов - например, "спать". И когда у нас есть класс, мы можем создать сколько угодно его экземпляров с разными свойствами. Например, мы можем добавить несколько пород кошек:</p>
76
Класс один - значения свойств разные<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Теперь перейдём к принципам ООП.</p>
76
Класс один - значения свойств разные<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Теперь перейдём к принципам ООП.</p>
77
<p>При создании класса мы упрощаем его до тех атрибутов и методов, которые нужны в этом конкретном коде, не пытаясь описать его целиком и отбрасывая всё второстепенное. Скажем, все кошки теоретически умеют охотиться, но если наша программа не предназначена для ловли мышей, то и прописывать этот метод незачем.</p>
77
<p>При создании класса мы упрощаем его до тех атрибутов и методов, которые нужны в этом конкретном коде, не пытаясь описать его целиком и отбрасывая всё второстепенное. Скажем, все кошки теоретически умеют охотиться, но если наша программа не предназначена для ловли мышей, то и прописывать этот метод незачем.</p>
78
А что ещё нужно домашним кошкам?<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Доступ к данным объекта должен контролироваться, чтобы пользователь не мог изменить их в произвольном порядке и что-то поломать. Поэтому для работы с данными программисты пишут публичные методы, которые составляют интерфейс объекта.</p>
78
А что ещё нужно домашним кошкам?<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Доступ к данным объекта должен контролироваться, чтобы пользователь не мог изменить их в произвольном порядке и что-то поломать. Поэтому для работы с данными программисты пишут публичные методы, которые составляют интерфейс объекта.</p>
79
<p>Возвращаясь к нашим кошечкам. Мы можем разрешить изменять атрибут "возраст", но только в большую сторону (к сожалению, с годами никто не молодеет), а атрибут "порода" лучше открыть только для чтения - ведь порода кошки не меняется.</p>
79
<p>Возвращаясь к нашим кошечкам. Мы можем разрешить изменять атрибут "возраст", но только в большую сторону (к сожалению, с годами никто не молодеет), а атрибут "порода" лучше открыть только для чтения - ведь порода кошки не меняется.</p>
80
Мы сами можем ограничивать доступ к определённым свойствам<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Классы могут передавать свои атрибуты и методы классам-потомкам. Например, мы хотим создать новый класс "Домашняя кошка". Он практически идентичен классу "Кошка", но у него появляются новые атрибуты - "хозяин" и "кличка", а также метод "клянчить вкусняшку". Достаточно объявить "Домашнюю кошку" наследником "Кошки" и прописать новые атрибуты и методы - вся остальная функциональность перейдёт от родителя к потомку.</p>
80
Мы сами можем ограничивать доступ к определённым свойствам<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Классы могут передавать свои атрибуты и методы классам-потомкам. Например, мы хотим создать новый класс "Домашняя кошка". Он практически идентичен классу "Кошка", но у него появляются новые атрибуты - "хозяин" и "кличка", а также метод "клянчить вкусняшку". Достаточно объявить "Домашнюю кошку" наследником "Кошки" и прописать новые атрибуты и методы - вся остальная функциональность перейдёт от родителя к потомку.</p>
81
Классы-потомки наследуют свойства и методы классов-родителей, а также добавляют новые<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Этот принцип позволяет применять одни и те же команды к объектам разных классов, даже если они выполняются по-разному. Например, помимо класса "Кошка", у нас есть никак не связанный с ним класс "Попугай" - и у обоих есть метод "спать". Несмотря на то, что кошки и попугаи спят по-разному (кошка сворачивается клубком, а попугай сидит на жёрдочке), для этих действий можно использовать одну команду.</p>
81
Классы-потомки наследуют свойства и методы классов-родителей, а также добавляют новые<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Этот принцип позволяет применять одни и те же команды к объектам разных классов, даже если они выполняются по-разному. Например, помимо класса "Кошка", у нас есть никак не связанный с ним класс "Попугай" - и у обоих есть метод "спать". Несмотря на то, что кошки и попугаи спят по-разному (кошка сворачивается клубком, а попугай сидит на жёрдочке), для этих действий можно использовать одну команду.</p>
82
Метод один и тот же, но действия разные<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Классами в C# является практически всё - строки, числа, массивы и так далее. У каждого из них есть свой набор свойств (например, количество символов в строке или размер типа данных), а также методы, которые позволяют удобно работать с объектами класса (например, отсортировать массив или сложить два числа).</p>
82
Метод один и тот же, но действия разные<em>Инфографика: Оля Ежак / Skillbox Media</em><p>Классами в C# является практически всё - строки, числа, массивы и так далее. У каждого из них есть свой набор свойств (например, количество символов в строке или размер типа данных), а также методы, которые позволяют удобно работать с объектами класса (например, отсортировать массив или сложить два числа).</p>
83
<p>На основе "базовых" классов из C#, мы можем создавать свои. К примеру, возьмём числа типа Int64 и создадим с помощью них числа с плавающей точкой. Такой класс, конечно, уже есть, но мы можем переопределить его по-своему.</p>
83
<p>На основе "базовых" классов из C#, мы можем создавать свои. К примеру, возьмём числа типа Int64 и создадим с помощью них числа с плавающей точкой. Такой класс, конечно, уже есть, но мы можем переопределить его по-своему.</p>
84
<p>Изучая C#, разработчик в первый же день сталкивается с классами и объектами. Например, вот как выглядит первая программа любого новичка:</p>
84
<p>Изучая C#, разработчик в первый же день сталкивается с классами и объектами. Например, вот как выглядит первая программа любого новичка:</p>
85
using System; namespace OOPConsole { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } } }<p>Здесь создаётся класс Program, у которого есть метод Main() - с него начинается выполнение программы, поэтому его называют точкой входа.</p>
85
using System; namespace OOPConsole { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } } }<p>Здесь создаётся класс Program, у которого есть метод Main() - с него начинается выполнение программы, поэтому его называют точкой входа.</p>
86
<p>Для вывода текста используется следующий оператор:</p>
86
<p>Для вывода текста используется следующий оператор:</p>
87
Console.WriteLine("Hello, World!");<p>Тут программа обращается к объекту Console и вызывает метод WriteLine(), который выводит переданное значение в консоль.</p>
87
Console.WriteLine("Hello, World!");<p>Тут программа обращается к объекту Console и вызывает метод WriteLine(), который выводит переданное значение в консоль.</p>
88
<p>Также у объекта Console есть разные свойства:</p>
88
<p>Также у объекта Console есть разные свойства:</p>
89
Console.ForegroundColor = ConsoleColor.Red; //Цвет шрифта - красный Console.BackgroundColor = ConsoleColor.Blue; //Цвет фона - синий<p>Если бы не было объекта, было бы сложно определить, цвет какого фона и какого шрифта будет указываться, потому что их в программе может быть несколько.</p>
89
Console.ForegroundColor = ConsoleColor.Red; //Цвет шрифта - красный Console.BackgroundColor = ConsoleColor.Blue; //Цвет фона - синий<p>Если бы не было объекта, было бы сложно определить, цвет какого фона и какого шрифта будет указываться, потому что их в программе может быть несколько.</p>
90
<p>Вот что выведет программа:</p>
90
<p>Вот что выведет программа:</p>
91
<em>Скриншот: Skillbox Media</em><p>Чтобы создать класс, откройте в Visual Studio меню<strong>Project</strong>и выберите пункт<strong>Add Class…</strong>:</p>
91
<em>Скриншот: Skillbox Media</em><p>Чтобы создать класс, откройте в Visual Studio меню<strong>Project</strong>и выберите пункт<strong>Add Class…</strong>:</p>
92
<em>Скриншот: Skillbox Media</em><p>Затем введите его название и нажмите<strong>Add</strong>:</p>
92
<em>Скриншот: Skillbox Media</em><p>Затем введите его название и нажмите<strong>Add</strong>:</p>
93
<em>Скриншот: Skillbox Media</em><p>Программа создаст отдельный файл с таким кодом:</p>
93
<em>Скриншот: Skillbox Media</em><p>Программа создаст отдельный файл с таким кодом:</p>
94
namespace OOPConsole { class Character { } }<p>Разберём его по порядку.</p>
94
namespace OOPConsole { class Character { } }<p>Разберём его по порядку.</p>
95
<p>Namespace - это пространство имён, в котором находится класс. Оно необходимо для того, чтобы не возникало конфликтов с именами классов и переменных из подключаемых библиотек. Например, можно создать свой класс Console, и это не будет ошибкой, потому что он будет находиться в другом пространстве имён.</p>
95
<p>Namespace - это пространство имён, в котором находится класс. Оно необходимо для того, чтобы не возникало конфликтов с именами классов и переменных из подключаемых библиотек. Например, можно создать свой класс Console, и это не будет ошибкой, потому что он будет находиться в другом пространстве имён.</p>
96
OOPConsole.Console.WriteLine(); //Класс, созданный в пространстве имён программы System.Console.WriteLine(); //Класс из системного пространства имён<p>Затем в коде следует ключевое слово class, которое говорит о том, что нужно создать класс с определённым именем. В данном случае - Character.</p>
96
OOPConsole.Console.WriteLine(); //Класс, созданный в пространстве имён программы System.Console.WriteLine(); //Класс из системного пространства имён<p>Затем в коде следует ключевое слово class, которое говорит о том, что нужно создать класс с определённым именем. В данном случае - Character.</p>
97
<p>Запомните! Имена классов принято писать с заглавной буквы, а объектов - со строчной.</p>
97
<p>Запомните! Имена классов принято писать с заглавной буквы, а объектов - со строчной.</p>
98
<p>Всё, что находится внутри фигурных скобок, относится к этому классу. Несмотря на то, что он пустой, уже можно создать его экземпляр - объект. Это называется объявлением или инстанцированием.</p>
98
<p>Всё, что находится внутри фигурных скобок, относится к этому классу. Несмотря на то, что он пустой, уже можно создать его экземпляр - объект. Это называется объявлением или инстанцированием.</p>
99
<p>Чтобы объявить объект, нужно перейти к методу main и использовать следующий код:</p>
99
<p>Чтобы объявить объект, нужно перейти к методу main и использовать следующий код:</p>
100
Character hero = new Character();<p>Это похоже на то, как создаются переменные, но вместо типа данных указывается название класса. После знака присваивания указываются ключевое слово new и конструктор - специальный метод, который позволяет создать объект (о нём читайте в <a>блоке о методах</a>).</p>
100
Character hero = new Character();<p>Это похоже на то, как создаются переменные, но вместо типа данных указывается название класса. После знака присваивания указываются ключевое слово new и конструктор - специальный метод, который позволяет создать объект (о нём читайте в <a>блоке о методах</a>).</p>
101
<p>Теперь можно добавить поля и свойства для класса. Поле объявляется как обычная переменная:</p>
101
<p>Теперь можно добавить поля и свойства для класса. Поле объявляется как обычная переменная:</p>
102
class Character { int health = 100; int x = 50; int y = 25; }<p>Теперь у объекта есть свои поля, но к ним нельзя обратиться извне, потому что закрыт доступ (подробнее об этом - в статье про инкапсуляцию). Чтобы его открыть, нужно поставить перед каждым полем ключевое слово public. То же слово нужно поставить перед словом class.</p>
102
class Character { int health = 100; int x = 50; int y = 25; }<p>Теперь у объекта есть свои поля, но к ним нельзя обратиться извне, потому что закрыт доступ (подробнее об этом - в статье про инкапсуляцию). Чтобы его открыть, нужно поставить перед каждым полем ключевое слово public. То же слово нужно поставить перед словом class.</p>
103
public class Character { public int health = 100; public int x = 50; public int y = 25; }<p>Теперь можно вернуться к созданному объекту и обратиться к его полю здоровья:</p>
103
public class Character { public int health = 100; public int x = 50; public int y = 25; }<p>Теперь можно вернуться к созданному объекту и обратиться к его полю здоровья:</p>
104
Console.WriteLine(hero.health);<p>Вот что будет выведено:</p>
104
Console.WriteLine(hero.health);<p>Вот что будет выведено:</p>
105
<em>Скриншот: Skillbox Media</em><p>Если доступ к полям открыт, то с ними можно проводить вычисления или просто получать их значения. Если же нужно запретить доступ к определённым полям - используйте свойства.</p>
105
<em>Скриншот: Skillbox Media</em><p>Если доступ к полям открыт, то с ними можно проводить вычисления или просто получать их значения. Если же нужно запретить доступ к определённым полям - используйте свойства.</p>
106
<p>Это специальные конструкции, которые позволяют обращаться к полям. Чтобы создать свойства, нужно сначала закрыть доступ к полям с помощью уровня доступа private - тогда они будут доступны только изнутри класса:</p>
106
<p>Это специальные конструкции, которые позволяют обращаться к полям. Чтобы создать свойства, нужно сначала закрыть доступ к полям с помощью уровня доступа private - тогда они будут доступны только изнутри класса:</p>
107
public class Character { private int health = 100; private int x = 50; private int y = 25; }<p>Теперь нельзя узнать здоровье или координаты объекта или изменить их. Чтобы снова открыть к ним доступ, создайте свойства:</p>
107
public class Character { private int health = 100; private int x = 50; private int y = 25; }<p>Теперь нельзя узнать здоровье или координаты объекта или изменить их. Чтобы снова открыть к ним доступ, создайте свойства:</p>
108
public int Health { get { return this.health; } set { this.health = value; } } public int X { get { return this.x; } }<p>Тут указывается уровень доступа public, затем тип свойства и его имя. Имена свойств принято писать с заглавной буквы, и они должны соответствовать имени поля. Внутри свойства встречаются две конструкции:</p>
108
public int Health { get { return this.health; } set { this.health = value; } } public int X { get { return this.x; } }<p>Тут указывается уровень доступа public, затем тип свойства и его имя. Имена свойств принято писать с заглавной буквы, и они должны соответствовать имени поля. Внутри свойства встречаются две конструкции:</p>
109
<ul><li>get (геттер - позволяет получить значение свойства) - возвращает значение, которое идёт после ключевого слова return;</li>
109
<ul><li>get (геттер - позволяет получить значение свойства) - возвращает значение, которое идёт после ключевого слова return;</li>
110
<li>set (сеттер - позволяет изменить значение) - указывает поле, которое нужно изменить, используя значение value.</li>
110
<li>set (сеттер - позволяет изменить значение) - указывает поле, которое нужно изменить, используя значение value.</li>
111
</ul><p>Также тут можно заметить ключевое слово this, которое обозначает, что поле принадлежит этому объекту. Использовать его необязательно, но оно делает код более читаемым.</p>
111
</ul><p>Также тут можно заметить ключевое слово this, которое обозначает, что поле принадлежит этому объекту. Использовать его необязательно, но оно делает код более читаемым.</p>
112
<p>Такие манипуляции нужны для того, чтобы доступ к полям осуществлялся только так, как это нужно разработчику. Например, можно создать свойство, значение которого будет зависеть от выполнения условия:</p>
112
<p>Такие манипуляции нужны для того, чтобы доступ к полям осуществлялся только так, как это нужно разработчику. Например, можно создать свойство, значение которого будет зависеть от выполнения условия:</p>
113
public bool IsAlive { get { return this.health > 0 ? true : false; } }<p>Значение, которое будет возвращено, зависит от здоровья персонажа. Если оно ниже нуля, то будет передано false, а если выше - true.</p>
113
public bool IsAlive { get { return this.health > 0 ? true : false; } }<p>Значение, которое будет возвращено, зависит от здоровья персонажа. Если оно ниже нуля, то будет передано false, а если выше - true.</p>
114
<p>Вот как это работает в программе:</p>
114
<p>Вот как это работает в программе:</p>
115
Console.WriteLine($"Hero's health: {hero.Health} | Hero is alive: {hero.IsAlive}"); hero.Health = 0; Console.WriteLine($"Hero's health: {hero.Health} | Hero is alive: {hero.IsAlive}");<p>Вот что будет выведено на экран:</p>
115
Console.WriteLine($"Hero's health: {hero.Health} | Hero is alive: {hero.IsAlive}"); hero.Health = 0; Console.WriteLine($"Hero's health: {hero.Health} | Hero is alive: {hero.IsAlive}");<p>Вот что будет выведено на экран:</p>
116
<em>Скриншот: Skillbox Media</em><p>Теперь можно приступить к работе с поведением объектов. Оно реализуется с помощью методов - специальных блоков кода, которые позволяют избежать повторений в проекте.</p>
116
<em>Скриншот: Skillbox Media</em><p>Теперь можно приступить к работе с поведением объектов. Оно реализуется с помощью методов - специальных блоков кода, которые позволяют избежать повторений в проекте.</p>
117
<p>Методы являются аналогами функций (возвращают значение) и процедур (не возвращают), но с той разницей, что они являются частью какого-то класса. Например, можно в классе Character создать метод Move(), который будет отвечать за движение персонажа.</p>
117
<p>Методы являются аналогами функций (возвращают значение) и процедур (не возвращают), но с той разницей, что они являются частью какого-то класса. Например, можно в классе Character создать метод Move(), который будет отвечать за движение персонажа.</p>
118
public void Move(string direction) { switch (direction) { case "forward": this.x++; break; case "backward": this.x--; break; case "up": this.y++; break; case "down": this.y--; break; } }<p>Сначала указывается уровень доступа public, затем тип возвращаемого значения (в данном случае используется void, что говорит компилятору о том, что ничего возвращать не нужно). Затем идёт название метода и круглые скобки.</p>
118
public void Move(string direction) { switch (direction) { case "forward": this.x++; break; case "backward": this.x--; break; case "up": this.y++; break; case "down": this.y--; break; } }<p>Сначала указывается уровень доступа public, затем тип возвращаемого значения (в данном случае используется void, что говорит компилятору о том, что ничего возвращать не нужно). Затем идёт название метода и круглые скобки.</p>
119
<p>Внутри скобок указываются аргументы, которые принимает метод (в данном случае направление движения), - от переданных аргументов зависит результат работы метода.</p>
119
<p>Внутри скобок указываются аргументы, которые принимает метод (в данном случае направление движения), - от переданных аргументов зависит результат работы метода.</p>
120
<p>Вот пример вызова метода:</p>
120
<p>Вот пример вызова метода:</p>
121
Character hero = new Character(); string command = string.Empty; while (command != "exit") { Console.WriteLine($"You are at {hero.Coordinates}. Where to go?"); command = Console.ReadLine(); hero.Move(command); }<p>Пользователь видит свои координаты и вводит направление движения, а персонаж двигается с помощью метода Move(). Всё это повторяется, пока не будет введена команда exit.</p>
121
Character hero = new Character(); string command = string.Empty; while (command != "exit") { Console.WriteLine($"You are at {hero.Coordinates}. Where to go?"); command = Console.ReadLine(); hero.Move(command); }<p>Пользователь видит свои координаты и вводит направление движения, а персонаж двигается с помощью метода Move(). Всё это повторяется, пока не будет введена команда exit.</p>
122
<p>Вот как это выглядит:</p>
122
<p>Вот как это выглядит:</p>
123
<em>Скриншот: Skillbox Media</em><p>Если же нужно, чтобы метод что-то возвращал, то указывается его тип и используется оператор return:</p>
123
<em>Скриншот: Skillbox Media</em><p>Если же нужно, чтобы метод что-то возвращал, то указывается его тип и используется оператор return:</p>
124
public bool Collide(Character ch) { if (ch.X == this.x && ch.Y == this.y) { return true; } else { return false; } }<p>Этот метод принимает в качестве аргумента объект класса Character и сравнивает координаты. Если они равны, то метод возвращает значение true, а иначе - false.</p>
124
public bool Collide(Character ch) { if (ch.X == this.x && ch.Y == this.y) { return true; } else { return false; } }<p>Этот метод принимает в качестве аргумента объект класса Character и сравнивает координаты. Если они равны, то метод возвращает значение true, а иначе - false.</p>
125
<p>Вот как это можно использовать:</p>
125
<p>Вот как это можно использовать:</p>
126
Character hero = new Character(); Character npc = new Character(); bool collide = hero.Collide(npc); if (collide) { Console.WriteLine("Objects are on the same position."); } else { Console.WriteLine("Objects are not on the same position."); } Console.ReadKey();<p>Приведённая выше программа сравнит координаты двух объектов и выведет результат. Так как объекты создаются с одинаковыми полями, то они будут равны:</p>
126
Character hero = new Character(); Character npc = new Character(); bool collide = hero.Collide(npc); if (collide) { Console.WriteLine("Objects are on the same position."); } else { Console.WriteLine("Objects are not on the same position."); } Console.ReadKey();<p>Приведённая выше программа сравнит координаты двух объектов и выведет результат. Так как объекты создаются с одинаковыми полями, то они будут равны:</p>
127
<em>Скриншот: Skillbox Media</em><p>В примере выше объект создаётся с уже заданными значениями, но есть возможность указывать свои параметры. Для этого используются конструкторы - специальные методы, которые запускаются при инстанцировании экземпляра класса. С их помощью можно передать объекту параметры и провести необходимые операции.</p>
127
<em>Скриншот: Skillbox Media</em><p>В примере выше объект создаётся с уже заданными значениями, но есть возможность указывать свои параметры. Для этого используются конструкторы - специальные методы, которые запускаются при инстанцировании экземпляра класса. С их помощью можно передать объекту параметры и провести необходимые операции.</p>
128
<p>Вот пример того же класса с конструктором:</p>
128
<p>Вот пример того же класса с конструктором:</p>
129
public class Character { private string name; private int health; private int x; private int y; public Character(string name, int x, int y) { this.name = name; this.x = x; this.y = y; this.health = 100; Console.WriteLine($"Object {this.name} was created at {this.Coordinates}."); } //Геттеры и сеттеры из прошлых примеров }<p>Конструктор выглядит как метод, но ему не нужно указывать тип возвращаемых данных - он возвращает созданный объект. Теперь, чтобы объявить экземпляр класса, нужно вызвать конструктор с указанным количеством аргументов:</p>
129
public class Character { private string name; private int health; private int x; private int y; public Character(string name, int x, int y) { this.name = name; this.x = x; this.y = y; this.health = 100; Console.WriteLine($"Object {this.name} was created at {this.Coordinates}."); } //Геттеры и сеттеры из прошлых примеров }<p>Конструктор выглядит как метод, но ему не нужно указывать тип возвращаемых данных - он возвращает созданный объект. Теперь, чтобы объявить экземпляр класса, нужно вызвать конструктор с указанным количеством аргументов:</p>
130
Character hero = new Character("Player", 50, 20); Character npc = new Character("Enemy", 20, 30); Console.ReadKey();<p>Вот что выведет программа:</p>
130
Character hero = new Character("Player", 50, 20); Character npc = new Character("Enemy", 20, 30); Console.ReadKey();<p>Вот что выведет программа:</p>
131
<em>Скриншот: Skillbox Media</em><p>Создайте консольную игру, в которой игрок сможет управлять персонажем с помощью команд. Возможности, которые должны быть в игре:</p>
131
<em>Скриншот: Skillbox Media</em><p>Создайте консольную игру, в которой игрок сможет управлять персонажем с помощью команд. Возможности, которые должны быть в игре:</p>
132
<ul><li>перемещение;</li>
132
<ul><li>перемещение;</li>
133
<li>атака;</li>
133
<li>атака;</li>
134
<li>получение опыта за победу над врагами;</li>
134
<li>получение опыта за победу над врагами;</li>
135
<li>повышение уровня и здоровья персонажа.</li>
135
<li>повышение уровня и здоровья персонажа.</li>
136
</ul><p>Это лишь вступление в ООП, и ещё многое предстоит изучить, чтобы начать применять его в полную силу. Например, нужно понять, как технически работают классы, как они хранятся в памяти, почему их называют ссылочными типами и так далее.</p>
136
</ul><p>Это лишь вступление в ООП, и ещё многое предстоит изучить, чтобы начать применять его в полную силу. Например, нужно понять, как технически работают классы, как они хранятся в памяти, почему их называют ссылочными типами и так далее.</p>
137
<p>ООП - сложная, но эффективная парадигма программирования. Её стоит знать всем, кто хочет создавать программы и найти работу, потому что почти все популярные языки её поддерживают. И несмотря на то, что некоторые разработчики утверждают, будто "<a>ООП умерло</a>", потребность в программистах, которые владеют этим подходом, продолжает расти.</p>
137
<p>ООП - сложная, но эффективная парадигма программирования. Её стоит знать всем, кто хочет создавать программы и найти работу, потому что почти все популярные языки её поддерживают. И несмотря на то, что некоторые разработчики утверждают, будто "<a>ООП умерло</a>", потребность в программистах, которые владеют этим подходом, продолжает расти.</p>
138
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
138
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>