Модераторы: 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   Вверх
diadiavova
Дата 27.10.2008, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


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


Эксперт
***


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

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



Цитата(diadiavova @  27.10.2008,  21:43 Найти цитируемый пост)
Если функция помещена в класс просто для того, чтобы её могли использовать будущие поколения - то не страшно.


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



Цитата(diadiavova @  27.10.2008,  21:43 Найти цитируемый пост)
Но если эта функция используется самим базовым классом, и влияет на его поведение, то её переопределение может привести к непредсказуемым последствиям.

Для этого есть слово final, которое запрещает переопределение функции. Если у нас такая функция, которая используется самим классом и вредно, чтобы она "знала правду" о классе, тогда мы делаем её final. Всё, теперь такого не случится. 

А в обратном случае это может даже помочь. Мы можем нарочно определить функцию, которая используется в базовом классе но в расчёте на возможное переопределение в наследниках. Тогда наследник сможет влиять на поведение вызывающей функцией базового класса.

А к каким последствиям, по-Вашему, может привести первый сценарий? Можете придумать пример?

Цитата(diadiavova @  27.10.2008,  21:43 Найти цитируемый пост)
Поскольку программист не всегда знает детали реализации базового класса, то учесть все последствия переопрделния он не может.


Мне кажется, это нелогично. Если человек не знает свойств базового класса, то зачем он взялся его переопределять? Пусть тогда напишет обёртку, а не наследника. 

Кроме того, если наследование чревато, то, значит, разработчик базового класса не позаботился о том, чтобы его класс можно было легко расширять.

Цитата(diadiavova @  27.10.2008,  21:43 Найти цитируемый пост)
Затенённый и затеняющий методы - два разных метода, имеющих одинаковую сигнатуру и находящихся в одной области видимости(в следствии чего один из них не виден).

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

По Си++, повторяю, мне кажется, что причина была в экономии памяти. Всё-таки Си -- это макроассемблер, а Си++ это Си с классами. То есть, Си++ это ассемблер с классами. При программировании на Си++ можно (и желательно) представлять, что происходит с байтами, сколько занимает класс, как он расположен в памяти и так далее. А виртуальные функции вносят сумятицу в "ассемблерность". Поэтому для Си++ они лишь опция. А почему они лишь опция для C#?

PM MAIL   Вверх
diadiavova
Дата 27.10.2008, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
В Джаве функции переопределяются не для будущих поколений, а для полиморфизма, то есть, чтобы можно было работать с объектом не зная точно его типа. Для любого объекта, независимо от того, что нам в данный момент известно о его типе будет вызываться именно его метод. Это же логично.

В дотнете это всё тоже есть и такой подход даже является главенствующим, однако дополнительные возможности , насколько я понимаю "жрать не просят".
Когда я писал обудущих поколениях я имел в виду функции, которые не вызываются базовым классом, а предоставлены для использования производными. Относительно final, в до-диезе есть слово sealed которое(как я понимаю) деделает то же самое. Но если мне надо создать метод, переопределение которого будет иметь неблагоприяятные последствия из-за того, что в базовом классе этот метод вызывается в расчёте на определённое поведение и вдруг в производном классе это поведение изменяется. Чтобы этого избежать я просто не даю такой возможности и не делаю метод виртуальным. Что в этом плохого?
Если в жабе тоже есть такая возможность, то это говорит только о том, что различия здесь в том, какими функции считаются по умолчанию: в жабе - виртуальными, в дотнете - нет. И там и тут это можно изменить. Только в дотнете ещё можно и создать такую же функцию.
Насчёт упаковывания класса - хорошая задумка, особенно если в нём пара сотен членов и все надо упаковать, а в дотнете вместо этого надо упаковать всего-лишь один метод, к тому же затенённый метод можно вызвать из затеняющего(это не проблема).
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
А в обратном случае это может даже помочь. Мы можем нарочно определить функцию, которая используется в базовом классе но в расчёте на возможное переопределение в наследниках. Тогда наследник сможет влиять на поведение вызывающей функцией базового класса.

Ну для этого и есть виртуальные методы, в дотнете они тоже так работают(учитывая происхождение дотнета  вряд ли стоит этому удивляться).
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
А к каким последствиям, по-Вашему, может привести первый сценарий? Можете придумать пример?

Ну например такая ситуация:
Внутренний метод, вызывающий переопределённую функцию расчитывает на то, что значение ею возвращённое будет лежать в пределах определённого диапазона значений. Другое не предусмотренно из соображений экономии ресурсов. Переопределённый вариант функции(в отличии от первоначального) может возвращать значение, к которому вызывающий метод просто не готов.
Естественно это вызовет сбой. Конечно пример не очень показательный, но по крайней мере ясно, что я имею в виду.
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
Мне кажется, это нелогично. Если человек не знает свойств базового класса, то зачем он взялся его переопределять?

А от куда он может знать свойства? Если функция помечена как виртуальная - он знает, что её можно переопределить. Если нет - знает, что нельзя. Тут по-моему как раз всё просто.
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
Кроме того, если наследование чревато, то, значит, разработчик базового класса не позаботился о том, чтобы его класс можно было легко расширять.

Да нет. Как раз таки он позаботился, определив какие члены класса можно переопределять, а какие нет.
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
Я это понимаю, всё-таки с Си++ знаком. Вопрос в том, нафига это нужно. Зачем нужен такой же метод, но делающий совершенно другое? По логике, метод должен быть спроектирован и назван так, чтобы было понятно его предназначение. Если у метода другое предназначение, то нужно его назвать по-другому. 

Я не сказал, что он будет делать совершенно другое. Чуть-чуть другое, или просто по-другому, или например делая тоже самое(скажем посредством вызова затеняемого метода), при этом ещё инициировать какое-нибудь событие, да и вообще мало ли что ещё может понадобиться. Иногда бывает надо закрыть метод просто из-за того, что его вызов может не вписаться в логику класса и просто надо его перекрыть, например методом с пустой реализацией. И потом, в таком случае, почему не вызывает вопросов возможность перегрузки методов? Зачем нужно два метода с одинаковыми именами? 
Вариантов может быть много, хотя затенением я не пользуюсь, возможно именно по этому не могу привести какой-то яркий пример, но если так рассуждать "зачем нужно то, да зачем нужно это", то так можно очень далеко зайти. К примеру: зачем нужны модификаторы области видимости, когда можно просто не использовать те которые трогат нельзя, а зачем их прятать? Вопрос звучит странно, но он из того же набора, если мне не нужно, чтобы метод переопределяли - я не даю такой возможности
Цитата(Dims @  27.10.2008,  22:38 Найти цитируемый пост)
Поэтому для Си++ они лишь опция. А почему они лишь опция для C#?

Что значит "лишь опция"? Почему по-умолчанию они должны быть виртуальными? Потомучто в жабе так? Учитывая тот факт, что дотнет (мягко говоря) взял много из жабы, то наверно там это доставляло какие-то неудобства, раз уж это изменено. 


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


Эксперт
***


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

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



Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Но если мне надо создать метод, переопределение которого будет иметь неблагоприяятные последствия из-за того, что в базовом классе этот метод вызывается в расчёте на определённое поведение и вдруг в производном классе это поведение изменяется. Чтобы этого избежать я просто не даю такой возможности и не делаю метод виртуальным. Что в этом плохого?


Я не знаю. Просто мне пока непонятно, зачем это может быть нужно и оно кажется нелогичным. 

Если брать двоих: потомка и предка, то, по логике, потомок всегда знает больше предка. Поэтому, бояться, что знающий больше что-то напортачит, нелогично. 

Кроме того, затенение само по себе чревато ошибками: если мы приведём наследника к типу предка, что совершенно допустимо и не должно приводить ни к каким плохим последствиям, и вызовем метод, то вызовется затенённый метод. То есть, метод предка отработает на материале наследника, что чревато гораздо более серьёзными глюками, так как предок в принципе не может ничего знать о наследнике.

Но даже если возможности просто не нужны, то они "просят жрать" в том смысле, что требуют ресурсов, а взамен ничего не дают. Например, требуют от меня набирать слово "virtual".

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

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



Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Насчёт упаковывания класса - хорошая задумка, особенно если в нём пара сотен членов и все надо упаковать

Я так понимаю, что современные генераторы делают это автоматически. Мы же говорим о ситуации, когда разработчик не знает поведения базового класса и боится, что переопределение какой-то функции приведёт к нежелательным последствиям. Это значит, скорее всего, что ему и не нужны все 100 членов (раз он неосведомлён о том, что они делают).



Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Внутренний метод, вызывающий переопределённую функцию расчитывает на то, что значение ею возвращённое будет лежать в пределах определённого диапазона значений. Другое не предусмотренно из соображений экономии ресурсов. Переопределённый вариант функции(в отличии от первоначального) может возвращать значение, к которому вызывающий метод просто не готов.

Всё же это абстрактная ситуация. Где конкретно такое может произойти? 

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

Например, функция "Рост" для "Животного" может возвращать значение от миллиметров до десятков метров. А та же функция для "Человека" примерно от метра до двух. 

Как может получиться так, что частный случай возвращает больший спектр значений, чем общий?

Если это происхожит, то это, наверное, не частный случай. В этом случае функцию просто, наверное, нужно назвать по-другому. 


Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
А от куда он может знать свойства? Если функция помечена как виртуальная - он знает, что её можно переопределить. Если нет - знает, что нельзя.

Ну это правильно, но если функция не помечена, как виртуальная, то её можно затенить. И зачем нужна эта возможность -- непонятно.


Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Я не сказал, что он будет делать совершенно другое.


Ну а как же тогда? По логике ООП наследник -- это некто более осведомлённый. Частный случай предка. Его методы -- они либо повторяют методы предка, либо делают что-то более частное, детальное, что на уровне предка сделать было нельзя. Такая эволюция методов логична. 

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
или например делая тоже самое(скажем посредством вызова затеняемого метода)

Ну а причём тут затенение? Виртуальная функция точно так же может вызвать перекрытый метод, разве нет? Для этого затенение не нужно.

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
И потом, в таком случае, почему не вызывает вопросов возможность перегрузки методов? Зачем нужно два метода с одинаковыми именами? 

С одинаковыми именами, но с разными сигнатурами. Как правило, такие методы должны делать одно и тоже с разными исходными данными.

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Вариантов может быть много, хотя затенением я не пользуюсь

А как же? Объявляете все функции виртуальными? 

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
но если так рассуждать "зачем нужно то, да зачем нужно это", то так можно очень далеко зайти

Ну я не знаю, куда можно зайти smile Я просто после Джавы и у меня возникают естественные вопросы. Джава намеренно очищена ото всех лишних вещей и, как показывает практика, это позволяет писать очень красиво-оопешно. 

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

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
К примеру: зачем нужны модификаторы области видимости

Это чё такое? public/private?

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
когда можно просто не использовать те которые трогат нельзя, а зачем их прятат

Минуточку, но это ведь как раз Вы говорите, что что плохого в затенении, если его можно просто не использовать. 

Повторюсь, что слово override мне нравится. Оно добавляет проверку (кстати, если они любители проверок, то нафига убрали throws? в джаве есть два типа Exception, одни из них обязательно описывать в сигнатуре метода при помощи слова throws; то есть, ты смотришь на метод и видишь, чего он выбрасывает)

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Вопрос звучит странно, но он из того же набора, если мне не нужно, чтобы метод переопределяли - я не даю такой возможности

Как Вы можете не дать затенять?

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Почему по-умолчанию они должны быть виртуальными?

Ну если это единственная полезная их форма, то разве это не основание?

Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Учитывая тот факт, что дотнет (мягко говоря) взял много из жабы, то наверно там это доставляло какие-то неудобства, раз уж это изменено.  

Ну так давайте выясним, какие. Разве это не интересно?
PM MAIL   Вверх
diadiavova
Дата 28.10.2008, 02:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Если брать двоих: потомка и предка, то, по логике, потомок всегда знает больше предка. Поэтому, бояться, что знающий больше что-то напортачит, нелогично. 

Потомок может и знает, только код этого потомка пишет программист, который знает не всё.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Кроме того, затенение само по себе чревато ошибками: если мы приведём наследника к типу предка, что совершенно допустимо и не должно приводить ни к каким плохим последствиям, и вызовем метод, то вызовется затенённый метод. То есть, метод предка отработает на материале наследника, что чревато гораздо более серьёзными глюками, так как предок в принципе не может ничего знать о наследнике.

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

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Но даже если возможности просто не нужны, то они "просят жрать" в том смысле, что требуют ресурсов, а взамен ничего не дают. Например, требуют от меня набирать слово "virtual".

Ну если не набирать это слово, тогда компилятору будет не понятно почему программист создал метод с существующим именем: по-ошибке или намеренно. Полиморфизм - это хорошо, а если я просто создаю метод для поддержки какой-то функциональности и мне не надо, чтобы его переопределяли. Ядолжен каждый раз об этом уведомлять словом final? По моему гораздо проще реализовать метод без учёта того, что он может быть переопределён. Я например виртуальные методы создаю как раз в тех случаях, когда именно на то и расчитываю, что потом можно будет переопределить их, но там продумывается логика и все возможные нюансы возможной(!) реализации в производном классе. Гораздо проще написать метод под конкретные задачи, да и ресурсов он меньше жрёт, потомучто не проверяет тех возможностей, которых не должно быть в случае, если всё пойдёт как я задумал. В виртуальном методе всё это надо учитывать.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
В том-то и дело, что в Джаве это нельзя изменить. Все функции всегда виртуальные. 

Тогда я не понял, что такое final.
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Я так понимаю, что современные генераторы делают это автоматически. Мы же говорим о ситуации, когда разработчик не знает поведения базового класса и боится, что переопределение какой-то функции приведёт к нежелательным последствиям. Это значит, скорее всего, что ему и не нужны все 100 членов (раз он неосведомлён о том, что они делают).

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

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Как может получиться так, что частный случай возвращает больший спектр значений, чем общий?

Если оба класса пишет один человек - такого быть не должно. Но это не всегда так.
Насчёт специфичности класса я не согласен. Потомок расширяет базовый класс(кстати в jscript.net для указания базового класса используется слово exteds). Если считать, что производный класс сужает возможности(как в примере с ростом) тогда самым богатым классом должен быть Object, а все остальные более специфичными, ну это же не так.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Если это происхожит, то это, наверное, не частный случай. В этом случае функцию просто, наверное, нужно назвать по-другому. 

Это точно не частный случай. А функцию можно назвать и по-другому, но можно и так же(если надо).
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну это правильно, но если функция не помечена, как виртуальная, то её можно затенить. И зачем нужна эта возможность -- непонятно.

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

То есть: возможность затенения нужна для того, чтобы при создании такого же метода в производном классе, поведение базового, завязанное на ней не менялось.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну а как же тогда? По логике ООП наследник -- это некто более осведомлённый. Частный случай предка. Его методы -- они либо повторяют методы предка, либо делают что-то более частное, детальное, что на уровне предка сделать было нельзя. Такая эволюция методов логична. 


Я бы сказал не что-то более частное, а скорее, что-то сходное по логике, но иногда совсем другое. Что-то, что может быть тем же, что и в базовом классе, только применительно к другому контексту.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну а причём тут затенение? Виртуальная функция точно так же может вызвать перекрытый метод, разве нет? Для этого затенение не нужно.

Может, только как  я уже сказал, базовый класс тоже будет её вызывать. А пример я привёл для того, чтобы показать, что метод не только не делает что-то другое, аможет вести себя так же  как виртуальный, даже вызывать затеняемый метод, другой вопрос, что его не будет вызывать базовый класс.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
С одинаковыми именами, но с разными сигнатурами. Как правило, такие методы должны делать одно и тоже с разными исходными данными.

Как правило - это тоже ни кчему не обязывает, а потом я не говорил, что затеняющий метод должен делать что-то другое, по-другому - да.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
А как же? Объявляете все функции виртуальными? 

