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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> new keyword в объявление методов, зачем ??? 
:(
    Опции темы
StepS
  Дата 1.6.2007, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 26.8.2005
Где: Днепропетровск

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



Вем привет.

До недавнего времени я был уверен в следующем:
Код

class A{
   public void M1(){
      Console.WriteLine("Class A");
   }
}

class B : A{
    public void M1(){
       Console.WriteLine("Class B");
    }
}


так вот... я был уверен, что если написать так:
Код

  A a = new B();
  a.M1();


на экране появиться строка: "Class A", т.к. в классе B мы не используем ключевое слово new в объявлении метода, который скрывает метод из базового класса,
а если мы напишем new public void M1(){....} в классе В, то на экране появится строка "Class B". Но... как оказалось.. это не так

теперь я понимаю, что ключевое слово new чисто для удобства чтения кода.  или КАК ?
в книге написано: "Без использования ключевого слова new вы рискуете вызвать не тот метод". КАК НА ПРИМЕРЕ ВЫЗВАТЬ НЕ ТОТ МЕТОД ???  smile  у меня не получилось вызвать не тот метод.
PM MAIL ICQ   Вверх
SpaceSpace
Дата 1.6.2007, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

есть такое дело

ключевое слово NEW - вызывает конструктор класса,
но базовый то у тебя А!!
а, если напишеш
, а потом приведешь
Код

        class A
        {
            public void M1()
            {
                Console.WriteLine("Class A");
            }
        }

        class B : A
        {
            public void M1()
            {
                Console.WriteLine("Class B");
            }
        }
        static void Main(string[] args)
        {
            A g = new B();
           // видиш как хитро :)
            ((B)g).M1();
            Console.Read();
        }

то вызовется нужный метод В!

там все дело в том, что ты создаеш класс А, с его стеком процедур,
а конструктор чужой

а вот если напишешь
Код

        class A
        {
            virtual public void M1()
            {
                Console.WriteLine("Class A");
            }
        }

        class B : A
        {
            override public void M1()
            {
                Console.WriteLine("Class B");
            }
        }
        static void Main(string[] args)
        {
            A g = new B();
            g.M1();
            Console.Read();
        }

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

если в В напишешь
Код

override public void M1(){}

то всегда будет метод В!



--------------------
Репутация - самое ценное, что есть у человека. Зарабатывают годы, теряют за мгновение.
70-565
MCPD Enterprise 3.5 
PM MAIL   Вверх
StepS
Дата 1.6.2007, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 26.8.2005
Где: Днепропетровск

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



Спасибо, это я все знаю  smile 
У меня был вопрос про ключевое слово new в объявлении метода.
Как создаются классы я в курсе. Меня интересует имменно ключевое слово new именно в контексте приминения в объявлении метода. С override-ми я тоже знаком и знаю как они работют  smile 

Вопрос про скрытие методов наследуемыми классами.

PM MAIL ICQ   Вверх
archeg
Дата 1.6.2007, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

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



Модификатор new только для удобства чтения кода. С MSDN:
Код

Hiding members without the use of the new modifier is allowed, but generates a warning.

new в C# используется в 3-х случаях:
1) Operator
Код

Class1 o  = new Class1();

Код

Used to create objects and invoke constructors. 

2) Modifier
Код

public class BaseC 
{
    public int x;
    public void Invoke() {}
}
public class DerivedC : BaseC
{
    new public void Invoke() {}
}


Код
When used as a modifier, the new keyword explicitly hides a member inherited from a base class. Hiding an inherited member means that the derived version of the member replaces the base-class version. Hiding members without the use of the new modifier is allowed, but generates a warning. Using new to explicitly hide a member suppresses this warning, and documents the fact that the derived version is intended as a replacement

3) Constraint
Код

class ItemFactory<T> where T : new()
{
    public T GetNewItem()
    {
        return new T();
    }
}

Код

The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor. 


Это сообщение отредактировал(а) archeg - 1.6.2007, 12:05


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
adLucem
Дата 1.6.2007, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 17.4.2007
Где: Украина, Донецк

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



new (не полиморфное поведение) в объявлении метода, который скрывает метод базового класса используется только для синтаксического подтверждения понимания того что вы делаете и дополняет слово override (полиморфное поведение).
PM MAIL ICQ   Вверх
StepS
Дата 1.6.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 26.8.2005
Где: Днепропетровск

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



Ок. Я понял, тогда объясните что имелось ввиду под : "может быть вызван не правильный метод" без использования new. Это, кстати из книги, которая обсуждалась на этом форуме: "C# 2005 для проффесионалов".
PM MAIL ICQ   Вверх
adLucem
Дата 1.6.2007, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 17.4.2007
Где: Украина, Донецк

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



Если бы new не требовалось то:

Код

public class Base {
    public int Foo ( ) {
        return 1;
    }
}

public class Derived : Base {
    // если бы слово new не указывалось явно, 
    // то программисты могли бы расценивать это как полиморфное замещение
    public int Foo ( ) { // ошибка компилятора
        return 2;    
    }
}


Код

Base obj = new Derived ( );
Console.WriteLine ( obj.Foo ( ) ); // выводится единица

