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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Снова я... :), наследование в классах... 
:(
    Опции темы
JaguarSmith
  Дата 19.1.2005, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Привет!

Взялся написать класс который описывает древовидные структуры... и написал... smile

описываются структуры примерно так
Код

root.add("branch1")
root.SubLevel("branch1").add
root.SubLevel("branch1").SubLevel(1).Name = "карьера и личностный рост"

root.SubLevel(3).SubLevel(6).SubLevel(1).Name = "мотивация"


Дык вот...

класс называется level (слово structure уже занято самим VB... : )

Если обьявить переменную этого класса то выражение типа
Код

dim root as new level
....
root = root.SubLevel(2) ' допустим нас интересует не всё дерево а конкретная ветвь


Является вполне допустимым и реально работает

но если создать дочерний класс(даже пустой):
Код

Public Class AnyStrucrure
   
     Inherits Level

End Class


то на попытку сделать так:

Код

dim root as new AnyStrucrure
....
root = root.SubLevel(2) ' допустим нас интересует не всё дерево а конкретная ветвь


.Net Framework ругается: Заданное приведение является недопустимым.

smile

Как это лечится? Или что я делаю не так?



Это сообщение отредактировал(а) JaguarSmith - 19.1.2005, 02:06
PM MAIL YIM   Вверх
Kurt
Дата 19.1.2005, 02:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлеченный
***


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

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



А метод в классе AnyStructure (к-й наследник) возвращает объект какого типа?
Меня терзают смутные сомнения, что все тот же level. Отсюда и несовпадение типов - Вы объекту класса AnyStructure присваиваете объект класса level.
Или я не угадал?
..
Пожалуйста, называйте топики соответственно тематике. Как написано в правилах форума, "название темы должно отбражать ее суть".. smile


--------------------
Для корабля, который не знает куда плыть, нет попутного ветра... ((С) Архимед)
...
Все знают, что это невозможно. Но случайно находится невежда, который этого не знает. Он-то и делает открытие.. ((С) А. Эйнштейн)
PM ICQ   Вверх
JaguarSmith
Дата 19.1.2005, 03:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Да Kurt Вы абсолютно правы...

А как тогда правильно организовать наследование? smile

Зы. но в пояснении к теме то я точно написал что меня интересует... smile

на всяк случай привожу текст класса level

Код

Public Class Level

   Public Name As String

   Private Has_Sublevels As Boolean
   Private Sub_Level(1) As Level
   Private SubLevels As Int16 = 0

   Private Errorlevel As Level

   Private Shared Index_Of As Int16

   Public Sub New()
       Index_Of += 1

       If Index_Of = 1 Then
           Name = "Root"
       Else
           Name = "unNamed"
       End If

       Has_Sublevels = False

   End Sub

   Public ReadOnly Property IndexOf() As Int16  ' А всего элементов класса
       Get
           Return Index_Of
       End Get
   End Property

   Public ReadOnly Property HasSublevels() As Boolean ' А есть ли подуровни?
       Get
           Return Has_Sublevels
       End Get
   End Property


   Public ReadOnly Property Items() As Int16 ' А сколько подуровней (0 если их нет)
       Get
           Return SubLevels
       End Get
   End Property


   ' Добавляем подуровень синтаксис add(имя) или add()

   Public Sub add()
       SubLevels += 1

       If SubLevels > 1 Then
           ReDim Preserve Sub_Level(SubLevels)
       End If

       Sub_Level(SubLevels) = New Level
       Sub_Level(SubLevels).Name = "empty_sublevel"

   End Sub
   Public Sub add(ByVal n As String)

       SubLevels += 1

       If SubLevels > 1 Then
           ReDim Preserve Sub_Level(SubLevels)
       End If

       Sub_Level(SubLevels) = New Level
       Sub_Level(SubLevels).Name = n

   End Sub

   ' Удаляем подуровень синтаксис Remove(индекс) или Remove(имя)
   Public Sub remove(ByVal in_int As Integer)

       If in_int <= 0 Or in_int > SubLevels Then Exit Sub

       Dim i As Int16
       If in_int < SubLevels Then

           For i = in_int To SubLevels - 1

               Sub_Level(i) = SubLevel(i + 1)

           Next

       End If

       SubLevels -= 1
       ReDim Preserve Sub_Level(SubLevels)

   End Sub
   Public Sub remove(ByVal in_str As String)
       Dim i, i2 As Int16

       For i = 1 To SubLevels
           If Sub_Level(i).Name = in_str Then

               If i < SubLevels Then

                   For i2 = i To SubLevels - 1

                       Sub_Level(i) = SubLevel(i + 1)

                   Next

               End If

               SubLevels -= 1
               ReDim Preserve Sub_Level(SubLevels)
               Exit Sub

           End If
       Next


   End Sub

   ' работаем с подуровнями

   Public Property SubLevel(ByVal in_int As Integer) As Level
       Get
           If in_int <= 0 Or in_int > SubLevels Then

               Errorlevel = New Level
               Errorlevel.Name = "ERROR!!!!"

               Return Errorlevel
           Else
               Return Sub_Level(in_int)
           End If
       End Get
       Set(ByVal Value As Level)
           If in_int > 0 And in_int < SubLevels Then
               SubLevel(in_int) = Value
           End If


       End Set
   End Property

   Public Property SubLevel(ByVal in_str As String) As Level

       Get
           Dim i As Int16

           For i = 1 To SubLevels
               If Sub_Level(i).Name = in_str Then
                   Return Sub_Level(i)
               End If
           Next

           Errorlevel = New Level
           Errorlevel.Name = "ERROR!!!!"

           Return Errorlevel

       End Get

       Set(ByVal Value As Level)
           Dim i As Int16

           For i = 1 To SubLevels
               If Sub_Level(i).Name = in_str Then
                   SubLevel(i) = Value
               End If
           Next

       End Set
   End Property


End Class



Это сообщение отредактировал(а) JaguarSmith - 19.1.2005, 03:10
PM MAIL YIM   Вверх
[Last]Wizard
Дата 19.1.2005, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я так понял, что ты хочешь в одной древовидной структуре иметь узлы, относящиеся как к классу Level, так и к классу AnyStructure (а также других наследников).

В таком случае:

В классе AnyStructure добавь функциональность, позволяющую добавлять узлы типа AnyStructyre;
При обращении к дереву проверяй тип узла:
Код
dim root1 as Level
dim root2 as AnyStructure
....
root1 = root.SubLevel(2)
if(TypeOf root1 Is AnyStructure)
   root2 = root1


PM ICQ   Вверх
JaguarSmith
Дата 19.1.2005, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Не совсем...

Я хотел создать калсс level как базовый для описания всех обьектов имеющих древовидную структуру, например дерева каталога или структуры сайтов...

Проблема в том, что каждый класс созданый на основе класса Level должен иметь свойство SubLevel относящееся к этому же классу а не к классу Level и я не очень понимаю как это реализовать не переопределяя свойство каждый раз заново(что ИМХО совсем неудобно)... smile

Есть какие-нибудь варианты? smile

Это сообщение отредактировал(а) JaguarSmith - 19.1.2005, 15:12
PM MAIL YIM   Вверх
[Last]Wizard
Дата 19.1.2005, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть такая идея: (поясню на примере)

1. Создаем универсальный интерфейс для элемента дерева:
Код
Public Interface ITreeStructure
   Property Name() As String
   Sub AddBranch(ByVal branch As ITreeStructure)
   Sub RemoveByName(ByVal name As String)
   Function GetBranchByName(ByVal name As String) As ITreeStructure
End Interface


2. Создаем абстрактный класс, где прячем нетипизирование методы интерфейса
Код
Public MustInherit Class TreeBase
   Implements ITreeStructure

   Protected _name As String
   Protected _branches As ITreeStructure()

   Public Sub New()

   End Sub

   Public Sub New(ByVal name As String)
       Me._name = name
   End Sub

   ' Модификатор доступа - private для того, чтобы спрятать метод от производных классов
   Private Sub AddBranch(ByVal branch As ITreeStructure) Implements ITreeStructure.AddBranch
       Throw New NotImplementedException
   End Sub

   ' Тоже private
   Private Function GetBranchByName(ByVal name As String) As ITreeStructure Implements ITreeStructure.GetBranchByName
       Dim i As Int32
       For i = 1 To _branches.Length
           If (_branches(i).Name = name) Then
               Return _branches(i)
           End If
       Next
       Return Nothing
   End Function

   Public Property Name() As String Implements ITreeStructure.Name
       Get
           Return _name
       End Get
       Set(ByVal Value As String)
           _name = Value
       End Set
   End Property

   Public Sub RemoveByName(ByVal name As String) Implements ITreeStructure.RemoveByName
       Dim i, i2 As Int16
       For i = 1 To _branches.Length
           If _branches(i).Name = name Then
               If i < _branches.Length Then
                   For i2 = i To _branches.Length - 1
                       _branches(i) = _branches(i + 1)
                   Next
               End If
               ReDim Preserve _branches(_branches.Length - 1)
               Exit Sub
           End If
       Next
   End Sub

End Class


3. Теперь плодим наследников от базового абстрактного класса, переопределяем нетипизированые методы типизироваными:
Код
Public Class IntegerTree
   Inherits TreeBase

   Protected _value As Int32

   Public Sub New(ByVal name As String, ByVal value As Int32)
       Me._branches = New IntegerTree() {}
       Me._name = name
       Me._value = value
   End Sub

   ' Это уже другая функция - не реализация интерфейса ITreeStructure
   ' Это её типизированая версия
   Public Sub AddBranch(ByVal branch As IntegerTree)
       ReDim Preserve _branches(_branches.Length + 1)
       _branches(_branches.Length - 1) = branch
   End Sub

   ' Это тоже другая функция
   Public Function GetBranchByName(ByVal name As String) As IntegerTree
       Return CType(Me, ITreeStructure).GetBranchByName(name)
   End Function

   Public ReadOnly Property Value()
       Get
           Return _value
       End Get
   End Property

End Class

Получаем древовидную структуру, элементы которого относятся к одному и тому же типу, в то же время наследуются от одного и того же базового класса.

Такой подход используется и в самом Framework. Например есть интерфейс IList, его реализует абстракный класс CollectionBase, в котором спрятаны нетипизированые методы интерфейса IList (Add, Remove, Contains, и др). От CollectionBase можно наследоваться, переопределяя заменяя нетипизированые методы типизироваными, и получается в итоге строго типизированая коллекция.
PM ICQ   Вверх
JaguarSmith
Дата 19.1.2005, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Огромное СПАСИБО тебе о добрый волшебник!!! smile
PM MAIL YIM   Вверх
-Mikle-
Дата 21.1.2005, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

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



Цитата(JaguarSmith @ 19.1.2005, 20:59)
Огромное СПАСИБО тебе о добрый волшебник!!!

Добавляу плус к репутации JaguarSmith. Молодец smile


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума VB .NET
diadiavova
  • Прежде чем задать вопрос, воспользуйтесь поиском: возможно Ваш вопрос уже обсуждался и на него был получен ответ.
  • Если такой же вопрос не найден, не стоит задавать свой вопрос в любую тему, создайте новую.
  • Заголовок темы должен отображать ее суть.
  • Содержание поста должно описывать проблему понятно, но в то же время, по возможности, лаконично. Сначала следует описать суть вопроса, потом можно привести пример кода, не вынуждайте других участников угадывать в чем Ваша проблема - телепатов здесь нет.
  • Будьте взаимно вежливы и дружелюбны.
  • При оформлении сообщений используйте форматирование, примеры кода заключайте в теги [CODE=vbnet][/CODE].
  • Также ознакомьтесь с общими правилами, действующими на всем форуме.
  • Если вопрос решен, не забывайте помечать тему решенной(вверху темы есть ссылка). Кроме того, если Вы хотите отблагодарить участников, оказавших помощь в решении, можно повысить им репутацию, в случае, если у Вас менее 100 сообщений в форуме и функция изменения репутации Вам недоступна, можете написать сюда.
  • Общие вопросы по программированию на платформе .NET обсуждаются здесь.
  • Литература по VB .NET обсуждается здесь.

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

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


 




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


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

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