Должен ли я использовать методы получения и установки для следующего класса? - PullRequest
1 голос
/ 22 октября 2019

Итак, мне нужен класс, который имеет такую ​​структуру:

Obj
    .Name
        .value as string
        .tag as string
    .Id
        .value as string
        .tag as string

С этими value и tag переменными-членами, доступными извне. Поэтому я попытался написать класс с использованием типов.

'make a "RefPairType" Type for value/tag pair 
Public Type RefPairType
    value As String
    tag as String
End Type

'Make member vars of the class based on RefPairType 
Private Name As RefPairType
Private Id As RefPairType

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

Private Sub Document_New()
    'create an exemplar of aforementioned Class called "Class1"
    Dim client As New Class1

    'try to assign value to the member:
    client.Name.value = "foo"
    'COMPILE ERROR: method or data member not found
End Sub

И если я сделаю эти типы или переменные-члены открытыми, я получу ошибки:

'Cannot define a public user-defined type within an object module

или

'constants, ... user-defined types not allowed as public members of object modules

Это делаетзначит я должен сделать getters / setters для каждой переменной-члена класса? Что если мой класс в 10 раз больше? Как мне сделать геттеры и сеттеры для вложенных членов, таких как object.name.tag?

1 Ответ

2 голосов
/ 22 октября 2019

A Type - это не класс или объект. Это немного больше, чем кусок памяти с определенной раскладкой. Если у вас есть что-то, на что у вас есть экземпляр, который вы можете New поднять, то вам нужен не Type, а модуль класса. Определяемые пользователем типы имеют много ограничений, из-за которых с ними довольно сложно работать, по крайней мере, с точки зрения ООП.

В этом случае вы хотите, чтобы ValueTagPair или что-то могло выглядеть следующим образом - обратите внимание, как Private Type все еще может использоваться для хранения состояния экземпляра в одном частном поле (this):

Option Explicit
Private Type TPair
    Value As String 
    Tag As String
End Type
Private this As TPair

Public Property Get Value() As String
    Value = this.Value
End Property

Public Property Let Value(ByVal rhs As String)
    this.Value = rhs
End Property

Public Property Get Tag() As String
    Tag = this.Tag
End Property

Public Property Let Tag(ByVal rhs As String)
    this.Tag = rhs
End Property

Теперь вы можете объявить любую переменную As ValueTagPair и использовать ее как таковую, включаятип возврата члена Property в другом классе.

Option Explicit
Private Type TSomething
    Name As ValueTagPair
    Id As ValueTagPair
End Type
Private this As TSomething

Public Property Get Name() As ValueTagPair
    Set Name = this.Name
End Property

Public Property Get Id() As ValueTagPair
    Set Id = this.Id
End Property

Private Sub Class_Initialize()
    Set this.Name = New ValueTagPair
    Set this.Id = New ValueTagPair
End Sub

Теперь предположим, что это класс Something, теперь мы можем сделать это:

Dim thing As Something
Set thing = New Something
thing.Name.Tag = "name-tag"
thing.Name.Value = "name-value"
thing.Id.Tag = "id-tag"
thing.Id.Value = "id-value"

Если вам нужнобыть в состоянии сделать Set thing.Name = New ValueTagPair, тогда вам нужно будет выставить Public Property Set член для свойства Name.

Означает ли это, что я должен делать геттеры / сеттеры длякаждая переменная-член класса?

Да. Открытые члены класса определяют интерфейс этого класса, а интерфейс определяет, как можно использовать объект. Если Class1.Name не отображается на интерфейсе Class1, то он не существует;использование с ранней привязкой не будет компилироваться, а вызовы с поздней привязкой (т.е. вызовы, сделанные против Object или Variant) будут взорваны во время выполнения с ошибкой 438.

Что если мой класс в 10 раз больше?

Тогда у него, вероятно, слишком много обязанностей. Объекты с ясной и четко определенной целью обычно не выполняют 20 задач.

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