Нет, только те, которые собираюсь переопределять. Вся фишка в том, что как правило в затенении нет необходимости, но если она возникает, то у меня есть возможность создать в производном классе функцию с нужной сигнатурой, не затрагивая болевых точек базового класса. И хорошо, что она есть.
Я понимаю, что без этого, наверно можно обойтись, но это удобно. Если переопределение функции опасно - я лишён такой возможности. Разве это плохо? Сколько косяков можно напороть просто из-за незнания всех возможных опасностей. В современных языках в основном приходится работать с огромным количеством библиотечных классов, знать все нюансы поведения которых, просто невозможно. И если там есть ограничения, то это приводит просто к тому, что я не могу сделать некоторых вредных штук.
Взять например зоопарк. Звери сидят в клетках, чтоб никого не растерзали, но на расстоянии от клетки стоит ограда для людей, чтобы они не подходили близко. Ограничение свободы? Да. Хорошо это или плохо в данном случае?

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну я не знаю, куда можно зайти smile Я просто после Джавы и у меня возникают естественные вопросы. Джава намеренно очищена ото всех лишних вещей и, как показывает практика, это позволяет писать очень красиво-оопешно. 

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

Ну может от этого она не очищена, просто там до этогоне додумались? smile 
А если учесть, что у дотнета ноги из жабы растут...
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Это чё такое? public/private?

Угу
===========
Насчёт trows я не понял, но в дотнетовских языках это тоже есть, не знаю, может в жабе есть варианты...

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Как Вы можете не дать затенять?

А зачем? Не давать переопределять нужно для того, чтобы вызовы базового класса не получали подмену, а зачем не давать затенять? Затенение - другой метод. Пусть создают сколько влезет методов(или других членов) с такими же сигнатурами, на поведение, определённое в базовом классе это не повлияет. Запрещать затенение - это всё равно, что запрещать создавать члены с определёнными именами. Это ничего не даст. А вот запрет на изменение логики на какю-то неожиданную, может оказаться полезным.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Почему по-умолчанию они должны быть виртуальными?

Ну если это единственная полезная их форма, то разве это не основание?

Эта форма не единственная полезная, и кроме того - потенциально опасная.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну так давайте выясним, какие. Разве это не интересно? 

Да в общем-то этим и занимаемся уже несколько дней. smile

Добавлено через 10 минут и 18 секунд
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Если брать двоих: потомка и предка, то, по логике, потомок всегда знает больше предка. Поэтому, бояться, что знающий больше что-то напортачит, нелогично. 

Потомок может и знает, только код этого потомка пишет программист, который знает не всё.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Кроме того, затенение само по себе чревато ошибками: если мы приведём наследника к типу предка, что совершенно допустимо и не должно приводить ни к каким плохим последствиям, и вызовем метод, то вызовется затенённый метод. То есть, метод предка отработает на материале наследника, что чревато гораздо более серьёзными глюками, так как предок в принципе не может ничего знать о наследнике.

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

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Но даже если возможности просто не нужны, то они "просят жрать" в том смысле, что требуют ресурсов, а взамен ничего не дают. Например, требуют от меня набирать слово "virtual".

Ну если не набирать это слово, тогда компилятору будет не понятно почему программист создал метод с существующим именем: по-ошибке или намеренно. Полиморфизм - это хорошо, а если я просто создаю метод для поддержки какой-то функциональности и мне не надо, чтобы его переопределяли. Ядолжен каждый раз об этом уведомлять словом final? По моему гораздо проще реализовать метод без учёта того, что он может быть переопределён. Я например виртуальные методы создаю как раз в тех случаях, когда именно на то и расчитываю, что потом можно будет переопределить их, но там продумывается логика и все возможные нюансы возможной(!) реализации в производном классе. Гораздо проще написать метод под конкретные задачи, да и ресурсов он меньше жрёт, потомучто не проверяет тех возможностей, которых не должно быть в случае, если всё пойдёт как я задумал. В виртуальном методе всё это надо учитывать.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
В том-то и дело, что в Джаве это нельзя изменить. Все функции всегда виртуальные. 

Тогда я не понял, что такое final.
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Я так понимаю, что современные генераторы делают это автоматически. Мы же говорим о ситуации, когда разработчик не знает поведения базового класса и боится, что переопределение какой-то функции приведёт к нежелательным последствиям. Это значит, скорее всего, что ему и не нужны все 100 членов (раз он неосведомлён о том, что они делают).

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

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Как может получиться так, что частный случай возвращает больший спектр значений, чем общий?

Если оба класса пишет один человек - такого быть не должно. Но это не всегда так.
Насчёт специфичности класса я не согласен. Потомок расширяет базовый класс(кстати в jscript.net для указания базового класса используется слово exteds). Если считать, что производный класс сужает возможности(как в примере с ростом) тогда самым богатым классом должен быть Object, а все остальные более специфичными, ну это же не так.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Если это происхожит, то это, наверное, не частный случай. В этом случае функцию просто, наверное, нужно назвать по-другому. 

Это точно не частный случай. А функцию можно назвать и по-другому, но можно и так же(если надо).
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну это правильно, но если функция не помечена, как виртуальная, то её можно затенить. И зачем нужна эта возможность -- непонятно.

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

То есть: возможность затенения нужна для того, чтобы при создании такого же метода в производном классе, поведение базового, завязанное на ней не менялось.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну а как же тогда? По логике ООП наследник -- это некто более осведомлённый. Частный случай предка. Его методы -- они либо повторяют методы предка, либо делают что-то более частное, детальное, что на уровне предка сделать было нельзя. Такая эволюция методов логична. 


Я бы сказал не что-то более частное, а скорее, что-то сходное по логике, но иногда совсем другое. Что-то, что может быть тем же, что и в базовом классе, только применительно к другому контексту.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну а причём тут затенение? Виртуальная функция точно так же может вызвать перекрытый метод, разве нет? Для этого затенение не нужно.

Может, только как  я уже сказал, базовый класс тоже будет её вызывать. А пример я привёл для того, чтобы показать, что метод не только не делает что-то другое, аможет вести себя так же  как виртуальный, даже вызывать затеняемый метод, другой вопрос, что его не будет вызывать базовый класс.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
С одинаковыми именами, но с разными сигнатурами. Как правило, такие методы должны делать одно и тоже с разными исходными данными.

Как правило - это тоже ни кчему не обязывает, а потом я не говорил, что затеняющий метод должен делать что-то другое, по-другому - да.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
А как же? Объявляете все функции виртуальными? 

Нет, только те, которые собираюсь переопределять. Вся фишка в том, что как правило в затенении нет необходимости, но если она возникает, то у меня есть возможность создать в производном классе функцию с нужной сигнатурой, не затрагивая болевых точек базового класса. И хорошо, что она есть.
Я понимаю, что без этого, наверно можно обойтись, но это удобно. Если переопределение функции опасно - я лишён такой возможности. Разве это плохо? Сколько косяков можно напороть просто из-за незнания всех возможных опасностей. В современных языках в основном приходится работать с огромным количеством библиотечных классов, знать все нюансы поведения которых, просто невозможно. И если там есть ограничения, то это приводит просто к тому, что я не могу сделать некоторых вредных штук.
Взять например зоопарк. Звери сидят в клетках, чтоб никого не растерзали, но на расстоянии от клетки стоит ограда для людей, чтобы они не подходили близко. Ограничение свободы? Да. Хорошо это или плохо в данном случае?

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну я не знаю, куда можно зайти smile Я просто после Джавы и у меня возникают естественные вопросы. Джава намеренно очищена ото всех лишних вещей и, как показывает практика, это позволяет писать очень красиво-оопешно. 

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

Ну может от этого она не очищена, просто там до этогоне додумались? smile 
А если учесть, что у дотнета ноги из жабы растут...
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Это чё такое? public/private?

Угу
===========
Насчёт trows я не понял, но в дотнетовских языках это тоже есть, не знаю, может в жабе есть варианты...

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Как Вы можете не дать затенять?

А зачем? Не давать переопределять нужно для того, чтобы вызовы базового класса не получали подмену, а зачем не давать затенять? Затенение - другой метод. Пусть создают сколько влезет методов(или других членов) с такими же сигнатурами, на поведение, определённое в базовом классе это не повлияет. Запрещать затенение - это всё равно, что запрещать создавать члены с определёнными именами. Это ничего не даст. А вот запрет на изменение логики на какю-то неожиданную, может оказаться полезным.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Цитата(diadiavova @  27.10.2008,  23:39 Найти цитируемый пост)
Почему по-умолчанию они должны быть виртуальными?

Ну если это единственная полезная их форма, то разве это не основание?

Эта форма не единственная полезная, и кроме того - потенциально опасная.


Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Ну так давайте выясним, какие. Разве это не интересно? 

Да в общем-то этим и занимаемся уже несколько дней. smile 


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


Эксперт
***


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

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



Dims
Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Я не знаю. Просто мне пока непонятно, зачем это может быть нужно и оно кажется нелогичным. 

Если брать двоих: потомка и предка, то, по логике, потомок всегда знает больше предка. Поэтому, бояться, что знающий больше что-то напортачит, нелогично....

По логике потомок не знает больше предка, скорее к ним применимо "потомок есть предок". Человек, пишущий класс-предок, знает его public/protected интерфейс и внутреннюю реализацию. Человек, пишущий класс-потомок, знает о предке только public/protected интерфейс и ничего не знает о реализации. И, соответственно, не должен никак на эту реализацию влиять, если это явно не разрешил автор предка. Значения по умолчанию направлены на уменьшение интерфейса класса/сборки - private/internal вместо public, невиртуальные вместо virtual. Вообще, с точки зрения ООД наследование настолько увеличивает связность и тянет за собой столько ошибок, что надо классы по умолчанию sealed объявлять.

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Кроме того, затенение само по себе чревато ошибками: если мы приведём наследника к типу предка, что совершенно допустимо и не должно приводить ни к каким плохим последствиям, и вызовем метод, то вызовется затенённый метод. То есть, метод предка отработает на материале наследника, что чревато гораздо более серьёзными глюками, так как предок в принципе не может ничего знать о наследнике.

Вот именно поэтому и выводится warning, и требуется необязательное слово new. Просто надо воспринимать warnings as errors smile

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
Но даже если возможности просто не нужны, то они "просят жрать" в том смысле, что требуют ресурсов, а взамен ничего не дают. Например, требуют от меня набирать слово "virtual".

Набирая слово virtual, ты явно увеличиваешь площадь интерфейса. Во время набора нужно подумать что будет, если потомок реализует этот метод по-своему. Учесть что у автора потомка не будет знаний о внутреннем устройстве твоего класса. Учесть что через год какой-нибудь нуб придет и переопределит этот метод через 4 класса в цепочке наследования, при этом все 4 будут написаны тобой и будут завязаны на внутренее устройство родителя. Возможные проблемы гораздо круче чем проблемы при игнорировании варнинга "нужен new". Поэтому и слово длиннее на 4 буквы, чтобы больше времени было smile

Цитата(Dims @  28.10.2008,  00:34 Найти цитируемый пост)
нафига убрали throws

Затем, что классы-потомки могут бросать исключения, не описанные в синатуре предков. И еще затем, чтобы уменьшить связность и проблемы с версиями. В .net можно подменить, например, сборку с базовым классом даже если сборка потомка явно привязана к ее версии. И в момент выполнения список throws оказался бы совсем не таким, как в момент компиляции. В java фишек с версиями нет, там throws проверяется только в compile time.

Это сообщение отредактировал(а) PashaPash - 28.10.2008, 10:46


--------------------
PM MAIL WWW   Вверх
Dims
Дата 28.10.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(diadiavova @  28.10.2008,  02:20 Найти цитируемый пост)
Ну может от этого она не очищена, просто там до этогоне додумались? smile 

Это было в Си++, потом это убрали в Джаве, а потом обратно вернули в C#.

Джава произошла от Си++, а C# от них обоих. 

Цитата(diadiavova @  28.10.2008,  02:20 Найти цитируемый пост)
А зачем? Не давать переопределять нужно для того, чтобы вызовы базового класса не получали подмену, а зачем не давать затенять?

Я не знаю. Я не знаю ни зачем не давать затенять, ни зачем давать. В Си++ я понимаю, зачем сделано затенение, а зачем в C# не понимаю.

Добавлено через 8 минут и 30 секунд
Цитата(PashaPash @  28.10.2008,  10:44 Найти цитируемый пост)
Человек, пишущий класс-потомок, знает о предке только public/protected интерфейс и ничего не знает о реализации.

Правильно. Но если ему в инструкции сказано, что переопределив такой-то метод он добьётся такого-то результата, то он кое-что знает и о реализации. 

Цитата(PashaPash @  28.10.2008,  10:44 Найти цитируемый пост)
Затем, что классы-потомки могут бросать исключения, не описанные в синатуре предков.

Ну давайте тогда уберём спецификацию возвращаемого типа, чтобы потомки могли и возвращать объекты другого типа. 

Ну ладно, это отклонение.

В этой теме давайте разберёмся, зачем нужно затенение.


PM MAIL   Вверх
PashaPash
Дата 28.10.2008, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  28.10.2008,  11:48 Найти цитируемый пост)
Правильно. Но если ему в инструкции сказано, что переопределив такой-то метод он добьётся такого-то результата, то он кое-что знает и о реализации. 

Основной принцип ооп - о классе известен только его внешний интерфейс. Если в интрукции сказано что переопределение метода как-то повлияет на результат, то это значит все то же - что метод - часть public интерфейса класса. И никак не значит, что наследник что-то узнает о реализации. Если для наследования нужно нарушить инкапсуляцию, то это какое-то не ооп-ное наследование. На самом деле вопрос примерно на уровне:
А почему методы не public по умолчанию? в языке xxx все методы pubic, очень удобно. Ну и что, что программер может не знать зачем они нужны. Никто ж не заставляет его их вызвать, да и автору базового класса легче - не надо писать дурацкие public. Да, в .net/java есть возможность сделать метод public, но зачем нужны private методы, это ж неудобно.

Цитата(Dims @  28.10.2008,  11:48 Найти цитируемый пост)
Ну давайте тогда уберём спецификацию возвращаемого типа, чтобы потомки могли и возвращать объекты другого типа. 

в jave бросаемые исключения - часть интерфейса, т.е. подразумевается что они могут возникать при обычном ходе выполнения программы. В .net исключения - это именно исключительные ситуации, и они не являются частью интерфейса. На самом деле код очень редко может нормально обработать исключение, и принудительное перечисление типов приведет к желанию программеров тупо исключения глушить. И код очень редко знает полный список исключений, которые может бросить вызываемый им кусок. Кроме кода на границе слоев, ес-но

Цитата(Dims @  28.10.2008,  11:48 Найти цитируемый пост)
Это было в Си++, потом это убрали в Джаве, а потом обратно вернули в C#.
Джава произошла от Си++, а C# от них обоих. 

С таким же успехом можно утверждать что C# произошел от Eiffel или от Modula. C#/.NET - не наследник java, это самостоятельная платформа. Ничего в нем не "убирали" и не "добавляли". В нем все так и было с самого начала. И вопросы с позиции "почему тут не так, как в java" имеют общий ответ: потому что это не java, не java от MS, и не наследник Java. И потому что в java тоже есть просчеты с точки зрения дизайна платформы - хотя бы дурацкое выделение элементарных типов, обязательное перечисление исключений, проблемы с версионностью, вирутальные по умолчанию... C# не обязан копировать из java ее проблемы.


--------------------
PM MAIL WWW   Вверх
diadiavova
Дата 28.10.2008, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  28.10.2008,  11:48 Найти цитируемый пост)
Правильно. Но если ему в инструкции сказано, что переопределив такой-то метод он добьётся такого-то результата, то он кое-что знает и о реализации. 

А зачем такие сложности, когда можно просто запретить и всё(как в зоопарке)

Цитата(Dims @  28.10.2008,  11:48 Найти цитируемый пост)
В этой теме давайте разберёмся, зачем нужно затенение.

Проблема именно в том, что в этой теме мы смешали в кучу несколько близких тем. Это вносит некоторый сумбур.
1.Почему не все методы виртуальные?
Насколько я понял в жабе либо все методы виртуальны, либо класс вообще не наследуется. В дотнете, в противовес этому, механизм наследования можно настроить тонко. То есть при написании класса автор сам определяет что можно переопределить, а что надо оставить без изменений. На мой взгляд - дотнетовский подход более гибкий, чем "всё или ничего".

2. Зачем нужно затенение?
В общем то это следует из первого вопроса. Если возникает ситуация, в которой необходима собственная реализация метода, а он не виртуальный, то существует возможность это реализовать не затрагивая функций базового класса, завязанных на реализации данного метода в базовом классе.

