2014-12-05 4 views
0

Я кодирую классическую игру Sokoban. У меня есть класс с именем «Склад», который представляет собой склад и класс с именем «WarehouseItem», который является базовым классом для предметов, принадлежащих складу.Логическая проблема между двумя классами

Я хотел следующие операции можно:

Dim wh as Warehouse 
Dim whItem as WarehouseItem 

wh.Add(whItem) 
wh.Remove(whItem) 
whItem.Warehouse = wh 
whItem.Warehouse = Nothing 

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

Class Warehouse 
    ... 
    Items as List(Of WarehouseItem)   

    Sub Add(item as WarehouseItem) 
     Items.Add(item) 
     wh.Warehouse = wh // Recursive call 
    End Sub 
    ... 
End Class 

Class WarehouseItem 
    ... 
    Private mWarehouse as Warehouse 

    Property Warehouse As Warehouse 
     ... 
     Set(wh As Warehouse) 
      mWarehouse = wh 
      mWarehouse.Add(me) // Recursive call 
     End Set 
    End Property 
    ... 
End Class 

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

+0

Это очень распространенная проблема начинающих в объектно-ориентированном программировании в целом и не зависит от разработки игр. – Philipp

ответ

0

Проблема в том, что каждая функция всегда будет вызывать другую. Вы должны проверять, чтобы увидеть, если WarehouseItem уже был добавлен в Items в Warehouse, и только добавить его, если это не так:

Class Warehouse 
    ... 
    Items as List(Of WarehouseItem)   

    Sub Add(item as WarehouseItem) 
     If Not Items.Contains(item) Then 
      Items.Add(item) 
      wh.Warehouse = wh 
     End If 
    End Sub 
    ... 
End Class 

Вы должны убедиться, что WarehouseItem перегружает оператор для Равных , в противном случае содержит не даст вам то, что вы хотите:

Class WarehouseItem 
... 
    Public Overloads Function Equals(other As WarehouseItem) As Boolean _ 
     Implements IEquatable(Of WarehouseItem).Equals 
     If other Is Nothing Then 
      Return False 
     End If 
     Return (Me.Id.Equals(other.Id)) //or whatever makes warehouseparts equal 
    End Function 

Теперь, если вы звоните Warehouse.Add (WarehouseItem) в первый раз, это добавит его и вызовите WarehouseItem.Set (Warehouse). Warehouse.Add затем вызывается снова, но ничего не будет делать, поскольку элемент уже добавлен.

2

У вас бесконечная рекурсия. A вызывает B, а B вызывает A, который снова вызывает B ... Вам нужно как-то разбить это. Как правило, вы делаете WarehouseItem.Warehouse частным (или, по крайней мере, только для чтения), поэтому люди всегда должны пройти Warehouse.Add, чтобы добавить WarehouseItem. Это означает, что вам больше не нужно переопределять Set для WarehouseItem.Warehouse, поэтому он больше не будет звонить Warehouse.Add.

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