2016-02-03 5 views
1

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

У меня есть три класса:

abstract GameObjectBase 
{ 

} 

и производные от являются:

public Gamespace: GameObjectBase 
{ 
    private bool containsItem; 
} 

И:

public GameWall: GameObjectBase 
{ 
} 

(Очевидно, что эти классы содержат больше данных, методы и конструкторы).

Я создал массив из этих объектов, как этот

private GameObjectBase[,] _labyrinthArray = new GameObjectBase[10,10]; 

я затем заполнить указанный массив с Gamespaces и Gamewalls. Но когда я обращаюсь к объекту Gamespace в массиве, поле containsItem недоступно из-за ссылки на объект типа типа GameObjectBase.

Очевидно, я мог бы положить containsItem в GameObjectBase и сделать его доступным оттуда, но это не подходит для моего подхода к ООП. Единственное другое решение, которое я нашел, - это прямое задание объекта, заданного Gamespace.

Это кажется довольно грубым и подверженным ошибкам. Есть ли лучшее решение для этого?

+0

Как вы получаете доступ к объекту (коду) игрового пространства? – DanielVorph

+0

Что случилось с нажатием на базу в этой ситуации? Совершенно прекрасно, что реализация Gamewall всегда возвращает false, если она вызвана – jglouie

ответ

0

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

public interface ICanContainItem 
{ 
    bool ContainsItem { get; } 
} 

public class Gamespace : GameObjectBase, ICanContainItem 
{ 
    private bool _containsItem; 

    public bool ContainsItem 
    { 
     get { return _containsItem; } 
     private set { _containsItem = value; } 
    } 
} 

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

var gameObject = _labyrinthArray[i,j]; //i,j defined elsewhere 
var mayContainItem = gameObject as ICanContainItem; 
if (mayContainItem != null) 
{ 
    var itemExists = mayContainItem.ContainsItem; 
    //mayContainItem.ContainsItem = false; //<-- fails because there's no setter 
} 
Смежные вопросы