I have a class called ObjectArray, which mimics the regular array syntax (Append, Insert, Remove, IndexOf, Operator_Subscript, etc.). And I have a subclass of ObjectArray called WindowArray.
[code]Class ObjectArray
Public Sub Append(obj As Object)
…
Class WindowArray Inherits ObjectArray
Private Sub Append(obj As Object)
Public Sub Append(win As Window)
…
Dim arr As New WindowArray()
arr.Append(Window1)[/code]
On the last line I get a compiler error: “There is more than one item with this name and it’s not clear to which it refers.”
Why is the super class’s Append method considered by the compiler, when the subclass has set its scope to private? Look at this code:
Dim arr As New WindowArray()
arr.Append(New Timer)
The second line will not compile, which is correct. So the compiler doesn’t consider the same method of the superclass. But why does the compiler go after the overridden superclass’s method in the case of the argument being a window?
[quote=193853:@Eli Ott]Ok, but then this should compile too and thereby use the Append method of the superclass but it doesn’t:
Dim arr As New WindowArray()
arr.Append(New Timer)[/quote]
On the contrary, it’s clear why this bit of code fails to compile. WindowArray.Append(obj as Object) overrides the superclass method of the same signature, and its visibility is private. Thus it is not legal for the code above. That leaves WindowArray.Append(win as Window), and it’s clear why this method doesn’t work.
What would compile is the following code:
Dim arr as ObjectArray = New WindowArray()
arr.Append(New Timer)[/quote]
In this case, the compiler sees only the the method ObjectArray.Append(obj as Object), which is okay.
Oddly Joe & I just had this conversation related to another report about a “bug” like this.
I think the upshot was you can’t, by overriding a method in a subclass and changing the scope, affect the supers scope or visibility.
You can as long as no other public overloaded method exists. Because overriding and setting the scope to protected or private makes it of course impossible to use that method. I seems in my amateurish knowledge of compiler construction that the compiler first checks for overloaded methods and then for the scope, while maybe it should be the other way around.
It would be very helpful if this was possible as it would make it possible to create type-safe subclasses. It works when ObjectArray is an abstract class as Append() is not public. But in the above case it would be great to have ObjectArray as a concrete class.
Perhaps the real problem here is making WindowArray a subclass of ObjectArray. It looks like you’re attempting to implement contravariant parameter typing, and that does not play well with overloading.
You’re right. What I want to achieve is type safety. The easiest would have been to go with regular arrays of objects. I have come far with extension methods like:
Sub Sort(Extends arr() As Object, sd() As SortDescriptor)
Sub Filter(Extends arr() As Object, p As Predicate)
Function FilteredArray(Extends arr() As Object, p As Predicate) As Auto
That way I would have the maximum of type safety, because I could create any object array I want and use it like this:
Dim windows() As Window
windows.Sort(Array(New SortDescriptor("Title", True), New SortDescriptor("Width", True))
Since in my methods I want to keep some state (for example the current sort), I would need to store a WeakRef to the array. This is not possible as the upcasting to arr() As Object gives you a new array on each call of Sort. So I went back to the above solution, but it is difficult to get the maximum of type-safety the way inheritance works. The only true way is to have dozens and dozens of array classes (without inheriting from ObjectArray), and copy-paste the code all over the place.
Unfortunately, copy-paste is the only working approach for Xojo at this time. I’ve worked on these sorts of things off and on over the years. Xojo support for collections has long been primitive, and is unlikely to improve much. I wrote a plugin some time ago to supply an alternative, but it’s never made it past my computer.