Resumo : neste tutorial, você aprenderá como usar o modificador virtual C# e como usá-lo para definir um método virtual.
Introdução ao modificador virtual C#
Na herança , uma classe (subclasse) herda de outra classe (classe base). Se um membro da subclasse tiver o mesmo nome da classe base, o membro da subclasse substitui (ou oculta) o membro da classe base.
Por exemplo:
class Person
{
public string Name { get; set; }
public string Introduce() => $"Hi, I'm {Name}.";
}
class Employee : Person
{
public string JobTitle { get; set; }
public new string Introduce() => $"Hi, I'm {Name}. I'm a {JobTitle}.";
}
Linguagem de código: C# ( cs )
Neste exemplo, o Introduce()
método da Employee
classe oculta o Introduce()
método da Person
classe. O new
modificador comunica explicitamente nossa intenção.
No entanto, se quiser que um membro da subclasse substitua o membro com o mesmo nome na classe base, você precisará:
- Primeiro, use o
virtual
modificador na declaração do membro da classe base - Segundo, use o
override
modificador na declaração do membro da subclasse.
Por exemplo:
class Person
{
public string Name { get; set; }
public virtual string Introduce() => $"Hi, I'm {Name}.";
}
class Employee : Person
{
public string JobTitle { get; set; }
public override string Introduce() => $"Hi, I'm {Name}. I'm a {JobTitle}.";
}
Linguagem de código: C# ( cs )
Neste exemplo:
- Use a
virtual
palavra-chave para modificar a declaração doIntroduce()
método naPerson
classe. - Use a
override
palavra-chave para modificar a declaração doIntroduce()
método naEmployee
classe.
Diferenças entre modificadores novos e de substituição
Vamos dar um exemplo para entender a diferença entre os modificadores new e override.
O método de substituição
O override
modificador instrui o compilador C# a usar a última implementação definida de um método; mesmo se você chamar o método em uma referência da classe base. Por exemplo:
class Person
{
public string Name { get; set; }
public virtual string Introduce() => $"Hi, I'm {Name}.";
}
class Employee : Person
{
public string JobTitle { get; set; }
public override string Introduce() => $"Hi, I'm {Name}. I'm a {JobTitle}.";
}
Linguagem de código: C# ( cs )
// Program.cs
var employee = new Employee()
{
Name = "John Doe",
JobTitle = "C# Developer"
};
Console.WriteLine(employee.Introduce());
Person person = employee;
Console.WriteLine(person.Introduce());
Linguagem de código: C# ( cs )
Saída:
Hi, I'm John Doe. I'm a C# Developer.
Hi, I'm John Doe. I'm a C# Developer.
Linguagem de código: texto simples ( texto simples )
Neste exemplo, quando chamamos o método Introduce(), o compilador executa o método definido na classe Employee conforme o esperado.
E quando chamamos o método Introduce() em uma instância da classe Person, o compilador também executa o método Introduce() definido na classe Employee.
O novo método
O new
modificador instrui o compilador C# a usar o método definido na subclasse. Entretanto, se você chamar o método em uma instância da classe base, o compilador usará o método definido na classe base, e não aquele definido na subclasse. Por exemplo:
class Person
{
public string Name { get; set; }
public string Introduce() => $"Hi, I'm {Name}.";
}
class Employee : Person
{
public string JobTitle { get; set; }
public new string Introduce() => $"Hi, I'm {Name}. I'm a {JobTitle}.";
}
Linguagem de código: C# ( cs )
// Program.cs
var employee = new Employee()
{
Name = "John Doe",
JobTitle = "C# Developer"
};
Console.WriteLine(employee.Introduce());
Person person = employee;
Console.WriteLine(person.Introduce());
Linguagem de código: C# ( cs )
Saída:
Hi, I'm John Doe. I'm a C# Developer.
Hi, I'm John Doe.
Linguagem de código: texto simples ( texto simples )
Quando chamamos o Introduce()
método em uma instância da Employee
classe, o compilador executa o método definido na Employee
classe. Esse comportamento é o mesmo do exemplo do método de substituição.
Porém, quando chamamos o Introduce()
método em uma instância da Person
classe, o compilador executa o método definido na Person
classe. Esta é a diferença.
Chamando um método da classe base
Para chamar explicitamente um método de uma classe base de uma subclasse, você usa a base
palavra-chave.
Por exemplo, o seguinte ilustra como chamar o Introduce()
método da Person
classe no Introduce()
método da Employee
classe:
class Person
{
public string Name { get; set; }
public virtual string Introduce() => $"Hi, I'm {Name}.";
}
class Employee : Person
{
public string JobTitle { get; set; }
public override string Introduce() => $"{base.Introduce()} I'm a {JobTitle}.";
}
Linguagem de código: C# ( cs )
Neste exemplo, referenciamos o Introduce()
método da Person
classe no método Introduce() da classe Employee usando a base
palavra-chave:
base.Introduce()
Linguagem de código: CSS ( css )
Se não fizéssemos isso, teríamos um método recursivo porque o Introduce()
método chamaria a si mesmo.
Resumo
- Use o
virtual
modificador C# para um membro na classe base se desejar substituí-lo no membro com o mesmo nome das subclasses. - Use a palavra-chave base para referenciar explicitamente o método em uma classe base de uma subclasse.