3. Почему методы не виртуальны по-умолчанию?
Реализация функциональности завязанная на виртуальных методах требует учёта того, что они могут быть переопределены. Реализовать функциональность под конкретные задачи - проще и экономичнее, чем проверять все возможные(и невозможные) последствия переопределения.

ЗЫ

PashaPash, нам скоро с гастролями можно будет выступать.
Как Терренс и Филипп. smile 


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


Эксперт
***


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

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



Цитата(PashaPash @  28.10.2008,  13:48 Найти цитируемый пост)
Основной принцип ооп - о классе известен только его внешний интерфейс.

А что значит "известен" внешний интерфейс? Ведь это же не означает просто, что известны имена методов и типы их параметров. Это означает, что известно, и что эти методы ДЕЛАЮТ. Например, метод "длина" класса "вектор" вычисляет длину вектора. 

Цитата(PashaPash @  28.10.2008,  13:48 Найти цитируемый пост)
На самом деле вопрос примерно на уровне:

Нет, вопрос совсем на другом уровне.

Цитата(PashaPash @  28.10.2008,  13:48 Найти цитируемый пост)
Ничего в нем не "убирали" и не "добавляли". В нем все так и было с самого начала. И вопросы с позиции "почему тут не так, как в java" имеют общий ответ: потому что это не java, не java от MS, и не наследник Java

То есть, Вы утверждаете, что разработчики C# не продумывали свойства языка, а просто сделали не так как в Java?

Цитата(PashaPash @  28.10.2008,  13:48 Найти цитируемый пост)
хотя бы дурацкое выделение элементарных типов, обязательное перечисление исключений, проблемы с версионностью, вирутальные по умолчанию

Однако, эти вещи были специально созданы разработчиками, имея в виду какие-то мысли. Может быть, мысли и ошибочные, но они были. А в Вашем описании C# это вещь в себе, которая не произошла ни от кого и функции которой просто есть, нипочему.

Я совершенно с этим не согласен. Я думаю, что и тут были какие-то мысли, просто мы их не знаем. Почему просто в этом не признаться?

Добавлено через 51 секунду
Цитата(diadiavova @  28.10.2008,  14:13 Найти цитируемый пост)
А зачем такие сложности, когда можно просто запретить и всё(как в зоопарке)

Мы разбираем не вопрос как запретить, а вопрос как разрешить. И зачем.

Добавлено через 4 минуты и 49 секунд
На самом деле, я понял, что такое затенение функций -- это отколовшаяся часть системы преобразования типов.

Возможны как минимум два преобразования типов от типа наследника к типу предка. При первом преобразовании отражается ситуация, когда программисту просто неважен конкретный тип наследника. В этом случае он хочет работать с наследником, думая о предке, но при этом чтобы ничего не нарушалось. 

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

Во втором случае программист может хотеть принудительно превратить наследника в предка, обрубить ему все особенности. 

В этом случае методы должны браться от предка.
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)
Мы разбираем не вопрос как запретить, а вопрос как разрешить. И зачем.

Честно говоря: не понимаю, как одно можно рассматривать вне контекста другого. Я говорил всего лишь о том, что ппроще запретить переопределение конкретных членов, чем описывать в документации какие члены переопределять не следует.

Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)
Возможны как минимум два преобразования типов от типа наследника к типу предка. При первом преобразовании отражается ситуация, когда программисту просто неважен конкретный тип наследника. В этом случае он хочет работать с наследником, думая о предке, но при этом чтобы ничего не нарушалось. 

Конкретный тип не важен тогда, когда в базовом классе либо вообще отсутствуют виртуальные члены, либо те, что есть не переопределены в производном. В этом случае при преобразовании к базовому типу объект ведёт себя так как будто это экземпляр базового типа без каких-либо изменений.
Здесь же мы имеем дело с ситуацией, когда переопределёнными могут быть некоторые члены, а остальные - нет. Поведение такого объекта будет отличаться от экземпляров других классов, так же произведённых от данного, в силу того, что в нём таки будут присутствовать виртуальные члены.



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


Эксперт
***


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

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



Цитата(diadiavova @  3.11.2008,  12:52 Найти цитируемый пост)
Честно говоря: не понимаю, как одно можно рассматривать вне контекста другого. Я говорил всего лишь о том, что ппроще запретить переопределение конкретных членов, чем описывать в документации какие члены переопределять не следует.


Ну Вы же сами предложили рассмотреть случай -- а вдруг человек переопределит метод и это приведёт к ужасным последствиям. И я полностью с Вами согласен: проще запретить. Это можно сделать и в Джаве при помощи final.

А вот когда это не запрещено, как я понимаю, по Вашей теории, и могут быть проблемы. 

Вопрос: какие?

Цитата(diadiavova @  3.11.2008,  12:52 Найти цитируемый пост)
Здесь же мы имеем дело с ситуацией, когда переопределёнными могут быть некоторые члены, а остальные - нет. Поведение такого объекта будет отличаться от экземпляров других классов, так же произведённых от данного, в силу того, что в нём таки будут присутствовать виртуальные члены.

Хочу подчеркнуть, что тут я рассматриваю ситуацию гипотетического языка. Я слышал, что в новом Си++ ввели несколько разновидностей преобразования типов, но ещё не разбирался с ними и не уверен, что это то.

Так вот, в этом гипотетическом языке все функции виртуальные, как и в Джаве. А вопрос, какую из них использовать, решается в зависимости от формы преобразования типа.

По моим представлениям, после того, как над объектом было проведено "преобразовние к предку первого рода", он не перестал быть потомком. Поэтому, все функции по отношению к нему будут браться от потомка, если они там переопределены.

Если к объекту применено преобразование типа "второго рода", то он полностью превращён в предка, а лишняя информация, включая переопределённые функции, стирается. 
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  3.11.2008,  13:16 Найти цитируемый пост)
Это можно сделать и в Джаве при помощи final.

Просто тут есть выбор: запрещать всё или только часть. В дотнетовских языках тоже есть возможность запретить дальнейшее наследование класса. Кроме того, здесь есть возможность указать, что в дальнейшем виртуальный член перестаёт быть виртуальным(то есть больше не переопределяется в производных классах). Здесь есть возможность затенения виртуальных членов(выбор между переопределением и затенением). То есть здесь можно всё то же, что и в яве, плюс дополнительные возможности.

Цитата(Dims @  3.11.2008,  13:16 Найти цитируемый пост)
А вот когда это не запрещено, как я понимаю, по Вашей теории, и могут быть проблемы. 

Вопрос: какие?

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

Цитата(Dims @  3.11.2008,  13:16 Найти цитируемый пост)
Хочу подчеркнуть, что тут я рассматриваю ситуацию гипотетического языка. Я слышал, что в новом Си++ ввели несколько разновидностей преобразования типов, но ещё не разбирался с ними и не уверен, что это то.

Так вот, в этом гипотетическом языке все функции виртуальные, как и в Джаве. А вопрос, какую из них использовать, решается в зависимости от формы преобразования типа.

По моим представлениям, после того, как над объектом было проведено "преобразовние к предку первого рода", он не перестал быть потомком. Поэтому, все функции по отношению к нему будут браться от потомка, если они там переопределены.

Если к объекту применено преобразование типа "второго рода", то он полностью превращён в предка, а лишняя информация, включая переопределённые функции, стирается.  


Трудно рассуждать о гипотетическом языке, но в такую модель изначально заложены грабли. Вместо тонкой настройки поведения конкретного класса (в том числе в случае приведения типов), использовать общие правила для всех типов, которые в конкретном случае нельзя изменить...
Не думаю, что это наилучшее решение.
При желании поведение класса при приведении типов и так можно задать. Не вижу смысла в ограничении этой возможности.

Добавлено через 8 минут и 22 секунды
И потом: что значит стирается информация о переопределённых членах? Члены просто перестают быть виртуальными?


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


Эксперт
***


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

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



Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)
А что значит "известен" внешний интерфейс? Ведь это же не означает просто, что известны имена методов и типы их параметров. Это означает, что известно, и что эти методы ДЕЛАЮТ. Например, метод "длина" класса "вектор" вычисляет длину вектора. 

ЧТО делает не означает КАК делает. Если метод длина использует внутри метод "нарисовать" и "подсчитать клетки в нарисованном векторе" (для примера), то эти методы не должны быть видны извне. Подход "явно указать что видно извне" просто безопаснее с точки зрения архитектуры чем, "все сделать видимым извне, а потом закрывать доступ". Потому что урезать интерфейс после публикации довольно сложно - всегда есть шанс что на него кто-то уже привязался.
Скажем так - в java не было выбора virtual/not virtual. В C# есть выбор, и по умолчанию он сделан в сторону решения, несущего меньше потенциальных последствий. Никто тебя ни к чему не заставляет и не принуждает smile

Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)
То есть, Вы утверждаете, что разработчики C# не продумывали свойства языка, а просто сделали не так как в Java?

Не так - не всмысле "специально сделали через ж, чтобы от java отличаться". Не так - значит продумали, рассмотрели решения в 3-4х OO-языках и выбрали лучшее. Поэтому не стоит удивляться что что-то "не так".
Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)

Однако, эти вещи были специально созданы разработчиками, имея в виду какие-то мысли. Может быть, мысли и ошибочные, но они были. А в Вашем описании C# это вещь в себе, которая не произошла ни от кого и функции которой просто есть, нипочему.

Я совершенно с этим не согласен. Я думаю, что и тут были какие-то мысли, просто мы их не знаем. Почему просто в этом не признаться?

Просто C#/.NET вышел позже чем Java, и его создатели попытались решить некоторые проблемы OOP, о которых до появления Java никто не задумывался. Но это не значит что C# - это Java от MS. C# намного ближе к C++.

Цитата(Dims @  3.11.2008,  12:28 Найти цитируемый пост)
На самом деле, я понял, что такое затенение функций -- это отколовшаяся часть системы преобразования типов.

Проблема в том, что ты все еще считаешь что все функции должны быть виртуальными. Подходи с классической позиции с учетом минимализма интерфейса. Полиморфизм позднего связывания - только один из 2-х видов полиморфизма в OOP, но почем-то единственный в Java. Но на java свет клином не сошелся. smile


--------------------
PM MAIL WWW   Вверх
Dims
Дата 3.11.2008, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Если метод длина использует внутри метод "нарисовать" и "подсчитать клетки в нарисованном векторе" (для примера), то эти методы не должны быть видны извне.

Если они не видны извне, то их и нельзя переопределить. Мы же рассматриваем случай, когда метод А виден извне, используется одним из других методов Б и был переопределён в наследнике.

Утверждается, что это плохая ситуация, так как программист наследника не должен знать, что метод Б использует А. 

Я с этим не согласен. Если разработчик предка использовал метод А в методе Б и оставил метод А открытым, то он должен был написать в инструкции, что роль метода А сводится не только к тому, что он делает нечто, но она состоит ещё и в том, что он используется методом Б. Тогда программист наследника, прочтя инструкцию, узнает об этом и будет переопределять А с умом.

Если же это нежелательно, то метод А можно сделать оконечным и тогда никто его не сможет переопределить.

Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Скажем так - в java не было выбора virtual/not virtual

Зато он был в Си++, опыт которого использовали при создании Джава. То есть, в Джаве специально убрали этот выбор. Намеренно. 

Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Не так - значит продумали, рассмотрели решения в 3-4х OO-языках и выбрали лучшее.

Ну так это я и имел в виду, под "убрали" или "добавили". Учёт опыта. 

Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Но это не значит что C# - это Java от MS.

Не переводите вопрос в плоскость религиозных войн. Вы с одной стороны признаёте, что при создании Си-диез учитывался опыт Джавы, а с другой стороны пытаетесь принизить роль этого факта, говоря, что Си-диез это не Джава от МС.

Главные фишки Джавы -- это виртуальная машина, ссылочные типы и сборщик мусора. Всё это есть и в .НЕТ. Причём исторически тоже, сперва Микрософт лицензировало Джаву, сделала свой JIT, затем отказалась от неё, сделала J++ и потом придумало свою платформу NET и C#. Влияние, на мой взгляд, самое, что ни на есть прямое. Ну примерно как в СССР при создании ЕС использовали IBM 360. Учитывая производственные мощности Микрософта и их наработки, просто неизбежно должно было произойти какое-то столкновение видений и была должна получиться своя масштабная и полноценная платформа.

Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Проблема в том, что ты все еще считаешь что все функции должны быть виртуальными.

Это не проблема, а моё мнение. ;)

Цитата(PashaPash @  3.11.2008,  13:45 Найти цитируемый пост)
Полиморфизм позднего связывания - только один из 2-х видов полиморфизма в OOP, но почем-то единственный в Java.

На мой взгляд, связывание имеет отношение не к ООП, а к реализации. В моём гипотетическом языке компиллятор осуществлял бы раннее связываение при одном преобразовании типов и позднее -- при другом.
PM MAIL   Вверх
PashaPash
Дата 3.11.2008, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  3.11.2008,  14:30 Найти цитируемый пост)
Если они не видны извне, то их и нельзя переопределить. Мы же рассматриваем случай, когда метод А виден извне, используется одним из других методов Б и был переопределён в наследнике.

Утверждается, что это плохая ситуация, так как программист наследника не должен знать, что метод Б использует А. 

Я с этим не согласен. Если разработчик предка использовал метод А в методе Б и оставил метод А открытым, то он должен был написать в инструкции, что роль метода А сводится не только к тому, что он делает нечто, но она состоит ещё и в том, что он используется методом Б. Тогда программист наследника, прочтя инструкцию, узнает об этом и будет переопределять А с умом.

Если же это нежелательно, то метод А можно сделать оконечным и тогда никто его не сможет переопределить.

Проблема такого подхода - слишком много "может" на необходимых для успеха необходимых действиях. Это все на самом деле "может подумать о последствиях переопределения в наследнике, может написать документацию, может упомянуть в ней использование, может быть прочитает инструкцию, может быть будет думать при переопределении". Т.е. для нормального результата нужно много активных действий со стороны 2-х людей. В случае с невиртуальными по умолчанию "может" превращается в "должен". Должет обявить хотя бы protected, должен сделать виртуальной, должен прочитать warning при переопределении, должен написать new. Второй подход IMHO, безопаснее.
Цитата(Dims @  3.11.2008,  14:30 Найти цитируемый пост)
Не переводите вопрос в плоскость религиозных войн. Вы с одной стороны признаёте, что при создании Си-диез учитывался опыт Джавы, а с другой стороны пытаетесь принизить роль этого факта, говоря, что Си-диез это не Джава от МС.
Скажем, на обсуждаемый вопрос - особенности реализации наследования - больше влияния оказал C++ и COM, чем Java. 

Цитата(Dims @  3.11.2008,  14:30 Найти цитируемый пост)
На мой взгляд, связывание имеет отношение не к ООП, а к реализации. В моём гипотетическом языке компиллятор осуществлял бы раннее связываение при одном преобразовании типов и позднее -- при другом. 
А в реально существующем C# есть раннее связывание для невиртуальных методов, и позднее - для невиртуальных. И вроде никто (почти) не жалуется.


--------------------
PM MAIL WWW   Вверх
Dims
Дата 3.11.2008, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PashaPash @  3.11.2008,  16:08 Найти цитируемый пост)
В случае с невиртуальными по умолчанию "может" превращается в "должен". 

От того, что человек напишет слово virtual, он не станет должен написать инструкцию. Он всё равно может проигнорировать эту обязанность.

C# требует, чтобы человек явно РАЗРЕШИЛ переопределять функции. А Джава требует, чтобы человек явно ЗАПРЕТИЛ переопределять функции, если это опасно.

В обоих случаях человек может наплевать на написание инструкции, которая в обоих случаях необходима.

Цитата(PashaPash @  3.11.2008,  16:08 Найти цитируемый пост)
Второй подход IMHO, безопаснее.

Только при условии, что мы предполагаем, что сплошь и рядом встречаются случаи, когда
а) в предке используется метод
б) он переопределяется в наследнике
в) это нежелательно

Я считаю, что это маловероятно. По крайней мере, ситуацию, при которой это так, ещё никто не придумал. 

Зато гораздо более вероятна ситуация, когда функцию потребуется переопределить, но это будет запрещено, так как программист базового класса забыл написать virtual. Это защитило его от менее вероятной опасности, но так же и не дало возможность получить более вероятную выгоду.

