Программирование - это просто
Advertisement
Главная arrow Уроки C# arrow Средства и особенности C#, о которых знают не все arrow Средства C#. Урок 2. Использование методов new и override.
06.10.2022 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
Средства C#. Урок 2. Использование методов new и override. Печать E-mail
Автор megabax   
28.02.2013 г.
New Page 1

Средства C#. Урок 2. Использование методов new и override.

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

Теперь представим себе, что у базового класса светофора есть метод ChangeLights (поменять сигналы). Этот метод вызывается из метода, ответственного за обработку кванта времени, выделенного объекту "светофор" объектом "менеджер моделирования". Теперь представим себе, что мы создали на основе этого базового класса несколько разновидностей светофора, у каждого определив свой метод ChangeLights. А вот обработчик выделенного кванта времени у всех светофоров одинаков. Теперь представим, что у нас есть некий контейнер (массив или список) для хранения объектов, моделирующих светофор. Так как мы не знаем, какого типа будет светофор, то список будет заточен для хранения базовых классов - мы может с легкостью использовать переменную базового класса хранения объектов дочерних классов. Но есть одна проблема. При обработке кванта времени у нас будет вызываться от базового класса. Тоесть, дочерние объекты работать не будут! Как же быть? Не стоит паниковать, в C# есть возможность объявить метод виртуальным. Тоесть, в базовом классе вы объявите его с модификатором virtual,  а в дочерних override. Теперь у нас все будет работать правильно. Тоесть, несмотря на то, что элемент массива объявлен типом базового класса, вызывается будет метод ChangeLights того класса, которому реально принадлежит объект.

А теперь предположим гипотетическую ситуацию, когда нам не надо, что бы вызывался метод реально класса, а вызывался того класса, которым объявлена переменная. В этом случае мы объявим метод с модификатором new. Тот же эффект будет, если мы объявим метод вообще без модификатора. Тогда встает вопрос, а в чем разница между new и "без new"? Что бы ответить на этот вопрос, рассмотрим пример:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Child1 c1 = new Child1();

            c1.MyMethod();

            System.Console.WriteLine("---------------------");

            Child2 c2 = new Child2();

            c2.MyMethod();

            System.Console.WriteLine("---------------------");

            Child3 c3 = new Child3();

            c3.MyMethod();

            System.Console.WriteLine("---------------------");

 

            BaseClass b1 = new Child1();

            b1.MyMethod();

            System.Console.WriteLine("---------------------");

            BaseClass b2 = new Child2();

            b2.MyMethod();

            System.Console.WriteLine("---------------------");

            BaseClass b3 = new Child3();

            b3.MyMethod();

            System.Console.WriteLine("---------------------");

 

            System.Console.Read();

        }

    }

 

    class BaseClass

    {

        public virtual void MyMethod()

        {

            System.Console.WriteLine("It is BaseClass");

            Output();

        }

        protected virtual void Output()

        {

            System.Console.WriteLine("Base class protected method");

        }

    }

 

    class Child1 : BaseClass

    {

        public override void MyMethod()

        {

            System.Console.WriteLine("It is Child1");

            Output();

        }

    }

 

    class Child2 : BaseClass

    {

        public new void MyMethod()

        {

            System.Console.WriteLine("It is Child2");

            Output();

        }

        protected override void Output()

        {

            System.Console.WriteLine("Child2 class protected method");

        }

 

    }

 

    class Child3 : BaseClass

    {

        public void MyMethod()

        {

            System.Console.WriteLine("It is Child3");

            Output();

        }

        public new void Output()

        {

            System.Console.WriteLine("Child3 class public method");

        }

 

    }

}

Давайте скомпилируем эту программу, запустим и посмотрим, что она выдаст, а потом разберем ее более подробно:

Средства C#. Урок 2. Использование методов new и override.

И так, у нас есть базовый класс BaseClass и три дочерних от него класса Child1, Child2 и Child3.

Сначала мы испытываем метод MyMethod класса Child1, когда у нас переменная объявлена как Child1. Что происходит? Вызывается метод MyMethod  класса Child1 и печатает "It is Child1", а затем вызывается метод Output. Какого класса? Разумеется BaseClass, так как у класса Child1 он не реализован. И вторую строку мы видим "Base class protected method".

Далее идет класс Child2, его метод MyMethod  печатает "It is Child2" и вызывает метод Output(). Так как у Child2  он реализован, то вызывается именно метод класса Child2: у нас и переменная и сам объект имеют класс Child2. В итоге следующую строку получаем: "Child2 class protected method".

Программа переходит к классу Child3. У этого класса метод MyMethod  печатает "It is Child3"  и вызывает метод Output(). Так как у Child3  он реализован, то вызывается именно метод класса Child3: у нас и переменная и сам объект имеют класс Child3. В итоге следующую строку получаем: "Child3 class public method".

Теперь тестируем все эти три класса на переменных типа BaseClass.

Сначала вызываем метод MyMethod  класса Child1. Этот метод у нас виртуальный (virtual) и переопределенный (override), поэтому, будет вызван метод MyMethod класса Child1, а не BaseClass. Получаем сообщение "It is Child1". Все правильно. Затем вызывается метод Output(). Какого класса? Разумеется BaseClass, так как у класса Child1 он не реализован. И вторую строку мы видим "Base class protected method".

Переходим к Child2. Вызываем метод MyMethod. От какого класса он будет вызван? Разумеется, BaseClass. Почему? В классе Child2 он объявлен с модификатором new. Тоесть, мы не переопределяем метод, и он будет вызван тот, какого типа переменная. Данная переменная имеет тип BaseClass. И мы получаем сообщение "It is BaseClass". Далее, этот метод вызывает метод Output.  Какого класса? Child2, метод Output определен с модификатором override. В итоге программа выдает сообщение: "Child2 class protected method".

Теперь Child3. Метод MyMethod в классе Child3 объявлен без модификатора. Он тоже не переопределен. Вызывается метод BaseClass, так как переменна имеет тип BaseClass. Аналогично для метода Output, он объявлен с модификатором new.

Как видим, если метод объявлен в модификатором override, то при его вызове будет вызван метод реального класса, а если без модификатора или с модификатором new - то будет вызван метод того класса, какого типа переменная. Спрашивается, а в чем разница между new и без модификатора? А в том, что если метод объявлен без модификатора, то его уровень доступа наследуется от родительского класса, а если с модификатором new - можно менять уровень доступа. Например, если в родительском классе метод был protected, то благодаря new в дочернем классе его можно сделать public.

 

Последнее обновление ( 28.02.2013 г. )
 
« След.   Пред. »
 
© 2022 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги