none
Overriding a property

    Question

  • I'm trying to replace the functionality of a property in a class with something different

    I have

    Module Module1
        Sub Main()
            MsgBox((New class1).name)
        End Sub
    End Module

    Class class1
        Overridable Function name() As String
            Return "AAA"
        End Function
    End Class
    Class class2
        Inherits class1
        Overrides Function name() As String
            Return "BBB"
        End Function
    End Class

    This returns "AAA". How should I code to get class1.name to be "BBB" (note: I can't  change the real Class1)

    Sunday, March 26, 2017 11:48 AM

Answers

  • iLens,

    Here's an example of what I meant:

    Option Strict On Option Explicit On Option Infer Off Public Class Form1 Private Sub Form1_Load(sender As System.Object, _ e As System.EventArgs) _ Handles MyBase.Load Dim instance1 As New MyBaseClass Dim instance2 As New MyDerivedClass MessageBox.Show(String.Format("Instance1: {0}{1}Instance2: {2}", _ instance1.Example, vbCrLf, instance2.Example)) Stop End Sub End Class Public Class MyBaseClass Public ReadOnly Property Example As String Get Return "Base Class" End Get End Property End Class Public Class MyDerivedClass Inherits MyBaseClass Public Shadows ReadOnly Property Example As String Get Return "My Derived Class" End Get End Property End Class



    "A problem well stated is a problem half solved.” - Charles F. Kettering

    • Marked as answer by iLens Sunday, March 26, 2017 10:43 PM
    Sunday, March 26, 2017 10:19 PM

All replies

  • Try the following:

    Public Class BaseClass
    
        Public Overridable Property theProperty As String
            Get
                Return "AAA"
            End Get
            Set(value As String)
    
            End Set
        End Property
    End Class
    
    Public Class DerivedClass
        Inherits BaseClass
    
        Public Overrides Property theProperty As String
            Get
                Return "BBB"
            End Get
            Set(value As String)
    
            End Set
        End Property
    
    End Class


    Lloyd Sheen

    • Proposed as answer by dbasnett Sunday, March 26, 2017 5:24 PM
    Sunday, March 26, 2017 1:41 PM
  • You should write ‘New class2’, or:

       Dim c As class1

       c = New class2

       MsgBox(c.name)

    Sunday, March 26, 2017 4:38 PM
  • You cannot override a property in a Class which is not overridable. That is exact the reason of encapsulation. 


    Despite that SQLQuy shows in my perception the right way of overriding properties is his sample in my opinion very quick and dirty based on VB2002 but not complete and can give wrong ideas. 

    Here an in my idea more clean way. 

    Public Class SenselessClass
        Public Overridable ReadOnly Property theProperty As String
            Get
                Return "AAA"
            End Get
        End Property
    End Class
    
    Public Class DerivedClass
        Inherits SenselessClass
        Public Overrides ReadOnly Property theProperty As String
            Get
                Return "BBB"
            End Get
        End Property
    End Class


    Success
    Cor


    Sunday, March 26, 2017 4:54 PM
  • It still returns "AAA" - please test your answer before posting.
    Sunday, March 26, 2017 4:55 PM
  • This too returns ""AAA" from MsgBox((New SenselessClass).theProperty)
    Sunday, March 26, 2017 5:02 PM
  • It seems you're replying to yourself, which one is still returning AAA?

    Success
    Cor

    Sunday, March 26, 2017 5:04 PM
  • Both!
    Sunday, March 26, 2017 5:09 PM
  • Yes of course, you use the base class.

    Did you not read what I wrote about trying to do what you wrote?

     

    Success
    Cor

    Sunday, March 26, 2017 5:10 PM
  • Strange, 

    Be aware this is in fact not an answer on your question. 

    You simply cannot override a not overridable property.  There is a person in this forum who marks replies from others as answer because I wrote that it is different. 

    I get BBB

    Module Module1
        Sub Main()
            Dim x As New DerivedClass
            Console.WriteLine(x.theProperty)
            Console.ReadLine()
        End Sub
    End Module
    Public Class SenselessClass
        Public Overridable ReadOnly Property theProperty As String
            Get
                Return "AAA"
            End Get
        End Property
    End Class
    
    Public Class DerivedClass
        Inherits SenselessClass
        Public Overrides ReadOnly Property theProperty As String
            Get
                Return "BBB"
            End Get
        End Property
    End Class


    Success
    Cor

    Sunday, March 26, 2017 5:30 PM
  • You are using dim x as new derivedClass. I wanted to say dim x as new senslessClass to avoid having to change all the other references to senselessClass

    let me try and make it absolutely clear...

    in this case, every time I write senselessClass.theProperty I want to actually invoke derivedClass.theProperty BECAUSE I have loads more properties in senselessClass and they are accessed loads of times from many applications AND in most of the applications that use the class I need senselessClass.theProperty invoked but in one application I need the functionality of derivedClass

    I guess I just can't do it - but if not, what's Overidable for? 

    Sunday, March 26, 2017 6:52 PM

  • This returns "AAA". How should I code to get class1.name to be "BBB" (note: I can't  change the real Class1)

    No offense meant but that makes no sense.

    If you can't change Class1 then that's that; it'll never return something different than what it was designed for.

    Creating a derived class doesn't change the base class, obviously, so I'm not sure what the purpose of Class2 is? Did I misunderstand?

    ***** EDIT *****

    Also, please reword your question. This has nothing to do with a property - you're asking a method, not a property.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    Sunday, March 26, 2017 8:16 PM
  • ... but if not, what's Overidable for? 

    That pretty much sums up the confusion: Overridable is intended for the derived classes, not the base class:

    https://msdn.microsoft.com/en-us/library/zcfd2sa9.aspx


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, March 26, 2017 8:24 PM

  • This returns "AAA". How should I code to get class1.name to be "BBB" (note: I can't  change the real Class1)

    No offense meant but that makes no sense.

    If you can't change Class1 then that's that; it'll never return something different than what it was designed for.

    Creating a derived class doesn't change the base class, obviously, so I'm not sure what the purpose of Class2 is? Did I misunderstand?

    ***** EDIT *****

    Also, please reword your question. This has nothing to do with a property - you're asking a method, not a property.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    I understood that the whole purpose of overriding was to change the behaviour of the base class - otherwise what use is it? I meant I can't change the code of the base class (class1).

    You ask me to reword the question.... my initial example was with a function, but the first reply changed change it to a property - the behaviour would be the same in both cases.

    Sunday, March 26, 2017 9:20 PM
  • This was in my first reply

    You cannot override a property in a Class which is not overridable. That is exact the reason of encapsulation. 


    Success
    Cor

    Sunday, March 26, 2017 9:20 PM
  • I understood that the whole purpose of overriding was to change the behaviour of the base class - otherwise what use is it? I meant I can't change the code of the base class (class1).

    No - the base class is what it is. I do understand the confusion, though I've never thought about it.

    There's a school of thought (Jon Skeet) that goes like this: "All classes should either be abstract or sealed." That's my paraphrasing, not a quote, but that's the idea at least. I don't really agree with that, but I do understand the "why" behind it.

    At any rate, the base class isn't editable. If it were, that would make for a real mess down the line. ;-)

    *****

    It's not any of my business but why not set up your own class if you want it to do something differently?


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, March 26, 2017 9:29 PM
  • "it's not any of my business but why not set up your own class if you want it to do something differently?"

    because the class has about 25 properties and 20 methods - and I just want one property to behave differently


    Sunday, March 26, 2017 9:41 PM
  • "it's not any of my business but why not set up your own class if you want it to do something differently?"

    because the class has about 25 properties and 20 methods - and I just want one property to behave differently


    I'd guess IO.FileInfo, but I know that's not the one because it's sealed.

    If the property is set as Overridable, then create a derived class, override and use it. If it's not then - not a great solution - but are you familiar with Shadowing?


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, March 26, 2017 9:46 PM
  • iLens,

    Worth a bit to read:

    https://msdn.microsoft.com/en-us/library/ms172785.aspx

    and

    https://msdn.microsoft.com/en-us/library/c4swkw24.aspx

    In that last one, look specifically at "Shadowing By Inheritance". That's what I meant.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, March 26, 2017 9:55 PM
  • iLens,

    Here's an example of what I meant:

    Option Strict On Option Explicit On Option Infer Off Public Class Form1 Private Sub Form1_Load(sender As System.Object, _ e As System.EventArgs) _ Handles MyBase.Load Dim instance1 As New MyBaseClass Dim instance2 As New MyDerivedClass MessageBox.Show(String.Format("Instance1: {0}{1}Instance2: {2}", _ instance1.Example, vbCrLf, instance2.Example)) Stop End Sub End Class Public Class MyBaseClass Public ReadOnly Property Example As String Get Return "Base Class" End Get End Property End Class Public Class MyDerivedClass Inherits MyBaseClass Public Shadows ReadOnly Property Example As String Get Return "My Derived Class" End Get End Property End Class



    "A problem well stated is a problem half solved.” - Charles F. Kettering

    • Marked as answer by iLens Sunday, March 26, 2017 10:43 PM
    Sunday, March 26, 2017 10:19 PM
  • OK Thanks

    (I understand the difference between shadowing and overriding but in my case they have the same effect)

    I'm now convinced that I can't do what I want to do using inheritance, so Ill have to find another way.

    Again, may thanks, Frank

    Sunday, March 26, 2017 10:43 PM
  • OK Thanks

    (I understand the difference between shadowing and overriding but in my case they have the same effect)

    I'm now convinced that I can't do what I want to do using inheritance, so Ill have to find another way.

    Again, may thanks, Frank


    I'm glad it helped. :)

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, March 26, 2017 10:45 PM

  • I guess I just can't do it - but if not, what's Overidable for? 

    It is for what you are trying to do.  In the one application that you want the derived class just change the instances of the base class to the derived class. see Inheritance

    You have something like this

    Class BaseClass 'can't be changed
        Public Overridable Function Name() As String
            Return "AAA"
        End Function
    
        Public Function SomeFunction() As Boolean
            Return True
        End Function
    End Class
    
    Class BaseClassDerived : Inherits BaseClass
        Public Overrides Function Name() As String
            Return "BBB"
        End Function
    End Class

    In most of your apps you are doing something like this

            Dim foo As New BaseClass
            Debug.WriteLine(foo.Name)
            Debug.WriteLine(foo.SomeFunction)

    In one of your apps you want the functionality of the derived class, so do this

            Dim foo As New BaseClassDerived
            Debug.WriteLine(foo.Name)
            Debug.WriteLine(foo.SomeFunction)

    That seems to do what you want, which is to change the behavior of one method.  It will mean that in this one app that you change all of the references from the base class to the derived class.


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.



    • Edited by dbasnett Monday, March 27, 2017 10:21 AM
    Monday, March 27, 2017 10:16 AM
  • In the question from the OP

    (note: I can't  change the real Class1)

    But it seems nobody wants to read that and start telling to change the real Class


    Success
    Cor

    Monday, March 27, 2017 10:18 AM
  • In the question from the OP

    (note: I can't  change the real Class1)

    But it seems nobody wants to read that and start telling to change the real Class


    Success
    Cor


    Most of the replies, and even the OP and yourself, were all using inheritance.  I only found one mention of replacing the base class.

    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.


    • Edited by dbasnett Monday, March 27, 2017 10:25 AM
    Monday, March 27, 2017 10:24 AM

  • I guess I just can't do it - but if not, what's Overidable for? 

    It is for what you are trying to do.  In the one application that you want the derived class just change the instances of the base class to the derived class. see Inheritance

    You have something like this

    Class BaseClass 'can't be changed
        Public Overridable Function Name() As String
            Return "AAA"
        End Function
    
        Public Function SomeFunction() As Boolean
            Return True
        End Function
    End Class
    
    Class BaseClassDerived : Inherits BaseClass
        Public Overrides Function Name() As String
            Return "BBB"
        End Function
    End Class

    In most of your apps you are doing something like this

            Dim foo As New BaseClass
            Debug.WriteLine(foo.Name)
            Debug.WriteLine(foo.SomeFunction)

    In one of your apps you want the functionality of the derived class, so do this

            Dim foo As New BaseClassDerived
            Debug.WriteLine(foo.Name)
            Debug.WriteLine(foo.SomeFunction)

    That seems to do what you want, which is to change the behavior of one method.  It will mean that in this one app that you change all of the references from the base class to the derived class.


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.




    If there are a lot of references to the base class in the one app that you want to use the derived class you can use find and replace(stating the obvious I know ;)

    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.

    Monday, March 27, 2017 11:22 AM

  • I guess I just can't do it - but if not, what's Overidable for? 

    It is for what you are trying to do. 

    No. It's not for what he was trying to do:

    He was trying to modify the base class itself, even though he can't change the base class.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Monday, March 27, 2017 1:23 PM
  • I guess I just can't do it - but if not, what's Overidable for? 

    It is for what you are trying to do. 

    No. It's not for what he was trying to do:

    He was trying to modify the base class itself, even though he can't change the base class.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Not to be pedantic ;) but it was what the OP was trying to do, just not how they wanted to do it, '...was trying to modify the base class itself, ...'.   

    Didn't understand why the OP was confused since we all said pretty much the same thing.


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.

    Monday, March 27, 2017 4:20 PM

  • Not to be pedantic ;) but it was what the OP was trying to do, just not how they wanted to do it, '...was trying to modify the base class itself, ...'.   

    Didn't understand why the OP was confused since we all said pretty much the same thing.


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.

    I agree but the reason that he was getting confused was because of this (from the OP):

    "I understood that the whole purpose of overriding was to change the behaviour of the base class - otherwise what use is it? I meant I can't change the code of the base class (class1)."

    *****

    He ended up accepting that he was to use the derived class, but he was thinking that by creating a derived class, he could then cause the base class to behave differently.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Monday, March 27, 2017 4:25 PM