2015-10-14 2 views
3

Скажем, у меня есть базовый класс Enemy и производный класс под названием Ogre.Базовый класс = новый производный класс. Как это работает?

В чем разница между созданием экземпляра эти два способа:

Enemy newOgre = new Ogre(); 

Ogre newOgre = new Ogre(); 
+1

лучше использовать интерфейс 'IEnemy', а не базовый класс Enemy'. Если вы не создадите новых врагов в качестве базового класса, интерфейс будет более подходящим. – wudzik

+0

. Между этими творениями не так много различий, кроме нового объекта с точностью до Enemy, будет предоставляться только интерфейс базового класса. – Mykola

+0

Вы * не * создаете их по-разному. Вы делаете что-то другое с объектами, которые вы создаете одинаково (а именно, сохраняете их по-другому). – Servy

ответ

4

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

Первый оператор просто присваивает созданный экземпляр переменной типа Enemy. Второй присваивает ему переменную типа Ogre.

Так у вас есть две переменные разных типов, указывающие на объекты же типа, т.е. Ogre.

Переменная (что находится на левая сторона знака равенства), определяет только то, что вы можете получить от объекта. Например, если класс Ogre имеет метод, который не унаследован от Enemy, то с использованием переменной Enemy вы не сможете получить к ней доступ.

Обратите внимание: переменная не влияет на поведение объекта. Например, если Ogre переопределяет метод, определенный в Enemy, который выполняет что-то другое. Вызов этого метода на примере Ogre, используя переменную типа Enemy вызовет перекрытый метод в Ogre будет вызван, а не один в Enemy,

Для примера рассмотрим эти классы:

public class Enemy 
{ 
    public virtual void Test() 
    { 
     Console.WriteLine("enemy"); 
    } 
} 

public class Ogre: Enemy 
{ 
    public override void Test() 
    { 
     Console.WriteLine("ogre"); 
    } 
} 

сейчас если вы это сделаете:

Enemy enemy = new Ogre(); 

enemy.Test(); 

Консоль будет печатать «огр», а не «враг».

2

Объявляет переменную типа Enemy и ссылается на новый объект Ogre. Другой объявляет переменную типа Ogre и ссылается на новый объект Ogre.

Некоторые различия (не исчерпывающий список):

  • Вы не можете назвать Ненаследуемые методы Ogre на переменную типа Enemy.
  • Любые виртуальные методы Enemy, которые переопределены в Ogre, будут использовать реализацию Ogre's при вызове любой переменной.
1

Здесь

Enemy newOgre = new Ogre(); 

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

6

В дополнение к ответу Якуба, в этом случае Enemy не будет содержать свойства и методы, которые имеет Ogre.

public class Enemy 
{ 
    public int Property1 { get; set; } 
    public int Property2 { get; set; } 
} 

public class Ogre : Enemy 
{ 
    public int Property3 { get; set; } 
} 

Предположим, вы наследуете Врага в вашем классе Огра. Это означает, что ваш Ogre будет эффективно содержать 3 свойства: 1,2 и 3.

В вашем примере вы назначаете Ogre на тип Enemy. Тип Enemy не содержит «Property3», и поэтому вы не сможете работать с расширенным классом «Ogre» в объекте Enemy.

//This will work 
Ogre newOgre = new Ogre(); 
int newInt = newOgre.Property3; 

//This wont. 
Enemy newOgre = new Ogre(); 
int newInt = newOgre.Property3; 
1

Предположим, ваш класс Enemy выглядит следующим образом:

public class Enemy 
{ 
    public void Attack() { } 
    public void Move() { } 
} 

и ваш Ogre класс как это:

public class Ogre : Enemy 
{ 
    public void OgreSmash() { } 
} 

С переменной Enemy вы бы только доступ к Attack() и Move() но а не OgreSmash() с переменной Ogre, у вас будет доступ к методам базового и производного классов.

Смежные вопросы