Quando você precisar de uma parte da turma a ser implementada. O melhor exemplo que usei é o padrão método de modelo .
public abstract class SomethingDoer
{
public void Do()
{
this.DoThis();
this.DoThat();
}
protected abstract void DoThis();
protected abstract void DoThat();
}
Assim, você pode definir as etapas que serão executadas quando Do () for chamado, sem conhecer as especificidades de como elas serão implementadas. Classes derivadas devem implementar os métodos abstratos, mas não o método Do ().
Os métodos de extensões não satisfazem necessariamente a parte "deve ser uma parte da classe" da equação. Além disso, iirc, os métodos de extensão não podem (parecer) ser algo além de público no escopo.
editar
A pergunta é mais interessante do que eu originalmente acreditava. Após um exame mais aprofundado, Jon Skeet respondeu a uma pergunta como esta em SO em favor de usando interfaces + métodos de extensão. Além disso, uma possível desvantagem está usando a reflexão em relação a uma hierarquia de objetos projetada dessa maneira .
Pessoalmente, estou tendo problemas para ver o benefício de alterar uma prática comum no momento, mas também vejo poucas ou nenhuma desvantagem em fazê-lo.
Deve-se notar que é possível programar desta maneira em muitos idiomas através de classes Utility. As extensões fornecem apenas o açúcar sintático para fazer com que os métodos pareçam pertencer à classe.