Фактически, вот я пишу класс. Если я не объявил класс как sealed, значит, я предполагаю, что от класса будут производить наследников. И если при этом я не подписал все функции как virtual, то я исключил возможность нормального наследования от своего класса.

Иными словами, по умолчанию (то есть, без слов sealed и virtual) C# склоняет к созданию классов, непригодных к нормальному (с моей точки зрения) полиморфному наследованию. 

Отсюда следует, что разработчики C# считают, что наиболее частой является ситуация неполиморфного наследования, то есть, когда функции "затеняются".

Отсюда и вопрос: когда это может пригодиться? То есть, когда может пригодиться именно затенение, а не переопределение. Ответа на этот вопрос до сих пор нами не найдено.

Цитата(PashaPash @  3.11.2008,  16:08 Найти цитируемый пост)
А в реально существующем C# есть раннее связывание для невиртуальных методов, и позднее - для невиртуальных.

Здесь явная опечатка. Когда что?

Цитата(PashaPash @  3.11.2008,  16:08 Найти цитируемый пост)
И вроде никто (почти) не жалуется. 

Ну, люди терпят даже такие хаотические языки, как PHP и Perl smile

PM MAIL   Вверх
PashaPash
Дата 3.11.2008, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  3.11.2008,  16:44 Найти цитируемый пост)
Здесь явная опечатка. Когда что?

позднее - для виртуальных ес-но.

Цитата(Dims @  3.11.2008,  16:44 Найти цитируемый пост)
Только при условии, что мы предполагаем, что сплошь и рядом встречаются случаи, когда...

Я считаю, что это маловероятно. По крайней мере, ситуацию, при которой это так, ещё никто не придумал. 

Если ты не можешь увидеть такой ситуации, то значит ты пишешь код по принципу - "одна операция - один метод класса, который не вызывает остальные". 
Обычная ситуация. Есть метод А, он меняет внутренее состояние вызовом Б. Если методы виртуальные - значит ты готов поставить свою зарплату что кто-то другой всегда сможет корректно переопределить метод А и метод Б.

Цитата(Dims @  3.11.2008,  16:44 Найти цитируемый пост)
Фактически, вот я пишу класс. Если я не объявил класс как sealed, значит, я предполагаю, что от класса будут производить наследников. И если при этом я не подписал все функции как virtual, то я исключил возможность нормального наследования от своего класса.

Иными словами, по умолчанию (то есть, без слов sealed и virtual) C# склоняет к созданию классов, непригодных к нормальному (с моей точки зрения) полиморфному наследованию. 

Отсюда следует, что разработчики C# считают, что наиболее частой является ситуация неполиморфного наследования, то есть, когда функции "затеняются".

Фактически, это значит что C# склоняет разработчиков ПОДУМАТЬ, перед тем как сделать метод частью public interface. Точно так же, как модификатор доступа private по умолчанию. Т.е. перед тем как позволить кому-то переопределить часть функционала, разработчик обязан обдумать последствия. Подумать что переопределяющий не будет иметь о внутреннем строении твоего класса вообще никакой информации. Ты не видишь негативных последствий - значит код за тобой никогда не дописывали нубы. Я пытался объяснить, что минимизация интерфейса по умолчанию - есть хорошо. Просто рассматривай виртуальные функции с той же стороны, что и как public. Если ты разрешил вызвать функцию - то кто-то ее вызовет. Если ты разрешил ее переопределить - то кто-то ее переопределит, причем совершенно не так, как ты этого ожидал. 
Ты сейчас отстаиваешь точку зрения которая полностью аналогична "а давайте сделаем public методы по умолчанию". Просто до этого писал на языке, где по умолчанию publiс, и теперь private с твоей точки зрения - ненормальная вещь. Просто пойми, что protected virtual это более широкий досуп к классу, чем public.

А "неполиморфным наследованием" - возможностью затенения. Оно используется в исключительных случаях (читай - никогда).
Цитата(Dims @  3.11.2008,  16:44 Найти цитируемый пост)
Ну, люди терпят даже такие хаотические языки, как PHP и Perl smile

Некоторые сидят на JavaScript, с только public методами. И потом им private делает невозможной нормальную (с их точки зрения) работу с объектами smile


--------------------
PM MAIL WWW   Вверх
Dims
Дата 3.11.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Если ты не можешь увидеть такой ситуации,

Если ты можешь, то опиши её пжлст прямо здесь.

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Если методы виртуальные - значит ты готов поставить свою зарплату что кто-то другой всегда сможет корректно переопределить метод А и метод Б.

К чему этот пафос?

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Фактически, это значит что C# склоняет разработчиков ПОДУМАТЬ

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

Если я умалчиваю sealed и умалчиваю virtual -- что я получаю? Класс, в котором при наследоваии методы можно только затенять. То есть, это наиболее распространённая ситуация с точки зрения разработчиков. Ну так опиши же, наконец, для чего она может быть нужна?

Повторяю, это должна быть не какая-то ОДНА ИЗ ситуаций, а САМАЯ распространённая, так как она получается в результате умолчания.

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Точно так же, как модификатор доступа private по умолчанию. 

Вовсе не так же. private по умолчанию, потому что большую часть времени программист проводит в написании внутренней кухни класса. Поэтому private по умолчанию. Это разумно.

А зачем по умолчанию non-virtual? Кому нужны кучи классов, в которых нельзя переопределять методы?

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Просто рассматривай виртуальные функции с той же стороны, что и как public. Если ты разрешил вызвать функцию - то кто-то ее вызовет. Если ты разрешил ее переопределить - то кто-то ее переопределит, причем совершенно не так, как ты этого ожидал.

В таком случае виртуальные функции надо вообще запретить. Ведь так получается по твоей логике.

Я, конечно, не отрицаю, что в каких-то случаях злонамеренное или дурное переопределение функций может привести к нарушению работы. Но КАК ПРАВИЛО это не так. И ты это косвенно подтверждаешь тем, что не можешь привести примера, в котором переопределение виртуальной функции вредно.

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Ты сейчас отстаиваешь точку зрения которая полностью аналогична "а давайте сделаем public методы по умолчанию". 

Это тебе только так кажется.

Цитата(PashaPash @  3.11.2008,  17:15 Найти цитируемый пост)
Некоторые сидят на JavaScript, с только public методами. И потом им private делает невозможной нормальную (с их точки зрения) работу с объектами 

Ну вот я мог бы объяснить таким людям, зачем нужен private, потому что у меня есть практика их использования. А ты можешь ли объяснить мне, зачем нужно virtual/nonvirtual?
PM MAIL   Вверх
PashaPash
Дата 3.11.2008, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  3.11.2008,  19:03 Найти цитируемый пост)

К чему этот пафос?

Это не пафос, это суровая правда :(
Цитата(Dims @  3.11.2008,  19:03 Найти цитируемый пост)
Если я умалчиваю sealed и умалчиваю virtual -- что я получаю? Класс, в котором при наследоваии методы можно только затенять. То есть, это наиболее распространённая ситуация с точки зрения разработчиков. Ну так опиши же, наконец, для чего она может быть нужна?

Повторяю, это должна быть не какая-то ОДНА ИЗ ситуаций, а САМАЯ распространённая, так как она получается в результате умолчания.

Нет, ты получаешь класс в котором методы нельзя подменять без использования затенения. Это не значит что можно затенять методы без очень-очень веской причины. Пролистай стандартные классы .NET - в них очень неплохо продуман интерфейс и при этом - полно невиртуальных функций. Скажем, тот же BackgroundWorker - у него из виртуальных - только вызывающие события. Сравни его со своим воркером из соседнего топика. И сразу вылезет вот такой баг: 
Цитата(Dims @  27.10.2008,  22:25 Найти цитируемый пост)
По моим представлениям, наследник должен имплементить SpecificWork и (необязательно) Done. Внутри SpecificWork нужно проверять ShouldStop.get на предмет не пора ли завершиться.

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

Цитата(Dims @  3.11.2008,  19:03 Найти цитируемый пост)
В таком случае виртуальные функции надо вообще запретить. Ведь так получается по твоей логике.

Я, конечно, не отрицаю, что в каких-то случаях злонамеренное или дурное переопределение функций может привести к нарушению работы. Но КАК ПРАВИЛО это не так. И ты это косвенно подтверждаешь тем, что не можешь привести примера, в котором переопределение виртуальной функции вредно.

Не запретить, а сделать невиртуальными по умолчанию. А пример - да вот, прямо в твоем коде smile Ну или, навскидку, любой метод типа 
EnsureDataBound/EnsureChildControls который нужно вызывать из наследников, но ни в коем случае нельзя разрешить переопределить. Вообще, открой msdn, любой класс .net. Любая невиртуальная функция - пример. Если над ней подумать - то будут веские причины для ее невиртуальности.

Цитата(Dims @  3.11.2008,  19:03 Найти цитируемый пост)
Вовсе не так же. private по умолчанию, потому что большую часть времени программист проводит в написании внутренней кухни класса. Поэтому private по умолчанию. Это разумно.

Кухня класса - это не только private методы. Это еще и детали реализации для public/protected. Вопрос точно такой же - уменьшение связности и увеличение инкапсуляции. Для этих двух вещей и private и non-virtual - одно и то же.

Цитата(Dims @  3.11.2008,  19:03 Найти цитируемый пост)
Ну вот я мог бы объяснить таким людям, зачем нужен private, потому что у меня есть практика их использования. А ты можешь ли объяснить мне, зачем нужно virtual/nonvirtual? 

Ок, давай, попробуй объяснить мне, зачем нужен private. Делаем все public. Мои аргументы: Если что - всегда можно прочитать про конкретный метод в документации. Я писал на JavaScript, там все public, все счастливы. Пришел в вашу Java, тут все private по умолчанию. Приведи мне пример, когда public вреден. Что у вас вообще за OOP такое, если нельзя подменить любой кусок имплементации? Какое-то ненастоящее. И на все аргументы - типа инкапсуляция, кухня класса, связность, минимизация интерфейса, скрытие деталей реализации - я буду отвечать "а вот в JavaScript все public, и ничего, очень удобно, и инкапсуляция не нарушаешься. Если что - всегда можно в документации написать.".


--------------------
PM MAIL WWW   Вверх
diadiavova
Дата 3.11.2008, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

Разработчики явы учли опыт, имевшийся в С++, а разработчики дотнета учли и опыт явы тоже. Результат мы видим.

ЗЫ

И в javascript есть private члены.


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


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


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

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



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


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


Эксперт
***


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

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



Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Нет, ты получаешь класс в котором методы нельзя подменять без использования затенения.

Так зачем же подменять методы с использованием затенения?

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
И сразу вылезет вот такой баг

Где же тут баг?

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
У тебя в мелком классе всего пару виртуальных функций и уже есть родитель предьявляет требования к особенностям реализации наследника.

Класс всегда предъявляет требования к тем, кто им пользуется, в частности -- к наследникам.

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Вот это - увеличение связности - и есть проблема виртуальных функций и наследования вообще. 

Ну наконец-то ты признался: в Си-диезе намеренно ограничено наследование, так как у наследования есть проблемы. smile

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
А пример - да вот, прямо в твоем коде

Поподробнее пжлст. Только учти, что в бэкграунд воркере тот же, как ты выразился, "баг".

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Ну или, навскидку, любой метод типа 
EnsureDataBound/EnsureChildControls который нужно вызывать из наследников, но ни в коем случае нельзя разрешить переопределить.

Это плохой пример, потому что он -- частный. Если в каком-то редком случае метод нельзя переопределять, то это можно запретить отдельным ключевым словом. А по умолчанию переопределение должно быть разрешено.

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Если над ней подумать - то будут веские причины для ее невиртуальности.

Ну так подумай и выскажи свои соображения. 

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Ок, давай, попробуй объяснить мне, зачем нужен private.

Так ты что, не знаешь?

Ещё раз. Я могу объяснить, зачем нужен private тем, кто им не пользовался, не привык и не знает, зачем он нужен. Потому что я пользовался, привык и знаю. 

Но, естественно, я не могу объяснить это тому, кто это и так знает, но собирается изображать, что не знает (ты) smile Потому что этот человек всё равно будет изображать, что "не понял", при любых объяснениях.

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

Цитата(PashaPash @  3.11.2008,  20:29 Найти цитируемый пост)
Приведи мне пример, когда public вреден.

Я про вред ничего не говорил. Я говорил про наиболее часто нужные вещи в работе.

Добавлено через 7 минут и 17 секунд
Цитата(diadiavova @  3.11.2008,  20:54 Найти цитируемый пост)
Так разговор об умолчаниях что ли? Я то думал, что вопрос в том, зачем делать метод невиртуальным.

Так это связано. Сперва (как я понял) аргументация была такая, мол, а почему бы и нет? Лозунг -- больше возможностей, плохих и хороших. Тогда я заметил, что невиртуальность сделана по умолчанию, то есть, трактуется не просто как одна из возможностей, а как важнейшая из них. 

Ведь если бы дело было только в том, чтобы предоставить ВОЗМОЖНОСТЬ делать невиртуальные функции, то можно было бы ввести слово "nonvirtual" и всё. А по умолчанию делать бы функции виртуальными.

Цитата(diadiavova @  3.11.2008,  20:54 Найти цитируемый пост)
только их ещё можно предоставить в к использованию вне кухни, не мешая работе кухни. 

Ну так как же можно помешать работе кухни с помощью виртуального метода?

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

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

Добавлено через 8 минут и 18 секунд
Цитата(diadiavova @  3.11.2008,  21:16 Найти цитируемый пост)
Прибегал к разным ухищрениям, но такого способа я не нашёл. 

Как это нельзя? А как же ключевое слово base? (Оно же super в Джаве).
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Как это нельзя? А как же ключевое слово base? (Оно же super в Джаве). 

Хорошее слово. Жаль только за пределами класса использовать нельзя.


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


Эксперт
***


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

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



Вот код:

Код

class Program
    {
        static void Main(string[] args)
        {
            Производный п = new Производный();


            п.Звальщик();

            Console.ReadLine();
        }
    }

    class Базовый
    {
        public void Невиртуальная()
        {
            Console.WriteLine("Я невиртуальная в базовом классе");
        }

        public virtual void Виртуальная()
        {
            Console.WriteLine("Я виртуальная в базовом классе");
        }
    }

    class Производный : Базовый
    {
        public new void Невиртуальная()
        {
            Console.WriteLine("Я невиртуальная в наследнике");
        }

        public override void Виртуальная()
        {
            Console.WriteLine("Я виртуальная в наследнике");
        }

        public void Звальщик()
        {
            Невиртуальная();
            Виртуальная();
            base.Невиртуальная();
            base.Виртуальная();
        }
    }


вот вывод:

Я невиртуальная в наследнике
Я виртуальная в наследнике
Я невиртуальная в базовом классе
Я виртуальная в базовом классе

Добавлено через 2 минуты и 40 секунд
Вот такой код с теми же классами

Код

static void Main(string[] args)
        {
            Производный п = new Производный();

            ((Базовый)п).Невиртуальная();
            ((Базовый)п).Виртуальная();

            Console.ReadLine();
        }


даёт вот такой вывод:

Я невиртуальная в базовом классе
Я виртуальная в наследнике

Добавлено через 4 минуты и 10 секунд
То есть, чтобы вызвать невиртуальную функцию базового класса, нужно просто преобразовать тип.

А виртуальную функцию базового класса вызвать нельзя, в этом и состоит защита: функция, написанная, когда производного класса ещё не было в природе, не имеет права с ним работать, если была переопределена.
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Ну так как же можно помешать работе кухни с помощью виртуального метода?

Та я ж писал об этом. Когда на кухне используется метод, от него ожидается, что он будет делать дело определённым образом, а когда его переопределяют, он может делать это и по-другому. Это приходится учитывать. Не всегда возможно, да и лишний код, затраты на проверку условий и т. д. Я создаю метод для каких-то внутренних целей а кто-то его переопределяет, он работает не так как я задумал. И что в результате должно получиться? А человек, занимающийся наследованием моего класса не будет понимать откуда проблемы. У него ведь не обязательно должны быть исходные коды. 
Поэтому и по-умолчанию. А наследование это не только переопределение методов, а вообще расширение функциональности класса, определение новых методов например. Поэтому я не понимаю, к чему разговоры о нормальном наследовании и ненормальном.

Добавлено через 3 минуты и 33 секунды
Цитата(Dims @  3.11.2008,  21:38 Найти цитируемый пост)
А виртуальную функцию базового класса вызвать нельзя, в этом и состоит защита: функция, написанная, когда производного класса ещё не было в природе, не имеет права с ним работать, если была переопределена. 

Правильно, а если надо иметь такую возможность, то она есть - не делать метод виртуальным. Так что же: лучше бы её не было что ли?


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


Эксперт
***


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

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



Цитата(diadiavova @  3.11.2008,  21:50 Найти цитируемый пост)
Я создаю метод для каких-то внутренних целей а кто-то его переопределяет, он работает не так как я задумал. 

Во-первых, внутренний метод будет private.

А во-вторых, ну и что? Вред от этого будет только тому классу, который создан этим кем-то. И этот вред будет равен вреду от просто неправильно написанной функции. 

Но мы же не может надеяться запретить людям писать неправильные функции!

Добавлено через 3 минуты и 56 секунд
Цитата(diadiavova @  3.11.2008,  21:50 Найти цитируемый пост)
Правильно, а если надо иметь такую возможность, то она есть - не делать метод виртуальным. Так что же: лучше бы её не было что ли? 

Так я ж говорю, что если бы это была просто возможность, которая когда-то (непонятно, когда) может пригодиться, то тогда ладно. Но это не просто возможность, а возможность по умолчанию. То есть, важная возможность.

Поэтому, её надо понять, не так ли?

Это сообщение отредактировал(а) Dims - 3.11.2008, 21:56
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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

Добавлено через 3 минуты и 4 секунды
Цитата(Dims @  3.11.2008,  21:55 Найти цитируемый пост)
Во-первых, внутренний метод будет private.

А во-вторых, ну и что? Вред от этого будет только тому классу, который создан этим кем-то. И этот вред будет равен вреду от просто неправильно написанной функции. 

Но мы же не может надеяться запретить людям писать неправильные функции!

Да, но при этом он не будет знать в чём ошибка, так что лучше запретить.
Цитата(Dims @  3.11.2008,  21:55 Найти цитируемый пост)
Так я ж говорю, что если бы это была просто возможность, которая когда-то (непонятно, когда) может пригодиться, то тогда ладно. Но это не просто возможность, а возможность по умолчанию. То есть, важная возможность.

Поэтому, её надо понять, не так ли?

Та я то понимаю, только проблема в том, что мои аргументы мне кажутся убедительными, однако есть и другая точка зрения.


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


Эксперт
***


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

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



Цитата(diadiavova @  3.11.2008,  22:02 Найти цитируемый пост)
Да, и кстати: затенение не является такой уж важной фичей.

Тогда почему она включается по умолчанию?

Цитата(diadiavova @  3.11.2008,  22:02 Найти цитируемый пост)
Да, но при этом он не будет знать в чём ошибка, так что лучше запретить.

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

Вы почему-то делаете вывод, что надо ПО УМОЛЧАНИЮ отключить. Но для такого вывода недостаточно одной лишь констатации вреда, нужно СРАВНИТЬ частоту вреда и пользы, и сделать по умолчанию то, что приносит больше пользы и меньше вреда.

Добавлено через 4 минуты и 14 секунд
Вот, например, вред от невиртуальной функции -- можно вызвать базовую функцию по отношению к производному классу. 

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

Кстати.

Я тут покопался, и прихожу к выводу, что это и есть основной мотив. Микрософт, как коммерческий разработчик, заинтересован в том, чтобы его классы можно было использовать только так, как он предусмотрел. То есть, получать только то, за что заплачено. Если есть какая-то возможность развития класса, которую Микрософт не заметил и, стало быть, не взял за неё деньги при продаже, то эта возможность должна быть ограничена.
PM MAIL   Вверх
diadiavova
Дата 3.11.2008, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Тогда почему она включается по умолчанию?

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

Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Я не понимаю. Из этого следует, что нужно вообще запретить виртуальные функции. Но Вы же не делаете такой вывод?

А такой вывод я не делаю по двум причинам:
1.Знаю для чего нужны виртуальные методы.
2.Я уже миновал тот возраст, которому свойственен максимализм. Поэтому придерживаюсь средней линии. Вместо "всё или ничего" я предпочитаю "всё хорошо в меру и ко времени"

Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
нужно СРАВНИТЬ частоту вреда и пользы

Я так понимаю, что возможность вреда уже не оспаривается. 
О частоте вообще можно спорить долго, честно говоря не представляю себе как эту самую частоту вообще можно исчислить. Если речь идёт о неопытном программисте, то ему вообще запретить надо почти всё, а супердуперпрофи может не париться, у него и так всё получится. 
Я тут недавно одному парню советы давал по прорисовке в форме, так он в таком удивлении был, когда я объяснил ему, что надо вызвать Invalidate при изменении параметров прорисовки. Ему и в голову не пришло, что методы бывают виртуальными, и что метод определённый в базовом классе может вызывать прорисовку, которую он сам настряпал.

Добавлено через 5 минут и 33 секунды
Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Вот, например, вред от невиртуальной функции -- можно вызвать базовую функцию по отношению к производному классу. 

А можно и не вызвать, а вслучае с виртуальной - выбора нет. Иногда это хорошо, а иногда - плохо.
Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Вот ещё вред от невиртуальной функции -- невозможно вмешаться переопределить то, чего не предусмотрел или забыл предусмотреть разработчик базового класса.

Если разработчик создал плохой класс(по забывчивости), не лучше ли использовать другие разработки(кто его знает, что он там ещё забыл)

Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Я тут покопался, и прихожу к выводу, что это и есть основной мотив. Микрософт, как коммерческий разработчик, заинтересован в том, чтобы его классы можно было использовать только так, как он предусмотрел. То есть, получать только то, за что заплачено. Если есть какая-то возможность развития класса, которую Микрософт не заметил и, стало быть, не взял за неё деньги при продаже, то эта возможность должна быть ограничена. 

Коммерческий разработчик - не только майкрософт, а возможность такая есть не только у встроенных классов.


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


Эксперт
***


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

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



Вот основная мысль:
Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Класс всегда предъявляет требования к тем, кто им пользуется, в частности -- к наследникам.
Класс предьявляет к наследникам только требования по интерфейсу. А в примере с твоим воркером - ты (разработчик класса) предьявляешь требования к деталям реализации наследника. И эти требования никак не проверяются, и скорее всего про них никто никогда не узнает, даже если ты опишешь их в документации. Но зато ты явно увеличил связность и нарушил инкапсуляцию - теперь твой класс работает не со всеми наследниками, а только с некоторыми - что нонсенс с точки зрения ООП.
Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Так зачем же подменять методы с использованием затенения?

Я за 6 лет сидения на C# использовал затенение ровно 0 раз. Поэтому ответ - незачем. Нужно не извращаться с затенением, а продумывать интерфейс базового класса.

Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Это плохой пример, потому что он -- частный. Если в каком-то редком случае метод нельзя переопределять, то это можно запретить отдельным ключевым словом. А по умолчанию переопределение должно быть разрешено.

Кому должно? Вот лично мой опыт показывает, что действительно виртуальные функции - те, которые можно переопределить, и те которые действительно можно переопределить без знания о внутренностях базового класса встречаются очень-очень редко. Вообще, сам факт наследования (не от базовых классов FCL) встречается очень редко. В основном из-за того что:
Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Ну наконец-то ты признался: в Си-диезе намеренно ограничено наследование, так как у наследования есть проблемы.

C-ШАРП, раз уж ты на нем пишешь. У наследования есть проблемы вообще в OOP/OOD.


Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Поподробнее пжлст. Только учти, что в бэкграунд воркере тот же, как ты выразился, "баг".

Выше был пример. Твой воркер налагает ограничения по функциональности на наследников. Это серьезный баг с точки зрения дизайна - для того, чтобы создать простого наследника, кто-то должен будет перечитать документацию по всем методам воркера - потому что там наверняка можно будет встретить "если вы переопределяете А, то вы должны переопределить В, который обязательно должен вызвать С до вызова D, и ждать пока E станет false".

Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Так ты что, не знаешь?

Ещё раз. Я могу объяснить, зачем нужен private тем, кто им не пользовался, не привык и не знает, зачем он нужен. Потому что я пользовался, привык и знаю. 

Но, естественно, я не могу объяснить это тому, кто это и так знает, но собирается изображать, что не знает (ты) smile Потому что этот человек всё равно будет изображать, что "не понял", при любых объяснениях.

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

Честно, не знаю ;) Потому что твои аргументы применимы и к private. Типа, если написал код, который вызывает public функцию, и что-то не работает - то это код дурацкий. Никто не сколняет тебя к затенению, даже наоборот. НИКОГДА не используй его. Я аргументирую на уровне "я наступал на грабли, я знаю зачем невиртуальные функции". Просто ты не можешь понять решения проблемы т.к. с ней не сталкивался.

Вообще есть 2 проблемы, но ты из сливаешь в одну:
1. Невиртуальность по умолчанию. Это есть гуд. Хочешь доказать что не гуд - напиши версию воркера, которая не будет требовать сакральных требований.
2. Возможность делать затенение. 
Из 1 никак не следует что все поголовно затеняют методы. Из 1 следует только то, что интерфейс будет состоять только из тех методов, для которых возможность переопределения продумана. Как ты из этого выводишь что все поголовно затеняют вместо использования virual - я просто не понимаю.
Цитата(Dims @  3.11.2008,  21:23 Найти цитируемый пост)
Ну так как же можно помешать работе кухни с помощью виртуального метода?

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

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

А если знаний об интерфейсе класса недостаточно, чтобы написать рабочий вариант, как в случае твоего воркера? Документация - это зашибись, вот только ее очень часто не читают, или читают неправильно. Или забывают писать smile Если для написания недурацкого наследника требуется сакральное знание о предке, то это не наследник дурацкий, это создатель предка поленился и выставил наружу что-то лишнее. А в случае виртуальных по умолчанию - будут выставлять (забывать прятать) намного чаще. Потому что люди склонны полагаться на релизацию по умолчанию и игнорировать потенциальные проблемы.

Добавлено через 5 минут и 57 секунд
Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Тогда почему она включается по умолчанию?

она выключена по умолчанию, надо ее включить словом new. прочитав предварительно сообщение о возможных последствиях.

Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)

Вы почему-то делаете вывод, что надо ПО УМОЛЧАНИЮ отключить. Но для такого вывода недостаточно одной лишь констатации вреда, нужно СРАВНИТЬ частоту вреда и пользы, и сделать по умолчанию то, что приносит больше пользы и меньше вреда.

По умолчанию приносит меньше вреда невиртуальная функция и ругательства при попытке затенить.

Цитата(Dims @  3.11.2008,  22:13 Найти цитируемый пост)
Я тут покопался, и прихожу к выводу, что это и есть основной мотив. Микрософт, как коммерческий разработчик, заинтересован в том, чтобы его классы можно было использовать только так, как он предусмотрел. То есть, получать только то, за что заплачено. Если есть какая-то возможность развития класса, которую Микрософт не заметил и, стало быть, не взял за неё деньги при продаже, то эта возможность должна быть ограничена. 

Отличная гипотеза, вот только .net бесплатный и с открытыми исходниками. А вот в этом: "только так, как он предусмотрел" заинтересован каждый разработчик, потому что если упал твой код, пусть даже из-за кривого наследника, но глубоко в твоем коде, то виноват только ты. Все отмазки типа "это наследник кривой", "он унаследовался неправильно" не прнимаются smile



--------------------
PM MAIL WWW   Вверх
Dims
Дата 3.11.2008, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
Потомучто альтернативой затенению является переопределение, а от него вреда может быть больше.

Я этого не вижу.

Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
Если человек включил в свой класс метод, не думая о том, что его метод будет вызван базовым классом, а он всё равно будет вызван - это может стать проблемой. Поэтому по-умолчанию. 

Отсутствует логический переход. Из одного описания гипотетического вреда делается вывод, для которого необходимо сравнение вреда и пользы с разных сторон.

Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
Вместо "всё или ничего" я предпочитаю "всё хорошо в меру и ко времени"

Ну так невиртуальность в Си-диез используется безо всякой меры. Максималистски.


Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
Я так понимаю, что возможность вреда уже не оспаривается.

Она никогда и не оспаривалась. Вред может быть ото всего. Но я хотел оценить этот вред, для чего просил привести примеры.

Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
О частоте вообще можно спорить долго, честно говоря не представляю себе как эту самую частоту вообще можно исчислить.


Ну грубо можно: если несколько человек несколько дней не могут вспомнить подходящего случая, то частота невысока. И заведомо ниже, чем то, для чего следует использовать умолчание.

Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
надо вызвать Invalidate при изменении параметров прорисовки. Ему и в голову не пришло, что методы бывают виртуальными, и что метод определённый в базовом классе может вызывать прорисовку, которую он сам настряпал. 

А это, кстати, ещё один пример вреда от умолчательной невиртуальности: люди привыкают к ситуации, которая ненормальна. И о нормальных вещах узнают с удивлением.

Здесь под "нормальным" я понимаю то, что чаще пригождается. Польза от виртуальности нам известна, а вред от неё пока что гипотетичен. 

Сюда же я кладу многолетний опыт программирования на Джава: ни разу виртуальность не принесла вреда, зато постоянно исПОЛЬЗовалась. Только когда я перешёл с Си++ на Джаву, я и узнал, что такое настоящее ООП во всей красе.

Добавлено через 2 минуты и 21 секунду
Цитата(diadiavova @  3.11.2008,  22:28 Найти цитируемый пост)
Если разработчик создал плохой класс(по забывчивости), не лучше ли использовать другие разработки(кто его знает, что он там ещё забыл)

Это не плохой класс, а базовый. Предназначенный к расширению. Причём все возможности расширения предусмотреть должно быть невозможно. Потому что, если бы их можно было предусмотреть, то можно было бы включить в класс.
PM MAIL   Вверх
Dims
Дата 3.11.2008, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Класс предьявляет к наследникам только требования по интерфейсу. А в примере с твоим воркером - ты (разработчик класса) предьявляешь требования к деталям реализации наследника.

Ты уже написал об этом разработчикам бэкграунд-воркера в Микрософт? У них точно такие же требования.

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Я за 6 лет сидения на C# использовал затенение ровно 0 раз.

Ну. Значит твой опыт так же говорит, что это не нужно.

Тогда о чём мы спорим? Почему ты продолжаешь отрицать, что это ошибка разработчиков?

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Вот лично мой опыт показывает, что действительно виртуальные функции - те, которые можно переопределить, и те которые действительно можно переопределить без знания о внутренностях базового класса встречаются очень-очень редко.

Очень-очень редко -- это всё-таки чаще, чем 0, который ты признал по затенению.

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
C-ШАРП

А си-плюс-плюс ты называешь си-плас-плас? smile

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
для того, чтобы создать простого наследника, кто-то должен будет перечитать документацию по всем методам воркера - потому что там наверняка можно будет встретить "если вы переопределяете А, то вы должны переопределить В, который обязательно должен вызвать С до вызова D, и ждать пока E станет false"

А почему тогда такой баг допустили в Майкрософте?

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Никто не сколняет тебя к затенению, даже наоборот. НИКОГДА не используй его.

Это слова. А язык говорит другое: ВСЕГДА используй затенение.

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Просто ты не можешь понять решения проблемы т.к. с ней не сталкивался.

Ну так расскажи же о ней поскорее! Что ты тянешь так долго? Готовишь морально? smile


Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Невиртуальность по умолчанию. Это есть гуд. Хочешь доказать что не гуд - напиши версию воркера, которая не будет требовать сакральных требований.

Не вижу связи. Мой воркер содержит требования, аналогичные требованиям которые только что тут были описаны насчёт Validate и аналогичные требованиям, которые выдвинуты для Микрософтовского воркера. Ты предлагаешь мне для доказательства своей позиции превзойти в программировании всех на свете? А пониже планку никак не судьба?

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
Из 1 никак не следует что все поголовно затеняют методы

То же самое относится и к виртуальности. Из виртуальности метода не следует, что все поголовно его переопределяют. Поэтому здесь 0:0 или 1:1. Ничья.

