-7

I need to subclass a real class, I mean not an abstract class. I need a new behavior.

namespace MyProgram
{
    public class ParentClass
    {
        public int Calc(int a)
        { 
            return a + this.Cal();
        }

        public int Cal()
        {
            return 2;
        } 
    }

    public class ChildClass : ParentClass
    {
        public int Cal()
        {
            return 1;
        }
    }   
}   

In the main program, I tried the following:

ChildClass childClass = new ChildClass();
int a = childClass.calc(3);

The value of a, however, is 5, and not 4.

JonH
  • 32,732
  • 12
  • 87
  • 145
  • 1
    What awful naming convention so confusing code. – JonH Aug 28 '17 at 20:07
  • [Knowing When to Use Override and New Keywords](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords) – Paul Abbott Aug 28 '17 at 20:09
  • Fixed naming convention... – JonH Aug 28 '17 at 20:10
  • 5
    Did you observe an warnings when you compiled your code, by any chance? Did you *read* those warnings? – Jon Skeet Aug 28 '17 at 20:11
  • The most difficult tasks in programming: cache invalidation and naming things. Take the time to read about coding style, it will make your code far nicer and easier to read – Sten Petrov Aug 28 '17 at 20:11
  • This has to be a duplicate right?I just can't find anything with `how to override method` or something similar.... – Igor Aug 28 '17 at 20:12
  • Just declaring `public int cal()` in the child class, will not "connect" that method in the child class with the original method in the parent class. Instead it will create a `new` method which just happens to "hide" the original method in some cases. Instead you should use `override` in the child class method, and `virtual` in the parent class method. In C#, only methods that are marked with the word `virtual` can be overridden. – Jeppe Stig Nielsen Aug 28 '17 at 20:12
  • Possible duplicate [In C#, if a class or a method is not marked as sealed or virtual, what is it?](https://stackoverflow.com/q/24146110/1260204) – Igor Aug 28 '17 at 20:15
  • People: if you downvote that much it would be nice, if you comment why you did that so the OP can correct his/her mistakes. The way he describes his problem is not perfectly clear, thats true, but the provided code samples pretty much show, that he is either missing the new keyword, or he is missing a virtual and override keyword. – Tobias Theel Aug 28 '17 at 20:16
  • 2
    @TobiasTheel: I downvoted due to a lack of research. The code provided generates a warning, and the warning is well documented. Diligence in research would have meant that the question was not needed. – Jon Skeet Aug 28 '17 at 20:27
  • @JonH I know you changed the code in the question to follow C# capitalization conventions, but isn't it usually recommended to not edit the actual code? – Tot Zam Aug 28 '17 at 20:47

2 Answers2

4

You need to mark the cal() method as virtual in parentclass and override it in childclass.

namespace MyProgram
{
    public class ParentClass
    {
        public int calc( int a)
        { 
            return a + this.cal();
        }

        public virtual int cal()
        {
            return 2;
        } 
    }

    public class childClass : ParentClass
    {
        public override int cal() // same name and firm 
        {
            return 1;
        }
    }
}
AlexDrenea
  • 7,981
  • 1
  • 32
  • 49
1

Basically, when you define a method like public int cal() { return 2; } you are saying that it's going to be like this forever. In this way, when it is called inside the class (return a + this.cal()) it does not even try to find a different implementation. If you want to have the option to override the implementation, you must mark the method as virtual. In the child class, when you want to override the method, you must explicit say it's a override using the override keyword.

namespace MyProgram
{
    public class ParentClass
    {
        public int calc( int a) { return a + this.cal(); }
        public virtual int cal() { return 2; }
    }

    public class childClass : ParentClass
    {
        public override int cal()
        {
            return 1;
        }
    }
}
  • Two things. 1) I am pretty sure you did not mean to include `virtual` in your method definition in your 1st line. That mistake makes the whole sentence rather confusing for a noob. 2) An override class *could* also change it's own behavior by using the `new` keyword. – Igor Aug 28 '17 at 20:23
  • Thanks! I did not, indeed. Fixed! The `new` keyword is the default behavior (basically just hides warnings). The override class using the `new` keyword only works when the method is invoked in the context of this class. For instance, using the `new` keyword in the example above the result of `childClass child = new childClass; child.cal();` would result 1, as expected. But, `ParentClass parent = new childClass; parent.cal();` will result 2. – Leonardo Nunes Aug 28 '17 at 20:43
  • thanks to all, yes my English is very poor, I understand that I can't overwrite a non virtual or abstract method. https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/inheritance – Mario Carrera Aug 29 '17 at 09:21