Ключевое слово "shadows" по сути говорит: "Если кто-либо обращается к этому объекту, знает, что он принадлежит к этому типу или одному из его потомков, используйте этот элемент; в противном случае используйте базовый". Простейшим примером этого может быть базовый класс ThingFactory, который включает метод «MakeNew», который возвращает Thing, и класс CarFactory, производный от ThingFactory, чей метод «MakeNew» всегда возвращает Thing, который будет иметь производный тип Car. Если подпрограмма знает, что ThingFactory, которой она владеет, происходит, в частности, CarFactory, то она будет использовать затененный CarFactory.MakeNew (если он существует), который может указать тип возвращаемого значения как Car. Если подпрограмма не знает, что ее ThingFactory на самом деле является CarFactory, она будет использовать не затененный MakeNew (который должен вызывать внутренний защищенный переопределяемый метод MakeDerivedThing).
Кстати, еще одно хорошее использование теней - запретить доступ производных классов к защищенным методам, которые больше не будут работать. Невозможно просто скрыть член от производных классов, кроме назначения нового, но можно запретить производным классам делать что-либо с защищенным членом, объявив новый защищенный пустой класс с этим именем. Например, если вызов MemberwiseClone для объекта сломает его, можно объявить:
Protected Shadows Class MemberwiseClone
End Class
Обратите внимание, что это не нарушает принципы ООП, такие как принцип замещения Лискова, поскольку это применимо только в тех случаях, когда производный класс может использоваться вместо объекта базового класса. Если Foo и Bar наследуются от Boz, метод, который принимает параметр Boz, может быть законно передан в Foo или Bar. С другой стороны, объект типа Foo будет знать, что его объект базового класса имеет тип Boz. Это никогда не будет чем-то еще (например, это гарантированно не будет Баром).