Изъян твоей позиции в том, что ты никак не хочешь СРАВНИВАТЬ. Ты просто говоришь о висящих в воздухе вреде и пользе, об каких-то недостатках одного подхода. А надо говорить о РАЗНИЦЕ.


Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
А если знаний об интерфейсе класса недостаточно, чтобы написать рабочий вариант, как в случае твоего воркера? 

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

Ответ: никак.

Чтобы объектом пользоваться, надо знать не только тип параметров его интерфейса, но и что они делают.


Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
она выключена по умолчанию, надо ее включить словом new. прочитав предварительно сообщение о возможных последствиях.

new это варнинг. Его можно и не ставить.

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
По умолчанию приносит меньше вреда невиртуальная функция и ругательства при попытке затенить.

Ругательств при переопределении тоже больше -- забыть override это ошибка, а не замечание.

Цитата(PashaPash @  3.11.2008,  22:34 Найти цитируемый пост)
А вот в этом: "только так, как он предусмотрел" заинтересован каждый разработчик, потому что если упал твой код, пусть даже из-за кривого наследника, но глубоко в твоем коде, то виноват только ты.

"Кабы чё не вышло и чёб на меня не подумали" это не единственный мотив. Есть ещё такое понятие, как расширяемость. Каждый разработчик заинтересован и в ней тоже, причём даже больше, чем в первом.
PM MAIL   Вверх
Partizan
Дата 3.11.2008, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


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

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



Цитата

А язык говорит другое: ВСЕГДА используй затенение.


 smile 

Уж чего-чего, этого точно никто не говорил....


P.S. Лучше бы вы человеку про затенение не говорили...ему было бы спокойнее.


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


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


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

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



Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Это не плохой класс, а базовый. Предназначенный к расширению. Причём все возможности расширения предусмотреть должно быть невозможно. Потому что, если бы их можно было предусмотреть, то можно было бы включить в класс.

Здравая мысль! Если невозможно предусмотреть всего, значит невозможно основывать на этом какую-то логику. А если метод всё-таки нужен, то его надо делать private, а если в классах-наследниках такой метод тоже понадобится, то его по всей видимости прийдётся продублировать(потомучто private там не видно). И тут мы вообще приходим к абсурдной ситуации у нас окажется два одинаковых метода, один из которых мы сделаем private (внутренняя кухня), а второй будет виртуальным, хотя из базового класса мы его вызывать не будем.

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Отсутствует логический переход. Из одного описания гипотетического вреда делается вывод, для которого необходимо сравнение вреда и пользы с разных сторон.

Ну почему гипотетического? Если я создаю метод, и не имею возможности знать что от него можно ожидать, а что нельзя, то как я должен работать с ним? Обычно при вызове метода я ожидаю от него конкретного результата, а как я должен вызывать метод если понятия не имею, что он будет делать?

А то, что при определённом опыте можно обходить неудобства, ещё не говорит о том, что неудобств этих нет. И если в яве, где все функции виртуальны люди чувствуют себя комфортно, так и на ассемблере до сих пор некоторые пишут.


Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Ну так невиртуальность в Си-диез используется безо всякой меры. Максималистски.

Говоря о максимализме я отвечал на вопрос "Из этого следует, что нужно вообще запретить виртуальные функции...". Максимализм в том, чтобы отказаться от одного в пользу другого, а средняя линия - использование всего в меру.

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Она никогда и не оспаривалась. Вред может быть ото всего. Но я хотел оценить этот вред, для чего просил привести примеры.


Любой пример можно назвать частным случаем, а если он будет придуман для иллюстрации - надуманным.

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Ну грубо можно: если несколько человек несколько дней не могут вспомнить подходящего случая, то частота невысока. И заведомо ниже, чем то, для чего следует использовать умолчание.

А какой случай нужен? Как я создал виртуальный метод, а его переопределение принесло вред? Так не помню я такого случая. Я же на яве не писал, а в дотнете виртуальные методы я создаю только когда в виртуальности есть потребность. Я просто не задумывался о том, как бы так создать виртуальный метод, чтобы от этого были проблемы. 
Поэтому всё что могу - это описать гипотетическую ситуацию, но полагаю - это слабый аргуумент.

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
А это, кстати, ещё один пример вреда от умолчательной невиртуальности: люди привыкают к ситуации, которая ненормальна. И о нормальных вещах узнают с удивлением.


Я думаю, что ява-прогеры о понятии виртуальности узнают тоже не в первый день. Создают виртуальные функции и понятия не имеют, что они виртуальны.

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Здесь под "нормальным" я понимаю то, что чаще пригождается. Польза от виртуальности нам известна, а вред от неё пока что гипотетичен. 

Норма - понятие очень обтекаемое. То, что норма в одном контексте - в другой может не вписаться даже на правах аномалии. А чаще пригождается программисту то, к чему он больше привык. Помимо правил и гайдлайнов всевозможных есть ещё индивидуальный стиль программирования(почерк), и вырабатывается он под влиянием того, с чем приходится работать. Не удивительно, что после явы некоторые вещи кажутся неудобными, но при другом стиле программирования как раз ява может показаться "не в масть".

Цитата(Dims @  3.11.2008,  22:41 Найти цитируемый пост)
Только когда я перешёл с Си++ на Джаву, я и узнал, что такое настоящее ООП во всей красе.

Слегка напоминает высказывания последователей различных культов 
"Только познав Господа я ощутил всю полноту жизни" smile  
Ничего не имею против религии, только мы о программировании сейчас.
А ООП это просто набор принципов, которые могут реализовываться по-разному, и принадлежность к ООП накладывает не так много ограничений на язык как некоторые думают.

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Тогда о чём мы спорим? Почему ты продолжаешь отрицать, что это ошибка разработчиков?

Не ошибка, а возможность, которая жрать не просит, а если кому надо - пусть берёт, не жалко.

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Очень-очень редко -- это всё-таки чаще, чем 0, который ты признал по затенению.

Я как-то чего-то затенял, но потом общая идея оказалась неудачной, пришлось всё поменять, и в новом варианте затенения не было. Но неудачной идея была не из-за затенения, там что-то другое вылезло(уже не помню)

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
А си-плюс-плюс ты называешь си-плас-плас?

Кстати почему-то некоторых действительно раздражает. Я тут C# до-диезом называл, так один человек даже в подписи призвал так не поступать, хотя это как раз логичное название. Если американцу сказать си-шарп, то он скорее всего подумает, что речь идёт о ноте, а что до обозначения C#, так это вообще общепринятое обозначение ноты до-диез, и появилось оно задолго до компьютеров.

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Из виртуальности метода не следует, что все поголовно его переопределяют.

Проблема в том, что переопределение нужно в тех же случаях, что и затенение. Когда требуется собственная реализация метода с определённой сигнатурой. Но если эта реализация нарушит работу базового класса можно использовать затенение. 
Редкость его использования происходит от того, что классы проектируются таким образом, чтобы затенение не требовалось. Это вообще случай исключительный, а про умолчание повторяться не буду.

Добавлено через 5 минут и 23 секунды
Цитата(Partizan @  3.11.2008,  23:49 Найти цитируемый пост)
Лучше бы вы человеку про затенение не говорили...ему было бы спокойнее. 

А кто знал, что дополнительные возможности могут кого-то расстроить. Я если спрашиваю про какие-то особенности, то только из соображений, что возможно я что-то упускаю. Но вопросов такого типа у меня не возникает...

Добавлено через 12 минут и 35 секунд
Кстати здесь поблизости ещё одна такя же тема обсуждается. Там речь идёт о грядущих возможностях си-шарпа(исправляюсь smile ). За динамическую типизацию речь зашла, типа зачем и всё такое. А вот в бейсике её никто никогда не отменял, и пока никто не жаловался. Тем более, что прижелании можно включить, а можно выключить.


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


Эксперт
***


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

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



Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Обычно при вызове метода я ожидаю от него конкретного результата, а как я должен вызывать метод если понятия не имею, что он будет делать?

А причём тут виртуальность? Поверьте, тысячи людей используют Джава, где все методы виртуальные, и они отнюдь не находятся в описываемом Вами положении smile


Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Любой пример можно назвать частным случаем, а если он будет придуман для иллюстрации - надуманным.

Ну это если мы исходим из злонамеренности собеседника.

Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Как я создал виртуальный метод, а его переопределение принесло вред? Так не помню я такого случая. 

Ну так а как же Вы можете быть уверены, что такие случаи существуют?

Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
То, что норма в одном контексте - в другой может не вписаться даже на правах аномалии.

Я не против. Объясните, каким образом невиртуальные функции являются нормой вместе с контекстом, который тоже объясните.

Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Слегка напоминает высказывания последователей различных культов 

Это не ко мне. Я не делаю культа ни из чего. Или делаю из всего, то есть, пытаюсь найти логику и привлекательность в разных вещах.

Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Я как-то чего-то затенял, но потом общая идея оказалась неудачной, пришлось всё поменять, и в новом варианте затенения не было.


Ну вот. Итак, трое (включая меня) признают, что затенение не нужно. Отсюда вывод, что с нашей (конечно, субъективной и, возможно, ошибочной) точки зрения, разработчики Си-диеза допустили ошибку, когда включили его по умолчанию.

Цитата(diadiavova @  3.11.2008,  23:51 Найти цитируемый пост)
Кстати почему-то некоторых действительно раздражает.

Я думаю, они просто не знают, что такое диез, и как это будет по-английски. Логика совершенно ясна: в названии Си++ использовали оператор ++ из Си, чтобы обозначить язык больше Си, а в названии C# использовали уже музыкальный оператор повышения тона, то есть, диез; чтобы обозначить то же самое.
PM MAIL   Вверх
Partizan
Дата 4.11.2008, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


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

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



Цитата

Я думаю, они просто не знают, что такое диез, и как это будет по-английски. Логика совершенно ясна: в названии Си++ использовали оператор ++ из Си, чтобы обозначить язык больше Си, а в названии C# использовали уже музыкальный оператор повышения тона, то есть, диез; чтобы обозначить то же самое.


Я думаю, что они знают, что такое диез...
Всего-навсего так уж повелось, что язык программирования С# программисты(по крайней мере абсолютное большинство) называют "Си-шарп", в то же время музыканты запись С# в нотном стане, очевидно, прочтут как "до-диез"...и это тоже нормально, ибо в музыкальной области это действительно обозначение ноты...


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


Эксперт
***


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

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



Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Ты уже написал об этом разработчикам бэкграунд-воркера в Микрософт? У них точно такие же требования.

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
А почему тогда такой баг допустили в Майкрософте?

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Не вижу связи. Мой воркер содержит требования, аналогичные требованиям которые только что тут были описаны насчёт Validate и аналогичные требованиям, которые выдвинуты для Микрософтовского воркера. Ты предлагаешь мне для доказательства своей позиции превзойти в программировании всех на свете? А пониже планку никак не судьба?

У них требования не к наследнику, а к обработчику. Человек, подписавшийся на событие с гораздо большей вероятностью прочтет документацию по этому конкретному событию, чем по всем методам класса. Небольшая такая разница, из-за которой не нужно читать полную документацию по 20 методам майкросовтовского воркера.
Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Ну. Значит твой опыт так же говорит, что это не нужно.

Тогда о чём мы спорим? Почему ты продолжаешь отрицать, что это ошибка разработчиков

Вообще спорим о том, что ты считаешь что warning - это предупреждение. На самом деле warning - это самая настоящая ошибка. 

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
А си-плюс-плюс ты называешь си-плас-плас? smile
Ну уж никак не До-крест-крест.


Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
То же самое относится и к виртуальности. Из виртуальности метода не следует, что все поголовно его переопределяют. Поэтому здесь 0:0 или 1:1. Ничья.

Изъян твоей позиции в том, что ты никак не хочешь СРАВНИВАТЬ. Ты просто говоришь о висящих в воздухе вреде и пользе, об каких-то недостатках одного подхода. А надо говорить о РАЗНИЦЕ.

Если на стене висит ружье, то оно выстрелит. Если что-то можно сделать неправильно, кто-то сделает это неправильно. 1:0. Твой аргумент?


Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
Если недостаточно знаний об интерфейсе автомобиля, то как на нём ездить? Вот ты знаешь, что у автомобиля есть руль и он круглый и его можно крутить, и что есть педали и их можно нажимать. Но не знаешь, что они делают. 

Ответ: никак.

Чтобы объектом пользоваться, надо знать не только тип параметров его интерфейса, но и что они делают.

Что не есть как. Ты ездишь на автомобиле, все классно, но через год к тебе приходят и говорят: тут надо после каждого километра хреновинку поворачивать на полоборота? вы не поворачивали? ну тогда придется автомобиль выбросить и купить новый. Да, и штраф заплатить по количеству непроворотов.

Цитата(Dims @  3.11.2008,  23:07 Найти цитируемый пост)
"Кабы чё не вышло и чёб на меня не подумали" это не единственный мотив. Есть ещё такое понятие, как расширяемость. Каждый разработчик заинтересован и в ней тоже, причём даже больше, чем в первом. 

"как бы не пришлось учитывать что есть чужая кривая реализация" - тоже неплохой мотив. А ты предлагаешь по принципу: параметры валидируют только трусы! Разработчик заинтересован в контролируемой расширяемости, а не в поддержке чужих расширений.


--------------------
PM MAIL WWW   Вверх
diadiavova
Дата 4.11.2008, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  4.11.2008,  00:09 Найти цитируемый пост)
А причём тут виртуальность? Поверьте, тысячи людей используют Джава, где все методы виртуальные, и они отнюдь не находятся в описываемом Вами положении

Не только верю, но и сам думаю, что так оно и есть. Это привычка, выработашаяся при написании программ на яве. Я уже упоминал, что вещи неудобные в принципе могут казаться единственными удобными тем людям, которые к ним привыкли.

Цитата(Dims @  4.11.2008,  00:09 Найти цитируемый пост)
Ну это если мы исходим из злонамеренности собеседника.

Я исхожу не из злонамеренности, а из того, что вижу в собеседнике вполне естественное желание отстоять свою точку зрения. Просто иногда это желание ЗАТЕНЯЕТ желание разобраться в вопросе. Типичный пример плохого затенения.

Цитата(Dims @  4.11.2008,  00:09 Найти цитируемый пост)
Ну так а как же Вы можете быть уверены, что такие случаи существуют?

Ну у меня есть оправдание. Корпорация майкрософт надёжно защитила меня от таких ошибок. smile 

Цитата(Dims @  4.11.2008,  00:09 Найти цитируемый пост)
Я не против. Объясните, каким образом невиртуальные функции являются нормой вместе с контекстом, который тоже объясните.

Да контекст я ка бы уже объяснял. Ну вот пример: внутри класса я создаю метод, возвращающий строку в определённом формате. Вызывая функцию я ожидаю, что она будет возвращать нужную строку и её обработка не потребует много усилий. Если же я даю возможность переопределить метод, то строка может быть какой угодно. Мне потребуется проверить корректность строки, очень желательно, расширить формат, потомучто лишний пробел может сделать строку нечитабельной, и предусмотреть действия, при некорректном результате, которого в случае с моей функцией просто не может возникнуть. Теперь вопрос: какой вариант функции проще и безопаснее описать?

Цитата(Dims @  4.11.2008,  00:09 Найти цитируемый пост)
Ну вот. Итак, трое (включая меня) признают, что затенение не нужно.

Я этого не утверждал. Трудно рассуждать о примере, сути которого даже я не помню(разве что примерно помню что делал). Затенение там было нужно и проблему создало не оно. Я тогда осваивал элементы управления и делал комбобокс с картинками. Мне надо было чтобы элементы, которые принимает коллекция Items были строго моего типа, который содержал информацию о картинке, её расположении и т. д. Но свойство Item(а в бейсике индексаторы считаются свойствами) не было виртуальным и я его затенял. В данном контексте действие вполне уместное, но сама идея как оказалось не очень. 


Цитата(Partizan @  4.11.2008,  00:14 Найти цитируемый пост)
Всего-навсего так уж повелось, что язык программирования С# программисты(по крайней мере абсолютное большинство) называют "Си-шарп"

Насчёт большинства - сомневаюсь, компьютерщики всех мастей вообще любят называть то с чем работают всякими смешными словами.

Цитата(Partizan @  4.11.2008,  00:14 Найти цитируемый пост)
в то же время музыканты запись С# в нотном стане, очевидно, прочтут как "до-диез"

