![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
В Си++ было так, что если в подклассе определяешь функцию с такой же сигнатурой, что и в надклассе, то ничего не происходило, функция просто перекрывала надфункцию для кода внутри подкласса.
Чтобы функция подменялась, её нужно было определять, как виртуальную. В Джаве все функции виртуальные и ничего писать для этого не надо. Каковы функции в С#? |
|||
|
||||
diadiavova |
|
|||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Если нужно, чтобы функция была виртуальной надо указать virtual, а если она абстрактная - указываем abstract, а в производном классе переопределяемую функцию надо пометить как override? для затенения используется new
-------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
|||
|
||||
Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
А зачем может быть нужно затенение?
|
|||
|
||||
diadiavova |
|
|||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Перопределить можно только абстрактные и виртуальные члены класса. Если по какой-либо причине в производном классе нужен например метод, имеющий определённую сигнатуру, а в базовом классе есть такой метод, но он не нужен и не является ни абстрактным, ни виртуальным, то используется затенение. Это даёт возможность избежать конфликтов имён.
-------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
Использование ключевого слова new по сути вас просто избавит от надоедливого warning-a, выдаваемого студией
![]() -------------------- СУВ, Partizan. |
|||
|
||||
diadiavova |
|
|||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Ну тут есть и практический аспект. Допустим надо создать класс, наследующий какой-то другой класс, в котором определено много разных членов. Естественно помнить их все наперечёт трудно, да и ни к чему.
Далее разработчик включает в класс свой метод, в то время как такой же метод есть в базовом классе. Допустим студия молчит, метод затеняется без предупреждений, а после этого класс используется другими разработчиками, которые смотрят, от чего унаследован класс и естественно используют члены , унаследованные от базового класса. Вызывают затенённый метод и эффект от него оказывается неожиданным. А на этом методе в программе может быть много чего завязанно. Поэтому указание, что метод затенён - скорее сообщение компилятору, что разработчик выбрал имя не по ошибке, а напротив знает, что делает, и делает это намеренно. Я бы так сформулировал. -------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
|||
|
||||
VK_Techno |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 29.9.2007 Репутация: нет Всего: нет |
и покажет, что в производном классе намеренно скрыт метод / поле / свойство / etc. из класса-предка. |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 18 Всего: 67 |
VK_Techno, это да...но я имею виду, что всё будет нормально работать и без использования new...
-------------------- СУВ, Partizan. |
|||
|
||||
QryStaL |
|
|||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
Кроме этого, new используется для "прерывания" цепочки наследования и начала ее заново - в таком случае пишется new virtual. Еще бывают извраты типа new abstract.
![]() -------------------- I don't need a reason being who I am... |
|||
|
||||
diadiavova |
|
||||||||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Можно, конечно, и для "прерывания", только на самом деле цепочка не прерывется. Члены продолжают наследоваться, только к ним нет прямого досткпа. В качестве илюстрации приведу пример. Создаём 3 класса a, b и с. b наследуется от a, c - от b. В классе a определяем метод GetClassName, который будет возвращать строку "Класс а", в классе b затеняем этот метод, теперь он возвращает строку "Класс b". Один нюанс в классе а метод помечаем как public, а в классе b как private. И во всех трёх классах определяем свойство ClassName которое будет вызывать функцию и возвращать её значение.
далее создаём экземпляры классов и смотрим, что возвратит свойство у каждого из них (особенно интересен класс с)
дальше значение переменной s выводим для просмотра
Таким образом не смотря на то, что в классе b мы затенили метод GetClassName private - методом с той же сигнатурой, в производном классе с тем не менее спокойно вызывается метод который ранее был затенён. Просто теперь, когда затеняющий метод не виден, мы снова получили доступ к затенённому методу. -------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
||||||||
|
|||||||||
QryStaL |
|
|||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
Про наследование спору нет. Имелся в виду вызов соответствующего метода при приведении типов и полиморфном вызове. -------------------- I don't need a reason being who I am... |
|||
|
||||
diadiavova |
|
|||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Я и не пытался спорить, просто определение звучит несколько двусмысленно, поэтому я просто пояснил. -------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
|||
|
||||
QryStaL |
|
|||
![]() Intellectual feast ![]() ![]() Профиль Группа: Участник Сообщений: 914 Регистрация: 30.11.2005 Репутация: 14 Всего: 32 |
Ок. =) Вроде выяснили, теперь слово за автором темы... -------------------- I don't need a reason being who I am... |
|||
|
||||
diadiavova |
|
|||
![]() Доктор Зло(диагност, настоящий, с лицензией и полномочиями) ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5821 Регистрация: 14.8.2008 Где: В Коньфпольте Репутация: 31 Всего: 142 |
Да я чойта подзреваю, что вопросы ещё будут. Тема мутная.
![]() -------------------- Хочешь получить мудрый совет - читай подписи участников форумов. Злой доктор Щасзаболит ![]() |
|||
|
||||
Dims |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 0 Всего: 11 |
Ну это получается какое-то шаманское объяснение. Причины и следствия какие-то отвлечённые от жизни. Вот я уже давным давно программирую на Джаве и ни разу не пожалел, что там все функции виртуальные. Наоборот, это позволяет избежать потенциальных конфликтов, поскольку к объекту данного класса всегда будет вызывать его метод, написанный именно для него, независимо от того, к какому типу приведён объект. Добавлено через 5 минут и 34 секунды
Ну тут не вопрос, они, конечно, молодцы, что сделали ключевое слово override. Вопрос в том, зачем может понадобиться затенение? Чего оно такого может, чего не может обычное введение новой функции? Добавлено через 11 минут и 34 секунды
А зачем? Допустим, у нас все функции виртуальные. Никакой цепочки же нет. В каждом классе есть своя функция, либо он использует функцию базового класса. Цепочка возникает тогда, когда в методе наследника вызывается перекрытый метод предка. Ну тут уж программист явно написал, значит, хотел. Я прекрасно помню, зачем это нужно было в Си++ -- чтобы экономить память. Для хранения виртуальной функции нужен, как вариант, указатель на неё. Это добавляет байты в структуру описания класса, так как каждый класс должен помнить свою версию функции. А невиртуальная функция определяется типом объекта, к которому она применяется. Так что её помнить не надо, она вставляется на этапе компилляции. |
||||
|
|||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |