2012-06-20 3 views
4

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

class Figure { 
    public virtual void Draw() { 
     Console.WriteLine("Drawing Figure"); 
    } 
} 

Это наследующий класс:

class Rectangle : Figure 
{ 
    public int Draw() 
    { 
     Console.WriteLine("Drawing Rectangle"); 
     return 42; 
    } 
} 

Компилятор будет жаловаться, что прямоугольник в «Draw» скрывает Жеребьевка фигуры , и просит добавить либо ключевое слово new, либо override. Просто добавить new решает эту проблему:

class Rectangle : Figure 
{ 
    new public int Draw() //added new 
    { 
     Console.WriteLine("Drawing Rectangle"); 
     return 42; 
    } 
} 

Однако Figure.Draw имеет пустое тип возвращаемого значения, Rectangle.Draw возвращает Int. Я удивлен, что здесь возможны разные типы возврата ... Почему?

ответ

6

Вы действительно прочитали на new modifier?

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

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


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

Figure r = new Rectangle(); 
r.Draw(); 

Figure Затем сек Draw метод будет вызван. Возвращаемое значение не производится и не ожидается.

2

С помощью «нового» ключевого слова вы можете вызывать только int Draw из ссылки Rectangle. Не существует разрешения метода времени исполнения.

Rectangle r = new Rectangle(); 
Figure f = r; 
f.Draw(); // calls the void method Figure.Draw 
int x = r.Draw(); // calls the int method Rectangle.Draw 
+0

Для меня эти 4 строки показывают, как с ума все это. Кажется, это по дизайну, предназначенное новым ключевым словом ... спасибо! – Konerak

4

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

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

+0

бокс - это другая вещь. Тип значения не существует, поэтому здесь нет бокса. –

+0

Вы правы, но это простой поворот фразы. Производный тип является ссылкой, как если бы он был меньшим типом в иерархии наследования. – Tejs

4

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

class Base 
{ 
    public virtual void A() 
    { 
     Console.WriteLine("Base::A"); 
    } 
    public virtual void B() 
    { 
     Console.WriteLine("Base::B"); 
    } 
} 

class Derived : Base 
{ 
    public override void A() 
    { 
     Console.WriteLine("Derived::A"); 
    } 
    public new int B() 
    { 
     Console.WriteLine("Derived::B"); 
    } 
} 

Так,

Base obj = new Derived(); 
obj.A(); 
obj.B(); 

выведет

Derived::A 
Base::B 
Смежные вопросы