Вряд ли в нотном стане может появится такая запись(разве что при обозначении аккорда или тональности)

Цитата(Partizan @  4.11.2008,  00:14 Найти цитируемый пост)
и это тоже нормально, ибо в музыкальной области это действительно обозначение ноты

А почему сосно музыкант не может быть программистом?

Добавлено @ 00:45
Да насчёт автомобиля совсем забыл. Для тог, чтобы ездить не надо знать устройство. Надо просто уметь пользоваться интерфейсом.

Это сообщение отредактировал(а) diadiavova - 4.11.2008, 00:47


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


Let's do some .NET
****


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

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



diadiavova,  
Цитата

Насчёт большинства - сомневаюсь, компьютерщики всех мастей вообще любят называть то с чем работают всякими смешными словами.

Ну зачем ёрничать...

Цитата

А почему сосно музыкант не может быть программистом? 


Я говорю об области, в которой используется обозначение...
ежели это название языка программирования, то правильно будет его называть именно так, как устоялось...а именно "си-шарп"
ежели это музыкальное обозначение и мы говорим о музыке, то пожалуйста... тогда говорим "до диез"

....кстати говоря в этой теме я вообще увидел ещё одно))) Си-диез ) это у нас что?...я слышал, что у ноты Си диеза нету, только бемоль )


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


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


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

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



Цитата(Partizan @  4.11.2008,  00:53 Найти цитируемый пост)
Ну зачем ёрничать

Вообще-то ёрничаю я совсем не так. По моему это уже можно было заметить.
Примеры могу привести на ходу
мускул
пхп
хтмл
васик
жаба(по-моему куда более обидное название)
И это только языки программирования. А рассуждать обо всяких имхо, сабжах, матерях(в смысле железа, вот ещё тоже словечко "железо") можно вообще до бесконечности.

Цитата(Partizan @  4.11.2008,  00:53 Найти цитируемый пост)
Я говорю об области, в которой используется обозначение...
ежели это название языка программирования, то правильно будет его называть именно так, как устоялось...а именно "си-шарп"
ежели это музыкальное обозначение и мы говорим о музыке, то пожалуйста... тогда говорим "до диез"

Ну о том как сленг приходит из других областей тоже можно рассуждать долго.

Цитата(Partizan @  4.11.2008,  00:53 Найти цитируемый пост)
кстати говоря в этой теме я вообще увидел ещё одно))) Си-диез ) это у нас что?...я слышал, что у ноты Си диеза нету, только бемоль ) 

Здесь просто было название буквы(а точнее языка си) соединено с названием значка в русском языке, а музыкальный термин вообще не имелся ввиду.
А си-диез есть, только это чистая до. Просто между си и до - полтона, поэтому повышение си на полтона (это делает диез) приводит к ноте до.(это так, если интересно)



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


Let's do some .NET
****


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

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



Ладно )
Не хотите обращаться в нашу веру? - Как хотите  smile 

Цитата

Примеры могу привести на ходу
мускул
пхп
хтмл
васик


всё это производные от написания/произношения...
Си-Шарп вполне попадает в этот ряд...

никто же не говорит "МойЭсКуЭл"

Это сообщение отредактировал(а) Partizan - 4.11.2008, 01:23


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


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


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

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



Та я ж из васиков. И кстати, уверен, что васик - круче.

Добавлено через 4 минуты и 3 секунды
Цитата(Partizan @  4.11.2008,  01:21 Найти цитируемый пост)
никто же не говорит "МойЭсКуЭл"

А просто потому, что давая сленговые имена, думают не о логике, а о том, чтобы прикольнее было.


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


Let's do some .NET
****


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

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



diadiavova

о логике:
Цитата

...Одним из таких языков, причем для этой среды основным, и является Си# (читается как “Си шарп”). Названием языка конечно же хотели подчеркнуть его родство с Си++, ведь # - это два пересекшихся плюса...


Во всех статьях говорится именно о # как о подчёркивании сходства с С++, но нигде не говорится, что символ # был использован, чтобы показать "превосходство на полтона" )


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


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


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

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



Цитата(Partizan @  4.11.2008,  01:30 Найти цитируемый пост)
Во всех статьях говорится именно о # как о подчёркивании сходства с С++, но нигде не говорится, что символ # был использован, чтобы показать "превосходство на полтона"

Я видел оба варианта объяснения, и кстати: о последнем узнал недавно. В любом случае всё это только предположения. Официальных разъяснений на этот счёт я не видел, да и потом, о логике: повторюсь
 
Цитата(diadiavova @  4.11.2008,  01:22 Найти цитируемый пост)
А просто потому, что давая сленговые имена, думают не о логике, а о том, чтобы прикольнее было.



Это сообщение отредактировал(а) diadiavova - 4.11.2008, 01:35


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


Let's do some .NET
****


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

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



diadiavova, надо будет написать Хейльсбергу и спросить у него )))


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


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


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

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



А это правда так важно?

Это сообщение отредактировал(а) diadiavova - 4.11.2008, 02:06


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


Let's do some .NET
****


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

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



Как минимум интересно...


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


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


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

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



А вот кстати:
Язык F# - фа-диез
И что после этого думать?


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


Let's do some .NET
****


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

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



diadiavova, J# тогда это что?


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


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


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

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



Цитата(Partizan @  4.11.2008,  02:20 Найти цитируемый пост)
J# тогда это что? 

Ява
Свою реализацию javascript они назвали jscript, логично, что, стырив яву, они придерживались той же логики. А диез добавили, чтобы показать, что их ява круче smile

Добавлено через 2 минуты и 16 секунд
Кроме того, имя было неправильное, поэтому язык долго не прожил

Добавлено через 4 минуты и 27 секунд
И кстати: если C# выше С на пол-тона, то F# - выше C# на целую кварту.


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


Let's do some .NET
****


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

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



Не...я в смысле - это у нас чтоли Соль-диез?...
Не...не правильно это, язык программирования называть музыкальным термином...надо разграничивать...

з.ы. ладно...это уже полный оффтопик...
по топику могу только сказать, что согласен с теми, кто утверждает, что виртуальные по умолчанию методы из джавы(явы, как угодно) кроют потенциальную опасность, и, поэтому, невиртуальность по умолчанию, как это сделано в C# является плюсом...


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


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


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

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



Цитата(Partizan @  4.11.2008,  02:31 Найти цитируемый пост)
Не...я в смысле - это у нас чтоли Соль-диез?.

Соль-диез будет G#. Не удивлюсь если и такой язык появится.

Цитата(Partizan @  4.11.2008,  02:31 Найти цитируемый пост)
по топику могу только сказать, что согласен с теми, кто утверждает, что виртуальные по умолчанию методы из джавы(явы, как угодно) кроют потенциальную опасность, и, поэтому, невиртуальность по умолчанию, как это сделано в C# является плюсом... 

Трудно говорить, о таких вещах, как о плюсах или минусах. Дело привычки. Просто можно было какое нибудь ключевое слово придумать для всего класса, которое меняло бы умолчания, здесь варианты есть, да кто знает - может и придумают что-то в этом роде. 


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


Эксперт
***


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

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



Цитата(Partizan @  4.11.2008,  00:14 Найти цитируемый пост)
в то же время музыканты запись С# в нотном стане, очевидно, прочтут как "до-диез".

На мой взгляд, музыканты ни причём. Даже американские немузыканты воспринимают название языка как "Си-диез". Они могут не знать, что "Си" означает ещё и ноту, а думать, что речь идёт о языке Си.

Добавлено через 8 минут и 58 секунд
Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
У них требования не к наследнику, а к обработчику.

Это что, существенно меняет дело? Требования те же самые, один х... надо читать инструкцию. Твой идеальный мир, в котором этого можно не делать всё равно не прорисовывается.

Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
Человек, подписавшийся на событие с гораздо большей вероятностью прочтет документацию по этому конкретному событию, чем по всем методам класса.

Это уже чистейшая инстинуация с твоей стороны. Требования те же самые, элементы те же самые, предназначение то же самое, значит и вероятность прочесть инструкцию та же самая. 

Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
Вообще спорим о том, что ты считаешь что warning - это предупреждение. На самом деле warning - это самая настоящая ошибка. 

От того, что ты это сказал, оно так не стало smile

Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
Если на стене висит ружье, то оно выстрелит. Если что-то можно сделать неправильно, кто-то сделает это неправильно. 1:0. 

Я не понял, почему это ты себе очко записал? Это абстрактное рассуждение с тем же успехом можно записать и на мой счёт.

Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
Что не есть как.

А я где-то утверждал, что что есть как?

Цитата(PashaPash @  4.11.2008,  00:36 Найти цитируемый пост)
Разработчик заинтересован в контролируемой расширяемости, а не в поддержке чужих расширений. 

Разработчик железобетона предназначал его для изготовления цветочных горшков. Прикинь, что бы мы сейчас делали, если бы у него был в распоряжении C# для реальности?

Добавлено через 13 минут и 58 секунд
Цитата(Partizan @  4.11.2008,  01:30 Найти цитируемый пост)
Во всех статьях говорится именно о # как о подчёркивании сходства с С++, но нигде не говорится, что символ # был использован, чтобы показать "превосходство на полтона" ) 

Это говорится в англо-русском словаре, в статье про слово "шарп", которое переводится, как "диез". Странно, что они говорят "си-шарп", но не имеют в виду диез, потому что тогда почему они говорят именно так?
PM MAIL   Вверх
Dims
Дата 4.11.2008, 05:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Partizan @  4.11.2008,  02:31 Найти цитируемый пост)
Не...не правильно это, язык программирования называть музыкальным термином...надо разграничивать...

Ну это претензия к Микрософту.

Добавлено через 1 минуту и 32 секунды
http://en.wikipedia.org/wiki/C_Sharp_(prog...)#Language_name
PM MAIL   Вверх
PashaPash
Дата 4.11.2008, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
Это уже чистейшая инстинуация с твоей стороны. Требования те же самые, элементы те же самые, предназначение то же самое, значит и вероятность прочесть инструкцию та же самая. 

Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
Это что, существенно меняет дело? Требования те же самые, один х... надо читать инструкцию. Твой идеальный мир, в котором этого можно не делать всё равно не прорисовывается.

Нет, не те же. Для наследования от твоего воркера надо прочитать документацию по всем его функциям. Для использования MS-ового - только требования к обработчику события. Ты разницу между 1 статьей и полной документацией чувствуешь? Для дизайна MS не нужны виртуальные по умолчанию функции, даже наследование не нужно. Для твоего - надо обязательно сделать новый класс, и изучить всю документацию по базовому классу.
Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
От того, что ты это сказал, оно так не стало smile

Есть галочка threat warning as errors. Которую принято включать smile Warning - это когда даже компилятор видит что программист сморозил потенциально опасную хрень. Не влезай - убьет - warning, но его ты не игнорируешь обычно.
Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
Разработчик железобетона предназначал его для изготовления цветочных горшков. Прикинь, что бы мы сейчас делали, если бы у него был в распоряжении C# для реальности?
А представь что разрабочик глины предназначал ее для горшков. Один раз сделал ее чуть прочнее, какой-то чудак сделал из нее небоскреб, и с тех пор разрабочику глины приходится делать ее с учетом, что из нее будут лепить небоскребы. 
Наследование и виртуальные функции - не единственный способ расширяемости.

Вообще, наследование не от классов фреймворка - очень редко используемая вещь. Возьми, например, среднее web-приложение. Плоская иерархия классов-страниц, плоская иерархия контроллеров, плоская иерархия сервисов в BL, плоская иерархия объектов домена. Куча невирутальных функций. Основной упор - на реализацию интерфейсов, чтобы IoC работал. В win - та же самая картина. 90% классов не объявляют новые виртуальные функции и не переопределяют существующие. И вроде никто на проблемы с расширяемостью не жалуется. Нужно еще классы сделать sealed по умолчанию - потому что при написании классов никто обычно не думает что будет при наследовании. Очень сомневаюсь, что ты всегда думаешь о последствиях override-а.
Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
А я где-то утверждал, что что есть как?
Ты утверждал что практически любой метод можно сделать виртуальным без последствий. Это подразумевает что создающий наследника знает что делает метод родителя, и как именно он это делает. Или всегда может корректно переопределить его без знаний о деталях реализации этого метода в родителях. Т.к. телепаты пока не появились, то скорее - первое.

Это сообщение отредактировал(а) PashaPash - 4.11.2008, 11:13


--------------------
PM MAIL WWW   Вверх
diadiavova
Дата 4.11.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  4.11.2008,  05:00 Найти цитируемый пост)
На мой взгляд, музыканты ни причём. Даже американские немузыканты воспринимают название языка как "Си-диез". Они могут не знать, что "Си" означает ещё и ноту, а думать, что речь идёт о языке Си.

В Америке существует два способа именования нот. Одно - международное(как у нас), оно почти не используется; другое происходит от английского названия латинских букв, которыми принято обозначать ноты(за одним небольшим исключением, происходящим от того, что американская система немного отличается от классической, это касается нот си и си-бемоль). Поэтому если сказать американцу си-шарп, он скорее всего подумает, что речь идёт именно о ноте.

А статья

Цитата(Dims @  4.11.2008,  05:16 Найти цитируемый пост)
http://en.wikipedia.org/wiki/C_Sharp_(prog...)#Language_name 

порадовала. Оказывется есть ест ещё язык A#. То есть семейство "музыкальных" языков пополнилось ещё и ля-диезом smile smile 

Это сообщение отредактировал(а) diadiavova - 4.11.2008, 13:27


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


Эксперт
***


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

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



Цитата(PashaPash @  4.11.2008,  11:12 Найти цитируемый пост)
Для наследования от твоего воркера надо прочитать документацию по всем его функциям. Для использования MS-ового - только требования к обработчику события. Ты разницу между 1 статьей и полной документацией чувствуешь?

Эту разницу ты создал. 

Обработчик события DoWork -- это то, что у меня абстрактный метод SpecificWork. Собираясь его реализовать в наследнике, я должен буду прочесть к нему инструкцию. И там увижу почти тот же текст, что и в инструкции к Микрософтовскому воркеру. В частности, у себя в инструкции я увижу, что нужно проверять ShouldStop, а у Микрософта, что нужно проверять CancellationPending. Точно так же, как у Микрософта я могу захотеть написать обработчик RunWorkerCompleted и тогда прочту к нему инструкцию, так же и у меня я могу захотеть реализовать Done и тогда прочту инструкцию к нему.

Короче, те же яйца, вид сбоку. Где ты там видишь какую-то разницу, ума не приложу. 

Цитата(PashaPash @  4.11.2008,  11:12 Найти цитируемый пост)
Для твоего - надо обязательно сделать новый класс, и изучить всю документацию по базовому классу.

Выдумываешь.

Цитата(PashaPash @  4.11.2008,  11:12 Найти цитируемый пост)
Ты утверждал что практически любой метод можно сделать виртуальным без последствий.

Это не голословное утверждение, а вывод на основе опыта программирования на Джава. Сообщество накопило, наверное, миллионы человеко-часов. Ты понимаешь, поэтому, что все жутчайшие выводы, которые ты сейчас сделаешь -- это борьба с ветряными мельницами?

Я же предлагаю рассуждать разумно. Если виртуальность всех функций и содержит какие-то недостатки, то они ТОНКИЕ. Нет такого, как пишешь ты. Или как diadiavova написал, что он не любит работать, когда сидишь и не знаешь, что делают методы, мол, якобы, это следует из виртуальности. Не так это. Не следует. 

PM MAIL   Вверх
diadiavova
Дата 5.11.2008, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  4.11.2008,  23:21 Найти цитируемый пост)
Или как diadiavova написал, что он не любит работать, когда сидишь и не знаешь, что делают методы, мол, якобы, это следует из виртуальности. Не так это. Не следует. 

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

В такой ситуации по-моему вполне естественно что я предоставляю потенциальному(!) наследователю доступ только к тем элементам, которые расчитаны на то, что их могут переопределить. Всё остальное нужно для работы моего класса.

Кроме того: спорить о том, надо докуметировать классы или нет - бессмысленно. Другой вопрос: что лучше класс, требующий минимума документации, или такой, где про каждый метод надо будет объяснить все возможные последствия того или иного действия?

