Хорошо, допустим, у вас есть базовый класс, и этот базовый класс сам по себе является производным от другого класса.
public class Bar : Foo
{
virtual public int SomeProperty { get; set; }
}
Что означает виртуальное ключевое слово, так это то, что в классе, производном от Bar, вы можете переопределить SomeProperty, чтобы изменить его поведение:
public class Baz : Bar
{
private int thisInt;
override public int SomeProperty
{
get { return thisInt; }
set
{
if(value < 0)
{
throw new ArgumentException("Value must be greater than or equal to zero.");
}
thisInt = 0;
}
}
}
Пояснение: Когда используется объект типа Baz, вызывается его версия SomeProperty, если тип не приведен к типу Bar. Если вы определите SomeProperty в Baz как виртуальный, классы, производные от Baz, также могут переопределить его (на самом деле, это может потребоваться - не могу вспомнить сразу же).
Дальнейшее уточнение: Абстрактный метод не имеет реализации; когда вы добавляете один в свой класс, вы также должны пометить класс как абстрактный, и вы не можете создавать новые экземпляры этого класса, например:
MyAbstractType m = new MyAbstractType();
Виртуальные члены, с другой стороны, могут иметь реализацию (например, SomeProperty, выше), поэтому вам не нужно отмечать абстрактный класс, и вы можете создавать его экземпляры.