У меня только один основной вопрос:
public class virtualTest
{
public virtual void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public override void vTest()
{
Console.WriteLine("Derived Class");
}
}
Здесь я использовал функцию переопределения с функцией vTest()
Но если i:
public class virtualTest
{
public void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public void vTest()
{
Console.WriteLine("Derived Class");
}
}
удаляет виртуальные и переопределяет ключевые слова из соответствующих мест, а затем работает код.
Как это может быть возможным?
Или тогда, что использование переопределения и виртуального (целая функция переопределения), если код работает нормально без виртуального и переопределить???
Редактировать:
Мой метод, через который я звоню выше классов
static void Main(string[] args)
{
derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
objderivedVirtualTest.vTest();
virtualTest objvirtualTest = new virtualTest();
objvirtualTest.vTest();
Console.ReadLine();
}
Как пояснил qwr, основное различие в терминах ООП - полиморфизм. Это означает, что если вы получаете доступ к классу, который переопределяет базовый элемент с помощью ссылки базового типа, вызов, который вы выполняете для элемента с возможностью переопределения, перенаправляется на переопределение.
В случае класса, который скрывает/скрывает базовый элемент, вызов не перенаправляется, а метод базового класса выполняется.
Итак, учитывая:
class Base
{
public virtual void OverrideMe()
{
Console.WriteLine("I'm the base");
}
}
class Derived : Base
{
public override void OverrideMe()
{
Console.WriteLine("I'm derived");
}
}
class Shadowing : Base
{
public void OverrideMe()
{
Console.WriteLine("I'm shadowing");
}
}
И используя их таким образом:
var instances = new Base[] {new Base(), new Derived(), new Shadowing()};
foreach (var instance in instances)
{
instance.OverrideMe();
}
Будет производить:
Я базовый
Я получил
Я базовый
Дополнительная разница заключается в том, что в случае переопределения вы можете развить свой базовый класс, например, изменить подпись базового элемента или полностью удалить его, не изменяя его. Что в некоторых случаях может удовлетворить потребности точно, а в некоторых - не так много.
В случае переопределения вы также должны изменить подпись переопределяющего элемента, иначе ваш код не сможет скомпилироваться.
Сначала вы можете добиться полиморфизма. На секунду вы не можете.
Первый называется overriding
, второй называется hidding
или shadowing (Vb.Net)
И об этом много вопросов.
Во втором примере, возможно, вы проверите свой код следующим образом:
derivedVirtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Derived Class"
Попробуйте это, и вы увидите, что функция еще не была переопределена:
virtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Base Class"
//This will result "Dervived class" in the first one