Покупая телевизор тоже инструкцию надо прочитать, но совсем не обязательно знать как он устроен для того, чтобы каналы переключать.

Поэтому и возникает вопрос, что лучше сделать максимально безопасный класс, или позволить делать с ним всё, но снабдить подробной инструкцией, объясняющей, почему этого делать
 нельзя.


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


Эксперт
***


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

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



Цитата(diadiavova @  5.11.2008,  00:03 Найти цитируемый пост)
А что следует из виртуальности, если не то, что в производном классе функция будет делать неизвестно что?

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



PM MAIL   Вверх
PashaPash
Дата 5.11.2008, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  4.11.2008,  23:21 Найти цитируемый пост)
Эту разницу ты создал. 

Обработчик события DoWork -- это то, что у меня абстрактный метод SpecificWork. Собираясь его реализовать в наследнике, я должен буду прочесть к нему инструкцию. И там увижу почти тот же текст, что и в инструкции к Микрософтовскому воркеру. В частности, у себя в инструкции я увижу, что нужно проверять ShouldStop, а у Микрософта, что нужно проверять CancellationPending. Точно так же, как у Микрософта я могу захотеть написать обработчик RunWorkerCompleted и тогда прочту к нему инструкцию, так же и у меня я могу захотеть реализовать Done и тогда прочту инструкцию к нему.

Короче, те же яйца, вид сбоку. Где ты там видишь какую-то разницу, ума не приложу. 

Цитата(Dims @  4.11.2008,  23:21 Найти цитируемый пост)
Выдумываешь.

Что, не надо создавать базовый класс? Или не надо читать документацию?
Ок, используем подход java и делаем все методы виртуальными. Их в воркере штук 7, если считать сеттери и геттеры. Сколько из них может полностью переопределить наследник, не поломав всю реализацию? Полностью - без вызова base и без дублирования кода из base. Только 2, и то только потому что они ничего не делают. И виноват в этом ес-но ... автор наследника. IMHO, виноват автор базового класса, который не продумал интерфейс. 
А теперь сравни это с возможностью неправильно подписаться на событие стандартного воркера. Он, кстати, не предьявляет вообще никаких требований к использующему его. Только надежда что тот будет периодически (да хоть раз в сутки) проверять CancellationPending.
Что, совсем не видно разницы? А ведь именно из-за этой "неуловимой" разницы появился Design By Contract и прочие формы отказа от наследования реализации.
Вот, линк по теме, а то пересказывать влом: http://blogs.gotdotnet.ru/personal/bezzus/...2c-f54450aa64d6
Цитата(Dims @  4.11.2008,  23:21 Найти цитируемый пост)
Это не голословное утверждение, а вывод на основе опыта программирования на Джава. Сообщество накопило, наверное, миллионы человеко-часов. Ты понимаешь, поэтому, что все жутчайшие выводы, которые ты сейчас сделаешь -- это борьба с ветряными мельницами?

Есть PHP, в котором ООП в зачаточном состоянии. На нем написны миллиарды строк кода и проведены миллиарды человекочасов. На основе опыта программирования на PHP любой студент-кодер может сделать неголословное утверждение, даже вывод, что ООП - вообще вредно, только лишний раз мозг напрягает. Строгая типизация, обработка исключений, сборщик мусора, и вообще все, что хоть сколько-нибудь заботится о дизайне приложения, о минимизации контрактов, о соблюдении принципов ООП - это тоже борьба с ветряными мельницами? Или может это обдуманные решения, принятые ради удобства самих разработчиков? Миллионы леммингов не могут ошибаться.
И, кстати, C#/.NET тоже довольно распространенные языки, но за все время я только один раз видел жалобы на невиртуальные по умолчанию функции. Вот в этом топике smile

Добавлено через 4 минуты и 34 секунды
Цитата(Dims @  5.11.2008,  14:36 Найти цитируемый пост)
Я же говорю: этот вывод элементарно опровергается практикой. Не могло бы быть на джаве написано столько качественных прог, если бы функции делали неизвестно-что.

Зато на написание и на поддержку этого качества могло бы уйти намного меньше времени.


--------------------
PM MAIL WWW   Вверх
Dims
Дата 5.11.2008, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Их в воркере штук 7, если считать сеттери и геттеры. Сколько из них может полностью переопределить наследник, не поломав всю реализацию?

Да сколько угодно. Вопрос только, нафига их ему переопределять? Есть абстрактные методы, их переопрелять обязательно. А неабстрактные методы можно не переопределять. 

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Полностью - без вызова base и без дублирования кода из base.

Ну ты придумай ещё каких-нибудь ограничений. А потом ещё какие-нибудь выводы сделай на основании того, что сам придумал.

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
А теперь сравни это с возможностью неправильно подписаться на событие стандартного воркера.

Зачем мне сравнивать с возможностью подписаться неправильно? 

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Что, совсем не видно разницы?

Не видно разницы в необходимом объёме прочтения документации и в объёме требований к, которую ты заявлял. Ты теперь признаёшь, что был в этом неправ и переходишь к рассмотрению какой-то другой разницы? Невозможно же, не разобравшись с одним вопросом, перескакивать на следующий.

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Вот, линк по теме, а то пересказывать влом: http://blogs.gotdotnet.ru/personal/bezzus/...2c-f54450aa64d6

А не надо пересказывать, надо высказывать свои мысли.

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
На основе опыта программирования на PHP любой студент-кодер может сделать неголословное утверждение, даже вывод, что ООП - вообще вредно

Не надо передёргивать. На основании этого опыта можно сделать вывод, что отсутствие ООП это не катастрофа, вот и всё.

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Строгая типизация, обработка исключений, сборщик мусора, и вообще все, что хоть сколько-нибудь заботится о дизайне приложения, о минимизации контрактов, о соблюдении принципов ООП - это тоже борьба с ветряными мельницами?

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

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Или может это обдуманные решения, принятые ради удобства самих разработчиков?

Конечно, это обдуманные решения.

Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
Миллионы леммингов не могут ошибаться.

Дело не в количестве леммингов, а в качестве мыслей. За каждым решением должна стоять мысль, а эту мысль должно быть можно сформулировать.

За отказом от виртуальных функций я пока увидел только одну мысль -- ограничить возможность наследника вмешиваться в функционирование того, что он использует в своей конструкции. Я нахожу это не плюсом, а минусом. 
Цитата(PashaPash @  5.11.2008,  15:07 Найти цитируемый пост)
И, кстати, C#/.NET тоже довольно распространенные языки, но за все время я только один раз видел жалобы на невиртуальные по умолчанию функции. Вот в этом топике

Ой, а покажи, на какой странице? И кто жаловался, не подскажешь?
PM MAIL   Вверх
Partizan
Дата 5.11.2008, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


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

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



Dims, принцип наименьших привилегий знаком?


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


Эксперт
***


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

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



Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
Ну ты придумай ещё каких-нибудь ограничений. А потом ещё какие-нибудь выводы сделай на основании того, что сам придумал.

Это как раз не ограничения. Ограничения - это "обязательно надо вызвать base".
Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
Да сколько угодно. Вопрос только, нафига их ему переопределять? Есть абстрактные методы, их переопрелять обязательно. А неабстрактные методы можно не переопределять. 

Так о том и спор. Если наследник не может корректно переопределить неабстрактный метод, то лучше бы этому методу вообще не быть виртуальным.
Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
А не надо пересказывать, надо высказывать свои мысли.

А ты сходи, почитай. Может и появятся свои мысли, а не только "в java так, зачем вы сделали по-другому" smile
Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)

Не видно разницы в необходимом объёме прочтения документации и в объёме требований к, которую ты заявлял. Ты теперь признаёшь, что был в этом неправ и переходишь к рассмотрению какой-то другой разницы? Невозможно же, не разобравшись с одним вопросом, перескакивать на следующий.
Вообще-то объем документации которую НУЖНО изучить перед использованием класса напрямую связан с объемом требований. Просто ты почему-то воспрнимаешь, например, обязательный вызов base как само-собой разумеющееся, а не как требование, налагаемое на наследника. Или, например, необходимость поддерживать интерфейс следующих версий базового класса - тоже требование к наследнику.

Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
Не надо передёргивать. На основании этого опыта можно сделать вывод, что отсутствие ООП это не катастрофа, вот и всё.

Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
Ну если кто-то скажет, что без сборщика мусора -- полный капец -- то это будет борьба с ветряными мельницами. На самом деле, перечисленные тобой вещи просто улучшают жизнь, повышают КПД и производительность труда. Но они не превращают смерть в жизнь.

Да любой пхп-ст тебе как два пальца докажет что ООП - бесполезный выверт. Недвано на хабре даже спор был о полезности ООП.

Ну вот невиртуальность функций по умолчанию, и вообще переход от наследования реализации к наследованию контракта повышает производительность, КПД, и уменьшают количество багов и затрат на поддержку. Хочешь конкретных примеров - возьми стандартные паттерны - IoC/DI, MVC - не используется в них наследование. Возьми гамму - там наследование реализации очень редко встречается. Возьми того же Фаулера - там наследования почти нет. Возьми какой-нибудь Eiffel - типа идеал ООП - там вообще один интерфейсы. Почитай классику по ООП - Алана Кея - там нет наследования как такового.

Вирутальные функции тоже не превращают жизнь в смерть, просто перед их объявлением надо думать. Ну не верю я, что до написания тела функции можно быть 100% уверенным в том, что она достойна стать виртуальной. А ты веришь в умных кодеров наследников, которые будут читать документацию.

Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
Дело не в количестве леммингов, а в качестве мыслей. За каждым решением должна стоять мысль, а эту мысль должно быть можно сформулировать.

За отказом от виртуальных функций я пока увидел только одну мысль -- ограничить возможность наследника вмешиваться в функционирование того, что он использует в своей конструкции. Я нахожу это не плюсом, а минусом. 

Мысль - ограничить возможность наследника вмешаться прямо (некорректно заменить) или косвенно (использовать недокументированные подробности реализации базового класса) вмешаться в реализацию базового класса. Снизить вероятность привязки наследника к конкретной реализации базового класса. Ограничить распространение изменений базового класса - отказом от наследования вообще, или от виртуальных функций в частности. Принудительно потребовать от наследника соблюдать принцип подстановки (а не на надеятся на умных кодеров наследника). И еще много мыслей, которые ты сейчас отметешь как несущественные, потому что в java можно кодить без них.

Добавлено через 1 минуту и 6 секунд
Partizan, бесполезно, он исповедует принцип свободы, и считает невиртуальные функции лишними ограничениями и происками MS.


--------------------
PM MAIL WWW   Вверх
mr.DUDA
Дата 5.11.2008, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


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

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



Модератор: БУУУУУУУУУУУ !!!!!!!!!!!!!

Ну народ, и нафлудили вы тут пока меня не было полгода...  smile  smile  smile  smile 

В общем, насчёт "почему все функции не виртуальные по умолчанию" отвечаю по существу. Потому что вызов виртуальной функции дороже с точки зрения производительности. Соответственно полиморфизм - необязательное свойство методов в сишарпе (в отличие от Java).


--------------------
user posted image
PM MAIL WWW   Вверх
diadiavova
Дата 5.11.2008, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  5.11.2008,  14:36 Найти цитируемый пост)
Я же говорю: этот вывод элементарно опровергается практикой. Не могло бы быть на джаве написано столько качественных прог, если бы функции делали неизвестно-что.

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

Цитата(Dims @  5.11.2008,  18:56 Найти цитируемый пост)
За отказом от виртуальных функций я пока увидел только одну мысль -- ограничить возможность наследника вмешиваться в функционирование того, что он использует в своей конструкции. Я нахожу это не плюсом, а минусом.

А кто говорит об отказе? Речь только о том, чтобы не делать виртуальными члены, не предназначенные для переопределения.



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


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

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



OFF: Ура! Модератор вернулся. Теперь будет чистота и порядок. А то уже эти холивары надоели smile



mr.DUDA: угу, дискуссия была весьма захватывающей, я даже попкорн купил... но для холиваров есть целый раздел, а тут им не место вообще-то.  smile 

Это сообщение отредактировал(а) mr.DUDA - 6.11.2008, 00:43


--------------------
user posted image
PM ICQ   Вверх
diadiavova
Дата 6.11.2008, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(MasterOfCode @  5.11.2008,  21:32 Найти цитируемый пост)
дискуссия была весьма захватывающей, я даже попкорн купил... но для холиваров есть целый раздел, а тут им не место вообще-то.

То есть вот так вот значит, да? Развлёкся, попкорна похавал, а теперь мятыми упаковками от этого попкорна в тех, кто тебя развлекал швыряешь?
И потом: причём тут холивар? Мы просто общаемся, выясняя вопрос, вполне вписывающийся в тематику форума. Если автор темы не пометил вопрос решённым - значит ему не всё ясно, а объяснения вроде

Цитата(mr.DUDA @  5.11.2008,  20:58 Найти цитируемый пост)
Потому что вызов виртуальной функции дороже с точки зрения производительности. 

не убеждают даже меня, ибо в этом случае возникает вопрос: а почему тогда все классы не делаются завершёнными по-умолчанию? 


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


3D-маньяк
****


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

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



Цитата(diadiavova @  6.11.2008,  10:10 Найти цитируемый пост)
не убеждают даже меня, ибо в этом случае возникает вопрос: а почему тогда все классы не делаются завершёнными по-умолчанию? 

Разницу между расширяемостью и оптимальным подходом видишь?

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

Теперь про оптимальный подход. Допустим я хардкорный программер и хочу поиметь максимальную производительность и мимимум оверхеда на всякие ООП-приблуды, но вынужден по той или иной причине пользоваться дотнетом и сишарпом. Что мне делать? Использовать один-два класса, функциональный подход, никаких виртуальных функций, структуры вместо классов на мелкие объекты, массивы через указатели и так далее. Здесь мне уже начхать на полиморфизм и наследование.

Итак, вопрос: что важнее с точки зрения создателя такого языка и такой платформы как сишарп и дотнет? Ответ такой: важны все разработчики, важны все возможные области применения. Вердикт: минимум ограничений, максимум возможностей. Не запрещается наследование, но и не принуждается использование виртуальных функций.

Пример частный, но в контексте темы.

З.Ы. попкорном не кидаюсь!!!!!  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
diadiavova
Дата 7.11.2008, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Ну здесь, на сколько я понимаю, никто не говорил об ограничениях, спор всего-навсего о том, какими члены типов должны быть по-умолчанию. Умолчания обычно можно изменять, однако те значения, которые элементы имеют по-умолчанию, считаются оптимальными и наиболее часто используемыми. И разногласия были собственно в том, что чаще нужно: виртуальные члены или нет.
Если мне по тем или иным причинам понадобится виртуальный член, то скорее всего производительность отойдёт на второй план и я сделаю член типа виртуальным. Собственно, я говорил только о том, что в контексте разговора производительность(ИМХО) не является решающим фактором.

Цитата(mr.DUDA @  7.11.2008,  02:32 Найти цитируемый пост)
попкорном не кидаюсь

Та ладно бы попкорном, а то пожамканая упаковка в ход идёт smile



Это сообщение отредактировал(а) diadiavova - 7.11.2008, 02:51


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


3D-маньяк
****


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

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



Цитата(diadiavova @  7.11.2008,  02:48 Найти цитируемый пост)
Та ладно бы попкорном, а то пожамканая упаковка в ход идёт

diadiavova, работа такая у модератора - кидать упаковкой от попкорна или чем-нибудь потяжелее  smile

Консенсуса не видно, тема уже на 6 страницах, треть постов - оффтоп на тему нот и затенения. Заготавливаю ещё попкорн, чтобы было чем швыряться...


--------------------
user posted image
PM MAIL WWW   Вверх
diadiavova
Дата 7.11.2008, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(mr.DUDA @  7.11.2008,  12:14 Найти цитируемый пост)
работа такая у модератора - кидать упаковкой от попкорна или чем-нибудь потяжелее 

Можно было бы и попкорном швырнуть для разнообразия, а то тоже охота.
Цитата(mr.DUDA @  7.11.2008,  12:14 Найти цитируемый пост)
треть постов - оффтоп на тему нот и затенения

Насчёт нот - согласен, а с затенения всё и началось. Dims спросил: зачем оно нужно, и тут выяснилось, что функции не виртуальные по-умолчанию. 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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