Воскресенье, 22 Декабря 2024, 14:26

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Наследование "на пальцах".
seamanДата: Понедельник, 16 Сентября 2013, 11:32 | Сообщение # 1
старожил
Сейчас нет на сайте
Наследование "на пальцах".

Все в школе изучали на биологии классы, отряды, семейства... Даже если Вы не помните что это такое, Вам должно быть понятно значение слова "Млекопитающие". Это животные, которые выкармливают детенышей молоком. Это их общая черта, которая отличает их от других классов. Можно вести класс:

Код
class Mlekopitajuchie 
   {
            bool mleko = true;
            bool liveRod = true;
   }


второе что их отличает - они живородящие. Для этих двух отличий мы вводим две переменные, которое у всех млекопитающих true. У иных существ эти переменные false.

Классы делятся на отряды. Наследование!

У класса млекопитающих есть 20 отрядов. Всем этим отрядам присущи две указанные черты млекопитающих, но у каждого отряда есть свои какие-то отличительные черты.
Например хищники. Их отличительная особенность - они охотятся на других животных и питаются их мясом. В отличие от них насекомоядные понятно питаются насекомыми. Большинство грызунов питается травами, плодами и семенами растений, корнями и даже древесиной.
Соответственно можно перечислить возможные типы пищи:

Код
enum Food 
   {
            Meat;
            Vegetable;
   ...
   }


И отличать отряды по этому признаку. Однако не нужно забывать, что все они не прекращают быть млекопитающими. Поэтому у них должны быть упомянутые выше две переменные, отличающие млекопитающих. Можно, конечно ввести кучу классов по числу отрядов и у них всех ввести те же самые переменные, что у класса "Млекопитающие". Однако выгоднее будет использовать уже написанный код. Для этого вводится понятие "наследование". Класс, который наследуется от другого класса включает в себя автоматом все переменные и методы этого класса. "Наследует" их.
Т.о. классы "Хищники" и грызуны будут:

Код
class Predator : Mlekopitajuchie 
   {
           Food meal = Food.Meat;
   }
   class Rodent : Mlekopitajuchie
   {
           Food meal = Food.Vegetable;
   }


Наследование записывается так ": имя класса от которого наследуемся".
Как видим мы не указали переменные mleko и liveRod, однако мы спокойно можем их использовать и у классов Predator и Rodent - они их унаследовали от Mlekopitajuchie!
Аналогично можно определить все остальные классы млекопитающих.
Совершенно аналогично все и относительно функций. У млекопитающих можно ввести функцию "Кормление". В которой, например, прибавлять энергию детенышу. Все млекопитающие,- и хищники и грызуны будут иметь эту функцию!

Виртуальные функции. Полиморфизм!

Все млекопитающие питаются. Соответственно в класс можно ввести функцию Eat. Все млекопитающие в детстве питаются молоком. Поэтому в этой функции проверяем есть ли поблизости молоко. Если есть уменьшаем количество молока и прибавляем энергию млекопитающему. Это общее поведение для всех млекопитающих.

Код
void Eat() 
   {
            if(milk > 0)
            {
                milk -= eatMilk;
                energy += ener;
            }
   }


Однако у каждого отряда в пищевом поведении взрослой особи есть свои особенности.
Поэтому в классе "Хищники" нужно изменить функцию Eat. В данном случае проверяем возраст особи и если он больше определенного значения вместо поиска молока начинаем искать мясо. Если же меньше этого значения = ищем молоко.

Код
void Eat() 
   {
            if(age > minAge) eatMeat();
            else base.Eat();
   }


здесь видим новую запись - "base." - таким образом вызываются функции из класса от которого наследовались.

