virtual предполагает наличие реализации, которую при необходимости/желании можно переопределить.
abstract вы обязаны реализовать в неабстрактном классе. никакой реализации по умолчанию не предполагается.
т.е если virtual- то предполагает какую - то реализацию уже в момент создания, а потом уже могу переопределять. А abstract я могу не реализовывать в момент создания, но обязан переопределить. так?