Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перегрузка функций как в Си++ или как в Джаве? 
V
    Опции темы
Dims
Дата 26.10.2008, 01:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 0
Всего: 11



В Си++ было так, что если в подклассе определяешь функцию с такой же сигнатурой, что и в надклассе, то ничего не происходило, функция просто перекрывала надфункцию для кода внутри подкласса.

Чтобы функция подменялась, её нужно было определять, как виртуальную.

В Джаве все функции виртуальные и ничего писать для этого не надо.

Каковы функции в С#?
PM MAIL   Вверх
diadiavova
Дата 26.10.2008, 04:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Если нужно, чтобы функция была виртуальной надо указать virtual, а если она абстрактная - указываем abstract, а в производном классе переопределяемую функцию надо пометить как override? для затенения используется new

Код

    abstract  class a
    {
       public abstract string GetStr();
        public virtual int GetInt()
        {
            return 3;
        }

        public bool IsGood()
        {
            return true;
        }
    }

     class b : a
    {
        public override int GetInt()
        {
            return base.GetInt() + 1;
        }

        public override string GetStr()
        {
             return "blablabla";
        }

        new bool IsGood()
        {
            return false;
        }
    }



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Dims
Дата 26.10.2008, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 0
Всего: 11



А зачем может быть нужно затенение?
PM MAIL   Вверх
diadiavova
Дата 26.10.2008, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Перопределить можно только абстрактные и виртуальные члены класса. Если по какой-либо причине в производном классе нужен например метод, имеющий определённую сигнатуру, а в базовом классе есть такой метод, но он не нужен и не является ни абстрактным, ни виртуальным, то используется затенение. Это даёт возможность избежать конфликтов имён.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Partizan
Дата 26.10.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 18
Всего: 67



Использование ключевого слова new по сути вас просто избавит от надоедливого warning-a, выдаваемого студией smile


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
diadiavova
Дата 26.10.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Ну тут есть и практический аспект. Допустим надо создать класс, наследующий  какой-то другой класс, в котором определено много разных членов. Естественно помнить их все наперечёт трудно, да и ни к чему. 
Далее разработчик включает в класс свой метод, в то время как такой же метод есть в базовом классе. Допустим студия молчит, метод затеняется без предупреждений, а после этого класс используется другими разработчиками, которые смотрят, от чего унаследован класс и естественно используют члены , унаследованные от базового класса. Вызывают затенённый метод и эффект от него оказывается неожиданным. А на этом методе в программе может быть много чего завязанно. Поэтому указание, что метод затенён - скорее сообщение компилятору, что разработчик выбрал имя не по ошибке, а напротив знает, что делает, и делает это намеренно. Я бы так сформулировал.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
VK_Techno
Дата 26.10.2008, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 29.9.2007

Репутация: нет
Всего: нет



Цитата(Partizan @ 26.10.2008,  14:23)
Использование ключевого слова new по сути вас просто избавит от надоедливого warning-a, выдаваемого студией smile

и покажет, что в производном классе намеренно скрыт метод / поле / свойство / etc. из класса-предка.
PM MAIL   Вверх
Partizan
Дата 26.10.2008, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 18
Всего: 67



VK_Techno, это да...но я имею виду, что всё будет нормально работать и без использования new...


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
QryStaL
Дата 26.10.2008, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Кроме этого, new используется для "прерывания" цепочки наследования и начала ее заново - в таком случае пишется new virtual. Еще бывают извраты типа new abstract.  smile 


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
diadiavova
Дата 26.10.2008, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Цитата(QryStaL @  26.10.2008,  22:09 Найти цитируемый пост)
Кроме этого, new используется для "прерывания" цепочки наследования и начала ее заново - в таком случае пишется new virtual. Еще бывают извраты типа new abstract.

Можно, конечно, и для "прерывания", только на самом деле цепочка не прерывется. Члены продолжают наследоваться, только к ним нет прямого досткпа. В качестве илюстрации приведу пример.
Создаём 3 класса ab и сb наследуется от a,  c  - от b
В классе a определяем метод GetClassName, который будет возвращать строку "Класс а", в классе b затеняем этот метод, теперь он возвращает строку "Класс b"
Один нюанс в классе а метод помечаем как public, а в классе b как private. И во всех трёх классах определяем свойство ClassName которое будет вызывать функцию и возвращать её значение.
Код

  public  class a
    {
      public string GetClassName()
        {
            return "Класс а";
        }

      virtual public string ClassName
       {
           get
           {
               return GetClassName();
           }
       }
    }

     class b : a
    {

         new private string GetClassName()
        {
            return "Класс b";
        }

         override public string ClassName
         {
             get
             {
                 return this.GetClassName();
             }
         }
    }

     class c : b
     {
         override public string ClassName
         {
             get
             {
                 return this.GetClassName();
             }
         }
     }



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

