Shadowing is when a subclass defines a constant, property or enumeration (almost anything that is not an event or a method) that has the same name as a constant, property or enumeration (but not an event or a method) in the superclass. Generally the best rule is avoid using the same names for constants, properties and enumerations that the superclass has already used.
For code in the subclass things will work as you expect since scope resolution will figwill ure out it should use the one defined in the subclass. But, for code outside the subclass things get more difficult because you don’t always get what you expect.
Suppose you have a class like:
Class Foo const kDelta = 6 end class
Class Bar inherits Foo const kDelta = 66 end class
And somewhere else in you app you have code like:
dim c as Foo c = new Bar dim i as integer = c.delta
What would YOU expect the value of i to be?
Many would answer that it should be 66 since the Bar class Delta says 66. Many would be unpleasantly surprised to find that it is not. Constants, properties and many other items like enumerations, cannot be overridden like methods can because they are not virtual. Doing this is known as shadowing. This means that what is important is not the type of the instance you create using NEW but the type that is DECLARED – in the code above this is the type on the line dim C as Foo.
If you change that to say DIM C AS BAR you WILL get the result you expect, but doing that everywhere causes problems in your code becuase you can’t have polymorphic behavior.
So how to deal with this in your own code?
Don’t create code where you need shadowing to work. Shadowing will not always get you want you want or expect. If you expect properties, constants, etc. to be virtual, set your code up to make it so they are virtual using methods. A really nice aspect of Xojo is that code can’t tell if you’re accessing a property or constant or method.
Here’s what I’d suggest- it’s more work, but it’s also far safer at runtime and your code will work as you expect:
Interface Component
function Delta() as Integer end function ... I have no idea what else you'd want ... end interface Class Foo implements Component private sub Constructor() end sub function Delta() as Integer // return whatever the "generic delta" is return kGenericDelta end function private const kGenericDelta = 6 end class Class Bar inherits Foo function Delta() as Integer return kMyDelta end function private const kMyDelta = 66 end class
With this code, inheritance works as expected without the issues that shadowing brings to the table. Each subclass is a component so you can treat them all the same but they can all specialize in whatever way you need becuase they are all subclasses and using any properties of them gives you the properties of the instance not the declared type.
Still have questions about Shadowing? Ask them here or on the Xojo Forums!