How does "new" and "virtual" work in C #?

5

Can you explain to me how they work in C #?

When I create a parent class and it has a teste() method and I want to rewrite this method in the child class, I need to use virtual and new ?

If I create:

class Veiculo {
    public void andar() { /// BLA BLA }
}

class Carro: Veiculo {
    public void andar() { /// BLUBLU }
}
  • I'm re-scheduling the walk method and it works. So what does virtual and new serve in this context?
  • What would be the difference in this case and why use virtual and override if this works the same?
  • asked by anonymous 06.09.2016 / 00:13

    2 answers

    7

    The most common is to do polymorphism so when you send the Carro class where the Veiculo class is expected, the Carro method is called instead of the Veiculo class method. In this case, virtual should be placed in Andar() of class Veiculo and override should be placed in Andar() of class Carro .

    The new modifier should rarely be used. It just informs you that you really want to create a new method that already exists in the Carro class, replacing it, but not doing polymorphism. If the method is called on an instance of Carro , then it calls its method, but if it is called on Veiculo instance, the same Veiculo method will be called.

    public class Program {
        public static void Main() {
            Veiculo a = new Carro();
            a.Andar(); //imprime Carro, mesmo que x seja do tipo Veiculo
            Carro b = new Carro();
            b.Andar(); //imprime Carro, claro, isso é fácil deduzir
            Veiculo c = new Veiculo();
            c.Andar(); //imprime Veiculo, é óbvio
            Carro2 d = new Carro2();
            d.Andar(); //óbvio que imprime Carro
            Veiculo e = new Carro2(); //aqui só esconde, não faz polimorfismo, a instância não importa
            e.Andar(); //aqui imprime Veiculo, afinal o tipo da variável é dessa classe
            Carro3 f = new Carro3();
            f.Andar(); //funciona igual, nernhuma confusão
            Veiculo g = new Carro3(); //pode estar esperando polimorfismo que não ocorrerá
            g.Andar(); //funciona igual, mas poderia não ser o que deseja
            Carro4 h = new Carro4();
            h.Andar(); //funciona igual, nernhuma confusão
            Veiculo2 i = new Carro4(); //pode estar esperando polimorfismo que não ocorrerá
            i.Andar(); //funciona igual, mas poderia não ser o que deseja
        }
    }
    public class Veiculo {
        public virtual void Andar() { WriteLine("Veiculo"); }
    }
    public class Carro : Veiculo {
        public override void Andar() { WriteLine("Carro"); }
    }
    public class Carro2 : Veiculo {
        public new void Andar() { WriteLine("Carro"); }
    }
    public class Carro3 : Veiculo {
        public void Andar() { WriteLine("Carro"); } //note o warning
    }
    public class Veiculo2 {
        public void Andar() { WriteLine("Veiculo"); }
    }
    public class Carro4 : Veiculo2 {
        public void Andar() { WriteLine("Carro"); } //note o warning
    }
    

    See running on dotNetFiddle .

    Note that the class Carro3 has problems setting the method without new after all this may be occurring unintentionally. The new is for the programmer to tell the compiler that he knows what he is doing and it is intentional to create a new version of the method.

    You can use new to hide non-virtual methods as well. I used the term hide because it is what it does. It explicitly says that you want to use this method and hide the existing one in the parent class.

    Some questions that can help you understand:

    Some are about Java, but it explains the polymorphism.

        
    06.09.2016 / 00:28
    2

    To rewrite methods use virtual and in the class that inherits override .

    Vehicle Class

    public class Veiculo {
         public virtual void Andar()
         {
             //code
         }
    }
    

    Car Class

    public class Carro: Veiculo
    {
         public override void Andar()
         {
             //code
         }
    }
    
    The new modifier has the hide / hide method that is inherited from a base class, and when this happens, the base class method is overridden. Ref link

    With both questions:

    I'm re-scheduling the walk method and it works. So what is the virtual and new in that context?

    The virtual indicates that the method can be rewritten by the other class it inherited, but if it is omitted it will work not by rewriting the method, it has a functional character. By better reading your code it is ideal and readable to be informed to the class which methods can be rewritten by giving a pattern to a development team for example. The new in turn has a character to hide the method that was inherited from the class, giving the impression of a new method or replacing the one that was inherited, although there is, I do not see much logic, exists.

    What would be the difference in this case and why use the virtual and override if this works the same?

    In the case presented it would not then be mandatory to use virtual and override ?, perhaps, since they were not informed do not follow a standard nomenclature of development and in the code would have no validity. When you tell the base class a method with the virtual modifier, in the class that receives the inheritance by typing override it shows you which methods can be rewritten and that is a great purpose when obtaining third-party codes.

    It really works and it's implicit for the compiler to make this code work, but always work on the default put virtual on the methods that need to be rewritten and override on the ones you've rewritten, the code readable and is always good practice. There is also a factor that methods can behave differently by bringing different data, so look at the links below:

    Example without informing virtual and override

    Example reporting virtual and override

    That is, the compiler will treat the different return information!

        
    06.09.2016 / 00:26