Respostas:
Bem, herança ...
suponha que você tenha estas classes:
class A {
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A{
public new int Foo() { return 1;} //shadow
public override int Bar() {return 1;} //override
}
então quando você chama isso de:
A clA = new A();
B clB = new B();
Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1
//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1
Suponha que você tenha uma classe base e use a classe base em todo o seu código em vez das classes herdadas e use shadow, ela retornará os valores que a classe base retorna em vez de seguir a árvore de herança do tipo real do objeto.
Espero que esteja fazendo sentido :)
Sombreamento é, na verdade, linguagem VB para o que chamaríamos de ocultar em C #.
Freqüentemente, ocultação (sombreamento em VB) e sobreposição são mostrados como resposta de Stormenet .
Um método virtual é mostrado para ser substituído por uma subclasse e chamadas para esse método, mesmo no tipo de superclasse ou de dentro do código da superclasse, chamarão a implementação de substituição da subclasse.
Em seguida, um método concreto é mostrado (um não marcado como virtual ou abstrato) sendo escondido usando o new palavra chave ao definir um método com uma assinatura idêntica na subclasse. Nesse caso, quando o método é chamado no tipo de superclasse, a implementação original é usada, a nova implementação está disponível apenas na subclasse.
No entanto, o que muitas vezes é esquecido é que também é possível ocultar um método virtual.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new void DoStuff() { //new implementation }
}
B b = new B();
A a = b;
b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.
Observe no exemplo acima, DoStuff torna-se concreto e não pode ser sobrescrito. No entanto, também é possível usar as palavras virtual- newchave e juntas.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new virtual void DoStuff() { //new implementation }
}
class C : B
{
public override void DoStuff() { //replacement implementation }
}
C c = new C();
B b = c;
A a = b;
c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.
Observe que, apesar de todos os métodos envolvidos serem virtuais, a substituição em C não afeta o método virtual em A porque o uso de newem B oculta a implementação de A.
Edit: Foi observado nos comentários a esta resposta que o texto acima pode ser perigoso ou pelo menos não particularmente útil. Eu diria que sim, pode ser perigoso e estaria lá fora se fosse útil.
Em particular, você pode ter todos os tipos de problemas se também alterar os modificadores de acessibilidade. Por exemplo:-
public class Foo
{
internal Foo() { }
protected virtual string Thing() { return "foo"; }
}
public class Bar : Foo
{
internal new string Thing() { return "bar"; }
}
Para um herdeiro externo de Bar, Fooa implementação de Thing () permanece acessível e substituível. Tudo legal e explicável de acordo com as regras do tipo .NET, a menos que seja pouco intuitivo.
Publiquei esta resposta para aprofundar a compreensão de como as coisas funcionam, não como uma sugestão de técnicas que podem ser usadas livremente.
Acho que a principal diferença é que com o sombreamento, você essencialmente reutiliza o nome e simplesmente ignora o uso da superclasse. Com a substituição, você está alterando a implementação, mas não a acessibilidade e a assinatura (por exemplo, tipos de parâmetro e retorno). Consulte http://www.geekinterview.com/question_details/19331 .
Shadowing é um conceito VB.NET. Em C #, Shadowing é conhecido como Hiding. Ele oculta o método da classe derivada. Isso é feito usando a palavra-chave 'novo'.
A palavra-chave Override é usada para fornecer uma implementação completamente nova de um método de classe base (que é marcado como 'Virtual') na classe derivada.
Basicamente, se você tiver algo como abaixo,
Class A
{
}
Class B:A
{
}
A a = new B();
Qualquer método que você chamar no objeto 'a' será feito no tipo de 'a' (aqui o tipo é 'A') Mas se você implementar o mesmo método na classe B que já está presente na classe A, o compilador irá dar-lhe um aviso para usar uma palavra-chave "Novo". Se você usar "Novo", o aviso desaparecerá. Fora isso, não há diferença entre usar "Novo" ou não usá-lo na classe herdada.
Em algumas situações, você pode precisar chamar um método da classe de referência que a instância específica mantém naquele momento, em vez de chamar um método no tipo de objeto. No caso acima, a referência que contém é 'B', mas o tipo é 'A'. Portanto, se você quiser que a chamada do método aconteça em 'B', use Virtual e override para fazer isso.
Espero que isto ajude...
Daniel Sandeep.
Se houver um caso em que você não pode alterar o conteúdo de uma classe, digamos A, mas você deseja usar seus alguns métodos junto com você tem um método cujo nome é comum, você pode usar sua própria implementação de método pela newpalavra - chave.
O ponto crucial é usar que tanto a referência quanto o objeto devem ser do mesmo tipo.
class A
{
public void Test()
{
Console.WriteLine("base");
}
}
class B : A
{
public new void Test()
{
Console.WriteLine("sub");
}
public static void Main(string[] args)
{
A a = new A();
B aa = new B();
a.Test();
aa.Test();
}
}