Код

            a o1 = new a();
            b o2 = new b();
            c o3 = new c();
            string newLine = char.ConvertFromUtf32(13) + char.ConvertFromUtf32(10);
            string s = o1.ClassName + newLine + o2.ClassName + newLine + o3.ClassName;



дальше значение переменной s выводим для просмотра

Код

Класс а
Класс b
Класс а

Таким образом не смотря на то, что в классе b мы затенили метод GetClassName private - методом с той же сигнатурой, в производном классе с тем не менее спокойно вызывается метод который ранее был затенён. Просто теперь, когда затеняющий метод не виден, мы снова получили доступ к затенённому методу.



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
QryStaL
Дата 26.10.2008, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Цитата(diadiavova @  26.10.2008,  23:35 Найти цитируемый пост)
только на самом деле цепочка не прерывется. Члены продолжают наследоваться

Про наследование спору нет. Имелся в виду вызов соответствующего метода при приведении типов и полиморфном вызове.


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
diadiavova
Дата 26.10.2008, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Цитата(QryStaL @  26.10.2008,  23:54 Найти цитируемый пост)
Про наследование спору нет.

Я и не пытался спорить, просто определение звучит несколько двусмысленно, поэтому я просто пояснил.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
QryStaL
Дата 27.10.2008, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Intellectual feast
**


Профиль
Группа: Участник
Сообщений: 914
Регистрация: 30.11.2005

Репутация: 14
Всего: 32



Цитата(diadiavova @  26.10.2008,  23:57 Найти цитируемый пост)
определение звучит несколько двусмысленно, поэтому я просто пояснил.

Ок. =)
Вроде выяснили, теперь слово за автором темы...


--------------------
I don't need a reason being who I am...
PM MAIL ICQ   Вверх
diadiavova
Дата 27.10.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Да я чойта подзреваю, что вопросы ещё будут. Тема мутная. smile 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Dims
Дата 27.10.2008, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 0
Всего: 11



Цитата(diadiavova @  26.10.2008,  13:39 Найти цитируемый пост)
Если по какой-либо причине в производном классе нужен например метод, имеющий определённую сигнатуру, а в базовом классе есть такой метод, но он не нужен и не является ни абстрактным, ни виртуальным, то используется затенение. Это даёт возможность избежать конфликтов имён. 


Ну это получается какое-то шаманское объяснение. Причины и следствия какие-то отвлечённые от жизни. Вот я уже давным давно программирую на Джаве и ни разу не пожалел, что там все функции виртуальные. 

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

Добавлено через 5 минут и 34 секунды
Цитата(diadiavova @  26.10.2008,  19:03 Найти цитируемый пост)
Далее разработчик включает в класс свой метод, в то время как такой же метод есть в базовом классе. Допустим студия молчит, метод затеняется без предупреждений

Ну тут не вопрос, они, конечно, молодцы, что сделали ключевое слово override. Вопрос в том, зачем может понадобиться затенение? Чего оно такого может, чего не может обычное введение новой функции?

Добавлено через 11 минут и 34 секунды
Цитата(QryStaL @  26.10.2008,  22:09 Найти цитируемый пост)
Кроме этого, new используется для "прерывания" цепочки наследования и начала ее заново


А зачем? Допустим, у нас все функции виртуальные. Никакой цепочки же нет. В каждом классе есть своя функция, либо он использует функцию базового класса. Цепочка возникает тогда, когда в методе наследника вызывается перекрытый метод предка. Ну тут уж программист явно написал, значит, хотел.

Я прекрасно помню, зачем это нужно было в Си++ -- чтобы экономить память. Для хранения виртуальной функции нужен, как вариант, указатель на неё. Это добавляет байты в структуру описания класса, так как каждый класс должен помнить свою версию функции. 

А невиртуальная функция определяется типом объекта, к которому она применяется. Так что её помнить не надо, она вставляется на этапе компилляции.



PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1072 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.