PM MAIL ICQ   Вверх
StepS
Дата 1.6.2007, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 26.8.2005
Где: Днепропетровск

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



ну и что... теперь ставим ключевое слово:
Код

public class Base {
    public int Foo ( ) {
        return 1;
    }
}
public class Derived : Base {
    // если бы слово new не указывалось явно, 
    // то программисты могли бы расценивать это как полиморфное замещение
    public new int Foo ( ) { // ошибка компилятора
        return 2;    
    }
}


Код

Base obj = new Derived ( );
Console.WriteLine ( obj.Foo ( ) ); // ТОЖЕ выводится единица


не пойму, что твой пример показыват ?? кроме как вызов методов идет из типа объекта, а не объекта-типа.

Добавлено через 1 минуту
т.е. как написал archeg это для удобвства использования ?
PM MAIL ICQ   Вверх
ivashkanet
Дата 1.6.2007, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

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



Причем сдесь удобство использования? Это ключевое слово очень важно. 

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

В реализации .Net, если ты определил в наследнике метод с той же самой сигнатурой, что и в базовом но без модификаторов new или override, это равнозначно наличию модификатора new + выводится предупреждение на всякий случай.
В Java, например, все наоборот. Отсутствие модификатора говорит о том, что новый метод переопределяет (override) метод родителя.


Т.е. если ты пришел в .net из Java, то 
Цитата(StepS @  1.6.2007,  09:56 Найти цитируемый пост)
вы рискуете вызвать не тот метод
 что и сказал B]adLucem[/B].
PM MAIL WWW ICQ   Вверх
StepS
Дата 1.6.2007, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 26.8.2005
Где: Днепропетровск

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



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

Код

 A a = new B();
 a.M1();


будет всегда отрабатывать метод M1 из класса А, используешь ты new в определении метода (дочернего типа В) или нет !!!!

Цитата

Причем сдесь удобство использования? Это ключевое слово очень важно.

можешь объяснить с примерами как оно важно или дать ссылку где это описано плз?
PM MAIL ICQ   Вверх
stab
Дата 1.6.2007, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

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



Цитата(StepS @  1.6.2007,  19:52 Найти цитируемый пост)
будет всегда отрабатывать метод M1 из класса А, используешь ты new в определении метода (дочернего типа В) или нет !!!!


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

в данном контексте ключевое слово new решает такую проблему:

Код

Derived obj = new Derived ( );
obj.Foo();


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


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
adLucem
Дата 1.6.2007, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 17.4.2007
Где: Украина, Донецк

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



Цитата(StepS @  1.6.2007,  13:52 Найти цитируемый пост)
который без new вызывает

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

Цитата

For more information, see the following sections in the C# Language Specification:

10.2.2 The new modifier


Что вам еще - MSDN пересказать?


Цитата(StepS @  1.6.2007,  13:52 Найти цитируемый пост)
можешь объяснить с примерами как оно важно или дать ссылку где это описано плз? 


Пример из MSDN:
Цитата

In this example, a nested class hides a class with the same name in the base class. The example demonstrates using the new modifier to eliminate the warning message, as well as accessing the hidden class members by using their fully qualified names.

  Copy Code 
Код

// cs_modifer_new_nested.cs
// Using the new modifier with nested types.
using System;
public class BaseC 
{
    public class NestedC 
    {
        public int x = 200;
        public int y;
    }
}

public class DerivedC : BaseC 
{
    // Nested type hiding the base type members.
    new public class NestedC   
    {
        public int x = 100;
        public int y; 
        public int z;
    }

    static void Main() 
    {
        // Creating an object from the overlapping class:
        NestedC c1  = new NestedC();

        // Creating an object from the hidden class:
        BaseC.NestedC c2 = new BaseC.NestedC();

        Console.WriteLine(c1.x);
        Console.WriteLine(c2.x);   
    }
}




Это сообщение отредактировал(а) adLucem - 1.6.2007, 16:20
PM MAIL ICQ   Вверх
ivashkanet
Дата 1.6.2007, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

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



Цитата(StepS @  1.6.2007,  14:52 Найти цитируемый пост)
ivashkanet можешь привести пример, который без new вызывает из ротительского класса метод (при ссылке на родителя), а с присутствием new вызывает метод из дочернего класса (опять же при ссылке на родителя)

Нет, конечно, это бред.

Цитата(StepS @  1.6.2007,  14:52 Найти цитируемый пост)
можешь объяснить с примерами как оно важно или дать ссылку где это описано плз? 

Какие примеры? Что ты хочешь понять?

Цитата(StepS @  1.6.2007,  14:52 Найти цитируемый пост)
будет всегда отрабатывать метод M1 из класса А, используешь ты new в определении метода (дочернего типа В) или нет !!!!

ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, 
............................................................................................................................................................................................................................................ 
ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, ДА, 

Так оно и будет. Но дело не в этом.

new означает: "Я, Иванов Иван Иванович, полностью сознаю, что этот метод с такой сигнатурой используется так же в базовом классе, так же я заявляю, что определенный мною метод никоем образом не согласуется с методом базового класса , поэтому при полиморфизме прошу использовать метод базового класса."
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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