Уроки моддинга
Основной раздел
Search
K
Links

000132. ООП в c# Часть 1

ООП в c# Часть 1||wmysterio|wmysterio|[email protected]|||Всем привет! В очередной раз мы рассмотрим возможности ЯП (языка программирования, для тех, кто не знал это сокращение
smile
) C#, и сегодня речь пойдёт о классах. Мы научимся создавать классы и изучим базовые понятия с объектно-ориентированного программирования(ООП). Давайте начнём с понятия "Класс". Класс - это пользовательский тип данных, который содержит в себе некий набор данных, функций. Конструкцию класса вы уже видели много раз из уроков по скриптхук'у:
СПЕЦИФИКАТОР ДОСТУПА ИМЯ КЛАССА { СПЕЦИФИКАТОР ДОСТУПА КОНСТРУКТОР() { } ПОЛЯ, МЕТОДЫ, СВОЙСТВА, ПРОЦЕДУРЫ. }
Как уже звучало в предыдущих уроках, есть 4 спецификатора доступа public, protected, private и internal. Этот спецификатор указывает видимость содержимого класса из вне(то есть за пределами класса). Я составил таблицу, и перечислил разницу между этими спецификаторами:
Спецификатор
Описание
public
Публичный, поле доступно всем желающим объектам, которые работают с этим классом
protected
Защищённый, поле доступно только классу и его потомку
private
Приватное, поле или метод доступно только самому классу
internal
Внутренний, поле доступно только в одной области пространства имён. Не будет виден для другого namespace.
Пример класса вы видели из предыдущих уроков по c#. По-этому для вас объявить класс не составит проблем. Вот у меня получился примерно такой:
public class Car { public int Speed = 0; public int Accelerate = 0; public int Handling = 0; public Car() { // Пустой конструктор } public void SetSpeed(int NewSpeed) { Speed = NewSpeed; } }
Зелёным цветом обозначены изначальные данные, которые свойственны этому классу. Их называют полями класса. Синим цветом обозначен конструктор класса. Фиолетовым цветом обозначены функции, которые может выполнять объект класса. В C# такие функции принято называть методами, так что метод - это та же функция. Количество полей, методов и конструкторов в классе может быть сколько угодно. Так же само и классов в пространстве имён может быть сколько влезет. Давайте создадим ещё один класс:
public class Lanborghini { public int DoorCount = 4; public string EngineType = "Automatic"; public Lanborghini() { // Пустой конструктор } }
Существует такое понятие, как наследование классов. В народе это известно как понятия "Предок-Потомок", "Отец-Сын", "Иерархия классов". Это понятия говорит о том, что класс-наследник(Сын, Потомок) может наследовать свойства, процедуры класса "Предка"("Отца"). Если навести пример из жизни, то Сын Иван может наследовать некие особые приметы Отца Дмитрия, например, цвет глаз, манеру походки и тому подобное. Давайте сделаем тоже самое в программировании. Для этого нужно объявить класса-наследника. Пусть это будет Ламборгини, который наследует класс Машина. Наш код теперь будет иметь следующий вид:
public class Car { public int Speed = 0; public Car() { } public void SetSpeed(int NewSpeed) { Speed = NewSpeed; } } public class Lanborghini : Car{ public int DoorCount = 4; public string EngineType = "Automatic"; public Lanborghini() { } }
Распознать класс-наследника можно по этой записи:
Это значит, что класс Lanborghini наследует некие методы и свойства класса Car и при этом имеет свои же методы. Давайте напишем код программы, где мы создадим объект класса Lanborghini:
using System; namespace Consol { class Program { static void Main() { Lanborghini Lambo = new Lanborghini(); // Здесь будут другие команды Console.ReadKey(); } } public class Car { public int Speed = 0; public Car() { } public void SetSpeed(int NewSpeed) { Speed = NewSpeed; } } public class Lanborghini : Car{ public int DoorCount = 4; public string EngineType = "Automatic"; public Lanborghini() { } } }
Давайте посмотрим какие же свойства и команды имеет объект, что мы создали:
Оранжевым стрелками обозначены поля, которые имеет сам класс Lanborghini. Но откуда взялись поля, обозначены зелёными стрелками??? Здесь и проявилось наследование! Класс заимствовал эти поля из класса Car и теперь мы можем применять их к нашей Ламбо
smile
Теперь важную роль играет спецификаторы доступа. Давайте в классе Car мы напишем private возле процедуры SetSpeed:
И теперь посмотрим, что нам скажет объект Lambo:
Процедура пропала! Таким образом класс Lanborghini не смог наследовать её из класса Car. Теперь, я думаю, вы поняли для чего нужны эти спецификаторы вообще :) Давайте сделаем эксперимент: создадим класс Gallardo, который будет потомком класса Lamborghini, и посмотрим, что унаследует он от Предка:
public class Gallardo : Lanborghini { public int EnginePower = 1500; public int TireSize = 4; public Gallardo() { } }
Создадим в теле программы объект класса Gallardo и посмотрим его наследство (если вы понимаете о чём я
tongue
)
Gallardo MyCar = new Gallardo();
Унаследовал вот что:
Оранжевыми стрелками показаны поля, которые имеет класс Gallardo, зелёными стрелками указаны поля, которые унаследовал класс от Lanborghini. Что же значит синяя стрелка? Он её унаследовал от класса Car. Как такое возможно, ведь мы указали, что наследовать нужно из класса Lanborghini? Здесь можно сделать вывод: "Всё, что наследует класс-Отец от своего класса-Отца наследуется и для потомка". Если взять выражение из жизни, то можно выразится так: "Всё что наследует Отец от своего Дедушки, наследуется и для Сына". В этом и суть иерархии классов. Можно сделать такую картинку, что бы легче понять:
Оранжевыми стрелками указаны поля классов, которые задаются изначально в классе. Зелёными стрелками показано какие поля унаследует класс от своего отца. Синими стрелками показано какие поля унаследуются классом от более "старших" классов Несколько слов скажу о спецификаторе protected. Если в классе Car сделать переменную Speed с этим спецификатором
protected int Speed = 0;
то класс-потом его унаследует, но вызвать его из вне не получится
Но получать доступ к этому полю мы можем внутри. Если в конструкторе мы нажмём CTRL+ПРОБЕЛ, то мы сможем увидеть наследованное поле:
Ключик возле поля указывает, что параметр унаследовался со спецификатором protected. Мы можем создать поле в классе Gallardo, которое будет принимать унаследованное значение
public int GSpeed;
А в конструкторе заполним его:
public Gallardo() { GSpeed = Speed; }
И теперь мы сможем увидеть поле GSpeed в теле основной программы, как поле, унаследованное от Car, которое переданное в поле класса Gallardo (как видите пошла тафтология и повторение терминов, так как я не могу подобрать нужных синонимов к этим словам
smile
):
Если подобное сделать для класса Lanborghini:
public class Lanborghini : Car{ public int DoorCount = 4; public string EngineType = "Automatic"; public int GSpeed; public Lanborghini() { GSpeed = Speed; } } public class Gallardo : Lanborghini { public int EnginePower = 1500; public int TireSize = 4; public Gallardo() { } }
то его потомок унаследует это значение:
И при этом внутри себя может получать доступ к полю своего Дедушки. В следующий части мы поговорим о понятии "Полиморфизма" и.т.п.

С этого урока вы уже понимаете, для чего нужен символ ":" в следующее выражение из уроков о ScriptHoockDotNet:
public class Thread : Script { // ... }
Класс Thread (наш аналог потока из Sanny Builder) наследует поля, свойства, методы, процедуры, классы и тому подобное из "главного" класса Script, который находится в библиотеке ScriptHookDotNet.dll. Это как минимум основы ООП, и у ваш арсенал сриптинга должны входить эти возможности и умение ими воспользоваться. :) Важно! В отличии от некоторых языков программирования, класс-Потомок может наследовать поля только одного класса-Родителя.

P.S Возможно, некоторые вещи я неправильно назвал или описал. Напишите в комментах, что не так, я исправлю.|964|1|0|80243543png425504400474\|49862482png174173|26345781png174156\|42299098png169195|37370351png169173\|46562547png187148|07018888png167195\|90920270png167195||oop_v_c|1392798677