抽象基本クラスを使用する方法は 2 つあります。
抽象オブジェクトを特殊化していますが、すべてのクライアントはその基本インターフェイスを介して派生クラスを使用します。
設計内のオブジェクト内の重複を除外するために抽象基本クラスを使用しており、クライアントは独自のインターフェイスを介して具象実装を使用しています。
1の解決策 - 戦略パターン

最初の状況の場合、実際には、派生クラスが実装している抽象クラスの仮想メソッドによって定義されたインターフェイスがあります。
これを実際のインターフェイスにして、抽象クラスを具象クラスに変更し、コンストラクターでこのインターフェイスのインスタンスを取得することを検討する必要があります。派生クラスは、この新しいインターフェイスの実装になります。

これは、新しいインターフェイスのモック インスタンスを使用して以前の抽象クラスをテストし、新しいパブリック インターフェイスを介してそれぞれの新しい実装をテストできることを意味します。すべてがシンプルでテスト可能です。
ソリューション フォー 2
2 番目の状況の場合、抽象クラスはヘルパー クラスとして機能しています。

含まれている機能を見てみましょう。この重複を最小限に抑えるために、操作されているオブジェクトにそれらのいずれかをプッシュできるかどうかを確認してください。まだ何か残っている場合は、具体的な実装がコンストラクターで受け取り、基本クラスを削除するヘルパー クラスにすることを検討してください。

これも、単純で簡単にテストできる具体的なクラスにつながります。
原則として
複雑なオブジェクトの単純なネットワークよりも、単純なオブジェクトの複雑なネットワークを優先します。
拡張可能でテスト可能なコードの鍵は、小さな構成要素と独立した配線です。
更新: 両方の混合物を処理するには?
これらの両方の役割を実行する基本クラスを持つことが可能です...つまり、パブリック インターフェイスがあり、保護されたヘルパー メソッドがあります。この場合、ヘルパー メソッドを 1 つのクラス (シナリオ 2) に分解し、継承ツリーを戦略パターンに変換できます。
基本クラスが直接実装するメソッドがいくつかあり、他のメソッドが仮想であることがわかった場合でも、継承ツリーを戦略パターンに変換できますが、責任が正しく調整されていないことを示す良い指標としても捉えます。リファクタリングが必要です。
Update 2 : 踏み台としての抽象クラス (2014/06/12)
先日abstractを使った場面があったので、その理由を探ってみたいと思います。
設定ファイルには標準フォーマットがあります。この特定のツールには、すべてその形式の 3 つの構成ファイルがあります。設定ファイルごとに厳密に型指定されたクラスが必要だったので、依存性注入を通じて、クラスが関心のある設定を要求できるようになりました。
これを実装するには、設定ファイルの形式を解析する方法を知っている抽象基本クラスと、同じメソッドを公開するが設定ファイルの場所をカプセル化する派生クラスを用意しました。
3 つのクラスをラップした "SettingsFileParser" を作成し、基本クラスに委譲してデータ アクセス メソッドを公開することもできました。私はまだこれを行わないことを選択しました。これは、他の何よりも多くの委譲コードを含む 3 つの派生クラスにつながるためです。
ただし...このコードが進化するにつれて、これらの各設定クラスの消費者がより明確になります。各設定のユーザーは、いくつかの設定を要求し、何らかの方法で変換します (設定はテキストであるため、それらを数値に変換するオブジェクトでラップする場合があります)。これが発生したら、このロジックをデータ操作メソッドに抽出し、それらを厳密に型指定された設定クラスにプッシュします。これにより、設定の各セットのより高いレベルのインターフェイスにつながり、最終的には「設定」を扱っていることに気付かなくなります。
この時点で、厳密に型指定された設定クラスは、基になる「設定」の実装を公開する「ゲッター」メソッドを必要としなくなります。
その時点で、パブリック インターフェイスに設定アクセサー メソッドを含めたくありません。そのため、このクラスを変更して、設定パーサー クラスから派生させるのではなく、カプセル化します。
したがって、Abstract クラスは、現時点では委譲コードを回避する方法であり、後で設計を変更することを思い出させるためのコード内のマーカーです。私はそれにたどり着かないかもしれないので、それはしばらく続くかもしれません...コードだけがそれを知ることができます。
これは、「静的メソッドなし」や「プライベートメソッドなし」など、どのルールにも当てはまります。それらはコードの臭いを示しています...そしてそれは良いことです。見落としていた抽象化を探し続け、その間に顧客に価値を提供し続けることができます。
保守可能なコードが谷に住んでいる風景を定義するこのようなルールを想像します。新しい動作を追加すると、コードに雨が降るようになります。最初は、着地する場所に配置します..次に、リファクタリングして、すべてが谷に行き着くまで、優れた設計の力が動作をプッシュできるようにします。