Given what you're trying to accomplish, and with the sample code you posted, VB.NET will not let you do this.
Ordinarily, you can declare a property in VB.NET like so:
Public Class qwqwqw
Public Property xyz() As String
Get
Return ""
End Get
Private Set(ByVal value As String)
//
End Set
End Property
End Class
Basically marking the overall property as public, but giving a more restrictive scope to the setter (or getter).
The main problem in your case is the MustInherit (i.e. abstract) base class. Since the property you're defining in there is marked as MustOverride, you can't provide a default implementation (i.e. it, too, is abstract), and this includes the "Get" and "Set" outlines, therefore, whichever "overall" scope you give to this abstract property declaration, VB.NET will force you to use this scope for both the getters and setters within derived classes.
Having the ReadOnly qualifier on the base class's property will force all derived classes and the implementations of this property to also be ReadOnly. Leaving off the ReadOnly qualifier still will not work, since whatever scope you give to the abstract property will be the scope you must apply to both the setters and getters within derived implementations.
For example:
Public MustInherit Class Parent
Public MustOverride Property Foo() As String
End Class
Public Class ReadOnlyChild
Inherits Parent
Public Overrides Property Foo() As String
Get
//
End Get
Private Set(ByVal value As String)
//
End Set
End Property
End Class
(Note the Private scoping on the setter). This will not work as VB.NET is insisting that since you're overriding the base classes property, your entire property must have the same scope as the property you're overriding (in this case, public).
Attempting to make the base class's abstract property protected will not work either, since you would then be required to implement the property at the same level of scoping as it's declared in your base class (i.e. protected). Ordinarily, when not overriding a base class's abstract definition with a specific scoping level, you can give a getter or setter a more restrictive scoping level, but you can't give it a less restrictive scoping level.
Therefore:
Public MustInherit Class Parent
Protected MustOverride Property Foo() As String
End Class
Public Class ReadOnlyChild
Inherits Parent
Protected Overrides Property Foo() As String
Public Get
//
End Get
Set(ByVal value As String)
//
End Set
End Property
End Class
(Note the public scoping on the getter). Doesn't work either due to the public scope being less restrictive than the overall property scope of protected, and moreover, not of the same scoping level as defined on the base class's abstract property declaration.
If the design of your classes is as you mention in your question, I personally, would go with a "java-style" getter and setter methods as they can then be declared separately with their own scoping levels.