16

I've started to learn some C# and I came accross a troubling matter: the virtual methods. Is there any motivation for such keyword to be necessary?

A simple polymorphism in Java does not requre virtual keyword to work, even the Override adnotations are optional:

package figures;

public class Figures {
    public static void main(String[] args) {
        Figure figure = new Figure();
        Circle circle = new Circle();
        Triangle triangle = new Triangle();
        Figure []arrayOfFigures = {figure, circle, triangle};
        for (int i = 0; i < 3; i++){
            arrayOfFigures[i].introduceYourself();
        }
    }
}

class Figure {
    public void introduceYourself(){
        System.out.println("I am just a figure.");
    }
}

class Circle extends Figure {
    @Override
    public void introduceYourself() {
        System.out.println("I am a circle.");
    }
}

class Triangle extends Figure {
    @Override
    public void introduceYourself() {
        System.out.println("I am a triangle.");
    }
}

While in C# the same example requires both virtual and override keywords to work:

namespace Figures
{
    class Figures
    {
        static void Main(string[] args)
        {
            Figure figure = new Figure();
            Circle circle = new Circle();
            Triangle triangle = new Triangle();
            Figure[] arrayOfFigures = { figure, circle, triangle };
            for (int i = 0; i < 3; i++)
            {
                arrayOfFigures[i].IntroduceYourself();
            }
        }
    }
}

    class Figure
    {
        public virtual void IntroduceYourself()
        {
            System.Console.WriteLine("I am just a simple figure.");
        }
    }

    class Circle : Figure
    {
        public override void IntroduceYourself()
        {
            System.Console.WriteLine("I am a circle.");
        }
    }

    class Triangle : Figure
    {
        public override void IntroduceYourself()
        {
            System.Console.WriteLine("I am a triangle.");
        }
    }

Usually there is a motivation to introduce some keywords to languages. As C# was created after Java and many other object oriented languages, I Wonder if there was a reason to introduce obligatory (for polymorphism to work) virtual and override keywords?

3yakuya
  • 2,622
  • 4
  • 25
  • 40
  • In Java, all methods are virtual by default, that's why you *don't* need them there. – Luiggi Mendoza Feb 14 '14 at 16:15
  • Then why is it not the same in C#? Of course, different language - different rules, but for a new language there should be some motivation behind it, I thought. – 3yakuya Feb 14 '14 at 16:16
  • I'd guess because it's a performance hit to call methods through a vtable, so methods that can be overridden should be explicitly marked as such.. – Mike Christensen Feb 14 '14 at 16:16
  • Maybe the C# designers prefer to let the programmers choose whose methods can be overridden and whose not freely. In Java, unless you mark the method as `final`, any subclass can override its behavior, which can lead to problems if you don't understand what you're doing (which happens with junior programmers). But all this is my opinion, though. – Luiggi Mendoza Feb 14 '14 at 16:18
  • Why would you want methods to be virtual by default? That could just cause more issues than anything else. To me it is better to specify something is virtual rather than having to say every property is not virtual. – TyCobb Feb 14 '14 at 16:19
  • I guess you use overriding methods in derivated classes for polymorphism, and if you do not intend your class to be overriden you declare it final. Why would you want your method not to work with polymorphism? I still see not quite a reason for it. – 3yakuya Feb 14 '14 at 16:20
  • Polymorphism does not mean every single method or property needs to be overridden. It almost sounds like you want an interface instead if you are overriding everything. – TyCobb Feb 14 '14 at 16:23
  • If you use the same name for a method in a derived class and do not intend its functionality to be somehow adequate to the functionality of its parrent method then this would be a fatal name choice leading to confusion. If you declare a method with the same method as in parrents class I can't imagine a situation when you do not want it to be used in polymorphism – 3yakuya Feb 14 '14 at 16:24
  • @LuiggiMendoza Someone deleted their answer before I had a chance to respond to your comment. Private methods can't be overridden because they aren't inherited. http://stackoverflow.com/a/2000156/3224483 – Rainbolt Feb 14 '14 at 16:24
  • @John right, you can hide it but not override it. I was confusing it with accessing to private methods in sub classes, which you can. – Luiggi Mendoza Feb 14 '14 at 16:33
  • As far as I see it now: this mechanism gives us a Chance to create a class that allows only some of its methods to be overriden, while ones not marked `virual` become final. Is it correct? Is there a way to achieve the same thing in Java? – 3yakuya Feb 14 '14 at 16:34
  • 1
    @Byakuya By writing a Java class with the inverse modifiers on methods - anything not marked `virtual` in C# would have no modifier in Java, anything marked `final` in Java would have no modifier in C#. – Preston Guillot Feb 14 '14 at 16:40
  • Can you mark a single method as final in java (and not making whole class final)? – 3yakuya Feb 14 '14 at 16:41
  • 1
    http://stackoverflow.com/questions/5547663/java-final-method-what-promises-it – Preston Guillot Feb 14 '14 at 16:43

1 Answers1

19

In Java, methods are virtual by default. In C#, they are not, and must be marked as virtual in order for polymorphism to work.

It's a difference in philosophy. Java's philosophy is that a virtual-by-default approach makes it easy for you to extend classes at-will. C#, on the other hand, figures that you should only have virtual functions when you explicitly say you need them (so a function can be overriden only if explicitly allowed to.) There's a slight performance consideration, since a virtual function requires an additional level of indirection.

3yakuya
  • 2,622
  • 4
  • 25
  • 40
Matt Kline
  • 10,149
  • 7
  • 50
  • 87
  • What @3yakuya is asking is why C#, a newer language than Java, bothers us with the requirement of using the virtual keyword. The scenario where maybe you will want to invoke a father's method version instead of child's one, when the instance is declared as father, and instanced as child, is really very rare in real world applications. That's why Java implements polymorphism from scratch, with no requirement to use any keyword to do it. – Jose Ramon Garcia Oct 31 '19 at 12:09
  • 1
    My point is that C# was created by people coming from Borland, and they used a lot of principles from Object Pascal, as they created previously Borland Delphi. Object Pascal had the same requirement with the virtual keyword, and more or less the same use of the virtual method table. – Jose Ramon Garcia Oct 31 '19 at 12:11