Спросите - а где виртуальные функции? Дело в том, что очень часто нам не важно какого конкретно отряда животное. Поэтому вместо параметра функции типа Predator можно передать Mlekopitajuchie. Все Predator являются также и Mlekopitajuchie. Поэтому даже если в функцию будет передано значение типа Predator - ошибки не будет. Однако если мы вдруг в такой функции вызовем функцию Eat, то будет вызвана функция из класса Mlekopitajuchie, хотя у нас на самом деле Predator. Хотелось бы, чтобы при этом вызывалась соответствующая переданному значению функция. Вот тут приходят на помощь виртуальные функции. Переопределим функции так:
"Млекопитающие"

Код
virtual void Eat() 
   {
            if(milk > 0)
            {
                milk -= eatMilk;
                energy += ener;
            }
   }


"Хищники"

Код
override void Eat() 
   {
            if(age > minAge) eatMeat();
            else base.Eat();
   }


Здесь в Млекопитающие - функция определена как виртуальная, а в Хищники - как переопределенная.
Если теперь мы введем функцию:

Код
void Proba(Mlekopitajuchie animal) 
   {
            Eat();
   }


То внутри ее будет вызвана Eat, соответствующая тому, что мы передадим в качестве параметра. Если Хищник - то будет искать мясо, если Грызун, то растения.
Ощущаете удобство?


Сообщение отредактировал seaman - Понедельник, 16 Сентября 2013, 11:34
lapendownДата: Понедельник, 16 Сентября 2013, 14:10 | Сообщение # 2
постоянный участник
Сейчас нет на сайте
Отлично! Автор молодец) Прошу продолжение уроков по скриптингу "на пальцах" smile
NEBRДата: Понедельник, 16 Сентября 2013, 14:16 | Сообщение # 3
почти ветеран
Сейчас нет на сайте
seaman, молодец, хорошо для новичков расписал. Очень просто ) В свое время мне этой статейки не хватало )

King Size #Gamiron12
JHawkДата: Вторник, 17 Сентября 2013, 04:21 | Сообщение # 4
めゃくちゃちゃ
Сейчас нет на сайте
seaman, неплохо)

Добавлено (17.09.2013, 04:21)
---------------------------------------------
Для новичков урок самое то! А главное он учит понимать логику.

ETUN4Дата: Вторник, 17 Сентября 2013, 15:21 | Сообщение # 5
частый гость
Сейчас нет на сайте
Отличный урок, много узнал.
Andruha93Дата: Среда, 18 Сентября 2013, 21:50 | Сообщение # 6
частый гость
Сейчас нет на сайте
Мдаа оснавательно ! surprised
Ждем продолжения.
Кстати я тут недавно читал уроки Математика в Юнити и мне она понравилась очень понятными примерами того где в играх можно её использовать, поэтому я думаю будет еще круче если будут такие же примеры.
KiraДата: Воскресенье, 22 Сентября 2013, 11:30 | Сообщение # 7
заслуженный участник
Сейчас нет на сайте
Э... что-то я затупил. Вообщем есть два класса class1 и class2, мне нужно получить нечто следующие: class3:class2:class1.
Т.е унаследовать от 2х классов. Но что то не пойму как сделать. wacko


Unity3d разработчик на С#. Лучшее спасибо + в репу.
"Безумие: делать одно и то же снова и снова, и ждать при этом разных результатов".
"Человек, который никогда не ошибался никогда не пробовал ничего нового".
"Если человек может спокойно управлять автомобилем во время поцелуя красивой девушки, значит он уделяет поцелую недостаточно внимания”. Альберт Эйнштейн
error111Дата: Воскресенье, 22 Сентября 2013, 12:04 | Сообщение # 8
заслуженный участник
Сейчас нет на сайте
Цитата (Kira)
Э... что-то я затупил. Вообщем есть два класса class1 и class2, мне нужно получить нечто следующие: class3:class2:class1. Т.е унаследовать от 2х классов. Но что то не пойму как сделать.


