Two Classes “A” and “B”
Class “A” has as a property a collection of Class “B”, and it manipulates properties of Class “B”
Class “A” also needs to return an instance of a specific Class “B” to the calling program (currently selected record if you will)
HOWEVER, there are two properties the Class “B” has, that I DO NOT want exposed to the calling program.
How (or can) I make selected properties “Private” to the “world”, but exposed to Class “A” only?
What you’re looking for is “friend” from C++
There’s no such thing
BUT
Put Class A and Class B in a module so they are namespaced
Add a Private interface to the module
Have class B implement it - and yes you can use private methods to satisfy an interface
Now Class A can use the private interface to manipulate Class B instances
Nothing else can
What I do is 1) make the property private or protected in B with an accessor method, then 2) use a delegate in A to get access to that method. Basically delegates and Introspection break scope. This doesn’t make it impossible for others places to get access, but not any more than there already is
Put Class A and Bi in a module, Create an interface that is private to the module that case B implements with a protected method. Nothing outside the module knows about the interface.
Ok… I read Aarons article, I read Section 5 of the user guide, and I know less now that I did 1/2 hour ago.
Everything seems centered around the statement getting two classes that don’t share a Super to do similar things
I created a Module, I moved the two classes into that Module, I added an Interface to the Module…
but am at a total loss as to what I’m supposed to to with or to that interface
Class A has a collection of B objects
right now it has code in varioius places that
array_of_B(index).xyz=true
Class B has a computed Property called XYZ where the Setter updates a local variable, and decides if certain actions should occur
Class A also needs to expose an instance of CLASS B to the calling program, BUT NOT expose XYZ (xyz is read/write, all the other properites are GETTER only),
For those computed properties you want only ClassA to see, make them private. Actually, I think you also have to make them regular methods. Then create an interface for those methods and put that in the module too. Make the interface private and add the interface to ClassB.
Now those methods in ClassB are private so anything outside the module can’t access them. But ClassA can access them through the interface, and only things in the module can see the interface.
[quote=175502:@Will Shank]For those computed properties you want only ClassA to see, make them private. Actually, I think you also have to make them regular methods. Then create an interface for those methods and put that in the module too. Make the interface private and add the interface to ClassB.
Now those methods in ClassB are private so anything outside the module can’t access them. But ClassA can access them through the interface, and only things in the module can see the interface.
MyInterface(array_of_B(index)).xyz = true
No offense Will… but “create an interface for those methods”… that seems to be the part everyone keeps telling me, but that I keep saying I don’t understand…
Oh, It’s that xyz method. So I’m seeing you want to call xyz on ClassB from ClassA only. Make an interface and put all those methods into it and then add the interface to ClassB (which already has the interface implemented )
Class ClassB
Sub xyz(assigns val As Boolean)
End Class
turns into
[code]Module MyModule
Class ClassA
Sub test()
dim b As new ClassB
MyInterface(b).xyz = true
End Sub
End Class
Private Interface MyInterface
Sub xyz(assigns val As Boolean)
End Interface
Class ClassB
Private Sub xyz(assigns val As Boolean)
End Class
End Module[/code]
*may have errors but it’s the idea as i understand it
To do this via delegates you’d define a delegate type in ClassA for each private method you want access to in ClassB. Then in ClassA (and ClassA only) you can write…
[code]dim d As MyDelegate = AddressOf objB.privateMethod
d.Invoke(params)
The syntax is definitely clunkier than an interface, but if the classes aren’t or you don’t want them to be in the same module this is a way for access. And possibly simpler if there’s only 1 or 2 methods needing access a single time.
The important thing is to use it you MUST cast to the INTERFACE as this is what gives you access to the functions the rest of the world WONT know about and CANNOT USE
the following is simply an outline of what you are trying to set up & a quick silly sample of how to use the two methods in the private interface
And FYI I’d say you should learn to use interfaces as they can be VERY useful
[code]
Module foo
private interface bar
baz() as integer
baz(assigns v as integer)
end interface
Class ClassB
implements bar
private function baz() as integer
end function
private function baz(assigns v as integer)
end function
public sub foo()
end foo
end class
Class ClassA
function getClassBList() as ClassB()
return mClassBList
end function
sub changeSomeClassBProperty
// since we know EVERY classB ISA BAR
// we can do this
// and this gives us access to the private functions defined in the interface
dim tmp as bar = mClassList(0)
tmp.baz = tmp.baz() + 123 // <<<<<<< use the interface !
end sub
property mClassBList() as ClassB
end class
Had to change the Computed Property in CLASS B to an OverLoaded Method
Then to keep the code simpler, I created a shadow overloaded method in Class A, the uses the Interface
At least it compiles, and runs… just need to see it it exposes what I want, and not what I don’t want
Thanks everyone… I really do appreciate it… (today has been stressful… my poor puppy dog had cancer surgery today )
PERFECT! works just the way I wanted…
and I learned something new… proving you CAN still teach an old dog new tricks (even if he does growl while doing so)