I am testing the valentina database api. However, my problem is more related to a general class and inheritance question. I use two classes from the api:

VDatabase (the database object reference)
VTable (the table object reference)

To get an instance of a table there is only one way to go: Call the VDatabase.Table method with the table name as parameter.
Valentina now suggests to subclass the VDatabase and VTable classes.


Class myDatabase As VDatabase
Class customers As VTable

The new inherited customers object could now contain specific code for data manipulation (like adding calculated fields etc.).

The problem is now: How do I get a customers instance? If I override the “table” method in the myDatabase class, I can generate a customers instance but it doesn’t contain the table. I can call the superclasses table method of course to get a VTable instance, but since there is no way of “downcasting” it to a customer instance that wouldn’t help me.

Thanks for any advice in advance,

Of course you can downcast a VTable to Customers:

Dim custs As Customers = Customers(theVTable)

[quote=350605:@Eli Ott]Of course you can downcast a VTable to Customers:

Dim custs As Customers = Customers(theVTable)

This is unlikely to be possible in MOST cases

For instance

  1. new desktop project
  2. to Windows 1 add the Open event
  3. in the open event put
Dim c As CustomClass1 = CustomClass1( foo )
  1. add the “foo” method to Window1
Public Function foo() as Class1
   return new Class1
End Function
  1. add Class1
Class Class1
   Property untitled as integer
   Computed Property untitled1 as integer
end Class1
Class CustomClass1
 inherits Class1
   Property untitled2 as integer
   Computed Property untitled3 as integer
end Class1

run and you’ll get an illegal cast exception
This set up is intentionally made to mimic what I suspect Valentina is doing (since it cant know the subtype to return from the VDatabase.Table method call)

Subclasses can safely be cast to be the super class type (because they ARE instance of the super class type)
Super class instances are unlikely to be able to be cast to subclass types

The recommendation to subclass the type is curious because of this

I just wondered because factory classes like the VDatabase class are a common design pattern in OOP. In Terms of inheritance this seems to be a dead end though. I just wondered if I missed something here.

Thanks for the comments!

unless theres a mechanism for you to extend the factory and add new sub types to be returned I dont see how subclassing helps

as soon as you add anything that alters the subclass you’re going to get cast exceptions

[quote=350611:@Norman Palardy]Norman Palardy 11 minutes ago Xojo Inc Edited 9 minutes ago by Norman Palardy
@Eli Ott Of course you can downcast a VTable to Customers:
Dim custs As Customers = Customers(theVTable)
This is unlikely to be possible in MOST cases
I did not suggest to cast the method .Table, I suggested to cast the returned table – hence the name theVTable – as there is no other way. More explicitly:

Dim theVTable As Variant = vdb.Table(...) Dim custs As Customers = Customers(theVTable)

Did you even try this before making the suggestion ?

I’m not “casting a method”
I’d be casting the result the method returns
Which is the EXACT same thing regardless of the variant or not
Change the code I suggested to

dim v as variant = foo
Dim c As CustomClass1 = CustomClass1( v )

And you still get an illegal cast exception - going through a variant makes no difference
It doesn’t have any magic means to make a super class be a subclass instance

For exactly the reasons I outlined at the end of my post

Super class instances can NOT necessarily be cast to subclasses - there is one case where they are which is when the super & sub do NOT differ in any way so they have the EXACT same vtables memory layout etc
An then why bother having the subclass since its identical to the super ?

@Eli Ott
I think the problem here is that casting just points the compiler to the fact that an instance corresponds to a certain subclass, even if it has been originally declared as some of it’s superclasses. There is no conversion of instances taking place. As Norman pointed out the superclass cannot know about subcasses.

I guess I will write my own classes and implement the Valentina classes as properties.

I understood the OP in that he was supposed so subclass VDatabase and VTable. Then you override VDatabase.Table(name) along this:

Function VDatabaseSubclass.Table(name As String) As VTable Dim tmp As VTable = Super.Table(name) Select Case name Case "Customer" Dim cust As New VCustomer // VCustomer is a subclass of VTable cust.Prop1 = tmp.Prop1 cust.Prop2 = tmp.Prop2 ... cust.PropN = tmp.PropN Return cust Case "Employee" ... Else Return tmp End End
Then the caller can cast the result (indirectly via a Variant, Auto or VTable variable).

Quite possibly but this isn’t even remotely the same as what you suggested earlier

Subclassing just doesn’t seem as useful in this set up

It was, as I assumed it was self-evident (as he spoke about subclassing and overriding VDatabase.Table).

Apparently my “Read Forum Posters Mind” plugin has a bug

Socket failed to connect?

I should have included the following quote in my post:

… or where else could he have called New Customer()?

New YourSubclass() is needed. The only case where it wouldn’t be needed is if one could register pairs of table names with introspection’s type infos. Then the VDatabase class could return subclasses of VTable. But the Valentina API doesn’t contains something like that.