Что сложного?
Пишешь 1й класс public Class1: MonoBeheviour
Пишешь 2й класс public Class2: Class1
Ну и пишешь 3й класс public Class3: Class2
Class3 будет наследовать все методы из Class1 и Class2


[Shmup/RPG] Fantasy Shmup!
SarCasmДата: Воскресенье, 22 Сентября 2013, 12:04 | Сообщение # 9
заслуженный участник
Сейчас нет на сайте
Kira, чегооо? Тебе нужно третий унаследовать от второго, который унаследован от первого? Или третий унаследовать от второго И третьего? (в таком случае это все равно что наследовать от Динозавра и Табуретки)

Моя игра Gamiron#11 - Тема Скачать
KiraДата: Воскресенье, 22 Сентября 2013, 15:04 | Сообщение # 10
заслуженный участник
Сейчас нет на сайте
Цитата (SarCasm)
в таком случае это все равно что наследовать от Динозавра и Табуретки

Да да мне нужен, динотабурет.
Мне нужны как класс2 так и класс3. При этом класс2 не должен наследоваться от класс1.
Понятно, надо менять всю логику.


Unity3d разработчик на С#. Лучшее спасибо + в репу.
"Безумие: делать одно и то же снова и снова, и ждать при этом разных результатов".
"Человек, который никогда не ошибался никогда не пробовал ничего нового".
"Если человек может спокойно управлять автомобилем во время поцелуя красивой девушки, значит он уделяет поцелую недостаточно внимания”. Альберт Эйнштейн
seamanДата: Воскресенье, 22 Сентября 2013, 22:42 | Сообщение # 11
старожил
Сейчас нет на сайте
Смотря в каком языке. Шарп не поддерживает множественное наследование. Т.е. нельзя напрямую сделать "Динотабурет". Однако есть обходной маневр. В шарпе есть такая штука - "Интерфейс". Класс может реализовывать много разных интерфейсов.
Наиболее просто понять что такое интерфейс можно взглянув на какой-нибудь универсальный блок питания. Обычно у таких блоков шнур на конце которого несколько разных разъемов. Один можно воткнуть в мобильник, другой в какой-нибудь плейер. Эти разъемы и есть интерфейсы.
Интерфейс записывается так:
Код
public interface IName 
{
       bool MyFunc(float par);
}

Т.е. подобно классу. Только у функций в нем нет тела (операторов, которые что-то делают). Также у них не может быть модификаторов доступа (public).
Тело функции Вы записываете в классе, который реализовывает этот интерфейс. Потому и говорят "реализовывает", а не наследует. У наследуемого класса функции уже что-то делают, у интерфейса только определена их сигнатура (т.е. имя, входные параметры и что возвращает). А что делать определяется в классе, реализующем интерфейс.
С одной стороны такая структура уменьшает повторное использование кода. Реализацию, даже если она одинаковая приходится писать во всех классах, реализующих интерфейс.
С другой стороны это все же позволяет имитировать множественное наследование.
Например у нас есть класс и интерфейс
Код
class Dino 
{
       public virtual void Eat(float){}
}
interface ITaburet
{
       bool SitDown();
}

И есть классы наследующие от Dino и реализующий интерфейс табурета
Код
class DiplodokTab : Dino, ITaburet 
{
    public bool SitDown(){return true;}
}

class TiranosaurTab : Dino, ITaburet
{
    public bool SitDown(){return false;}
}

Можно как в первом топике использовать все преимущества наследования и переопределить метод Eat. Можно с другой стороны где-то написать функцию, которая получает флаг - можно ли на нем сидеть так:
Код
public bool Sit(ITaburet myDino) 
{
        return myDino.SitDown();
}

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


Сообщение отредактировал seaman - Воскресенье, 22 Сентября 2013, 22:46
KiraДата: Среда, 25 Сентября 2013, 19:37 | Сообщение # 12
заслуженный участник
Сейчас нет на сайте
Не к теме но удобная штука не помню как называется, вроде инициализатор.

