Code Fix

上級

does not implement inherited abstract member の原因と直し方

abstractなメンバーを持つ基底クラスを継承したのに、そのメンバーをoverrideしていないと出るコンパイルエラーです。

エラーメッセージの読み方

Program.cs(4,7): error CS0534: 'Circle' does not implement inherited abstract member 'Shape.Area()'
Program.cs
ファイル名
4
行番号
7
列番号 — この位置でコンパイラが解析に失敗しました
CS0534
エラーコード — 検索するとMicrosoftの解説ページが見つかります
'Circle' does not implement inherited abstract member 'Shape.Area()'
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  abstract class Shape {
 2      public abstract double Area();
 3  }
 4  class Circle : Shape {
 5      public double Radius;
 6                                                                      
                                        ^
 7  }
 8  class Program {
 9      static void Main(string[] args) {
10          Circle c = new Circle { Radius = 2 };
11          System.Console.WriteLine(c.Area());
12      }
13  }
Program.cs(4,7): error CS0534: 'Circle' does not implement inherited abstract member 'Shape.Area()'

abstractなメンバーは、派生クラスで必ずoverrideして実装しなければなりません。1つでも忘れるとそのクラスはインスタンス化できません。

直し方: (空) を public override double Area() { return 3.14 * Radius * Radius; } にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  abstract class Vehicle {
 2      public abstract void Drive();
 3  }
 4  class Car : Vehicle {
 5                                                                           
                                          ^
 6  }
 7  class Program {
 8      static void Main(string[] args) {
 9          Car c = new Car();
10          c.Drive();
11      }
12  }
Program.cs(4,7): error CS0534: 'Car' does not implement inherited abstract member 'Vehicle.Drive()'

publicかoverrideのどちらかが欠けても、抽象メンバーの実装としては認められません。

直し方: (空) を public override void Drive() { System.Console.WriteLine("Driving"); } にします。

この問題を解いてみる →

パターン3

 1  abstract class Employee {
 2      public abstract decimal CalculatePay();
 3  }
 4  class Manager : Employee {
 5                                                             
                                   ^
 6  }
 7  class Program {
 8      static void Main(string[] args) {
 9          Manager m = new Manager();
10          System.Console.WriteLine(m.CalculatePay());
11      }
12  }
Program.cs(4,7): error CS0534: 'Manager' does not implement inherited abstract member 'Employee.CalculatePay()'

戻り値の型(ここではdecimal)も基底クラスの宣言と完全に一致させる必要があります。

直し方: (空) を public override decimal CalculatePay() { return 5000; } にします。

この問題を解いてみる →

パターン4

 1  abstract class Shape {
 2      public abstract double Perimeter();
 3  }
 4  class Rectangle : Shape {
 5      public double Width;
 6      public double Height;
 7                                                                         
                                         ^
 8  }
 9  class Program {
10      static void Main(string[] args) {
11          Rectangle r = new Rectangle { Width = 3, Height = 4 };
12          System.Console.WriteLine(r.Perimeter());
13      }
14  }
Program.cs(4,7): error CS0534: 'Rectangle' does not implement inherited abstract member 'Shape.Perimeter()'

abstractなメンバーはoverrideキーワードを付けて実装しないと、派生クラスをインスタンス化できません。

直し方: (空) を public override double Perimeter() { return 2 * (Width + Height); } にします。

この問題を解いてみる →

パターン5

 1  abstract class Task {
 2      public abstract bool IsDone();
 3  }
 4  class Chore : Task {
 5      public bool Done;
 6                                                    
                               ^
 7  }
 8  class Program {
 9      static void Main(string[] args) {
10          Chore c = new Chore { Done = true };
11          System.Console.WriteLine(c.IsDone());
12      }
13  }
Program.cs(4,7): error CS0534: 'Chore' does not implement inherited abstract member 'Task.IsDone()'

戻り値の型(ここではbool)も基底クラスの宣言と一致させる必要があります。

直し方: (空) を public override bool IsDone() { return Done; } にします。

この問題を解いてみる →

よくある誤解

interface-not-implementedと似ていますが、こちらはabstract classの話です。publicとoverrideの両方が揃って初めて「実装した」とみなされます。

実務での勘所

abstract classとinterfaceの使い分けの目安は、共有したいものが「状態(フィールド)や共通のロジック」を含むかどうかです。abstract classは、抽象メソッドと並行して、全ての派生クラスに共通するフィールドやコンストラクタ、すでに実装済みの通常のメソッドを持てます。派生クラスは抽象メンバーだけを実装すればよく、共通部分は継承するだけで手に入ります。純粋な「この操作ができることを保証する」という契約だけを表したいならinterface、共通の実装や状態も一緒に配りたいならabstract classを選びます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)