Код
 
class NPC
{
public int hp,mp,dex,str;

public NPC()
{
//заполняем по умолчанию.
hp=3;
mp=3;
dex=3;
str=3;
}
}

//где то в коде

NPC Lex=new NPC{hp=8,str=6,dex=4};




Unity3d разработчик на С#. Лучшее спасибо + в репу.
"Безумие: делать одно и то же снова и снова, и ждать при этом разных результатов".
"Человек, который никогда не ошибался никогда не пробовал ничего нового".
"Если человек может спокойно управлять автомобилем во время поцелуя красивой девушки, значит он уделяет поцелую недостаточно внимания”. Альберт Эйнштейн
seamanДата: Среда, 25 Сентября 2013, 20:07 | Сообщение # 13
старожил
Сейчас нет на сайте
Цитата
не помню как называется, вроде инициализатор.

Мдя...
Лучше б не писал...
CreatingOverДата: Среда, 25 Сентября 2013, 20:31 | Сообщение # 14
ColdGamedev
Сейчас нет на сайте
seaman, молодец. Мне юнити очень простым по этой статье показался. Плюс.

Я снова с вами:з
Возвращение легенды. (нет)
RangerДата: Понедельник, 11 Ноября 2013, 08:25 | Сообщение # 15
почти ветеран
Сейчас нет на сайте
Прошу прощения за некропост.

Цитата CreatingOver ()
seaman, молодец.

Согласен.

Цитата CreatingOver ()
Мне юнити очень простым по этой статье показался

Это, я думаю, - заблужение.

Цитата seaman ()
внутри ее будет вызвана Eat, соответствующая тому, что мы передадим в качестве параметра. Если Хищник - то будет искать мясо, если Грызун, то растения.
Ощущаете удобство?

А если еще по ходу выполнения добавлять животным как компоненты скрипты поведения (трусость, смелость, агрессия), такую экосистему можно собрать biggrin .




Сообщение отредактировал Ranger - Понедельник, 11 Ноября 2013, 08:30
KamiRoninДата: Понедельник, 11 Ноября 2013, 14:58 | Сообщение # 16
почти ветеран
Сейчас нет на сайте
Цитата Ranger ()
А если еще по ходу выполнения добавлять животным как компоненты скрипты поведения (трусость, смелость, агрессия), такую экосистему можно собрать .

интересно, а ты просек весь смысл твоего предложения? smile на самом деле - очень мощная система бы получилась.. smile


Мыслю - значит программирую...
Конструктивная критика - умных ведет к совершенству...
Великие умы обсуждают идеи, средние - обсуждают поступки, а малые - людей.
RangerДата: Понедельник, 11 Ноября 2013, 15:04 | Сообщение # 17
почти ветеран
Сейчас нет на сайте
Цитата KamiRonin ()
интересно, а ты просек весь смысл твоего предложения?

Я, честно, не просек смысл этого вопроса.


Danteo122Дата: Понедельник, 11 Ноября 2013, 15:29 | Сообщение # 18
постоянный участник
Сейчас нет на сайте
Цитата seaman ()
Мдя

Мужчины в наше время какие то.....как бабы.
Хотя, написал урок неплохо. Насколько я понял, это JS?

Добавлено (11.11.2013, 15:29)
---------------------------------------------
Ааааа, этож Сишарп)))

RangerДата: Понедельник, 11 Ноября 2013, 17:12 | Сообщение # 19
почти ветеран
Сейчас нет на сайте
<делетед...>



Сообщение отредактировал Ranger - Понедельник, 11 Ноября 2013, 17:13
seamanДата: Понедельник, 11 Ноября 2013, 22:59 | Сообщение # 20
старожил
Сейчас нет на сайте
Цитата
в наше время

Интересно, а что Вы вкладываете в это понятие "наше время". "Мое время" - очень растяжимо, аж на 50 лет smile
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг