Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
19分59秒
C#の抽象クラスは、開発者の間でしばしば疑問が生じる基本的な概念です。 動画"C# Abstract Classes - What They Are, How to Use Them, and Best Practices"では、ティム・コーリーが抽象クラスとは何か、その使い方、ベストプラクティスについて掘り下げています。 この記事では、タイムスタンプを参照しながら、彼のビデオの要点を要約する。
ティム(0:00)は、抽象クラスはその目的、機能性、重要性の点でしばしば疑問視されると説明する。 抽象クラスとは、完全な基本クラスとインターフェースの中間のもので、機能的には両者の中間に位置するものである。
(0:59)では、Timがデモ・アプリケーションを通して抽象クラスを説明します。 アプリケーションは、コンソールアプリケーションと、データベース操作をシミュレートする2つのデータアクセスクラスを含むクラスライブラリで構成されています。 これらのクラスは、データのロードとセーブのためのメソッドを持っており、ティムはそれを使って抽象クラス、基底クラス、インターフェースの類似点と相違点を説明します。
以下は、基本クラスと派生クラスの初期コードです:
// Base Class Definition
public class DataAccess
{
// Method to load the connection string
public string LoadConnectionString()
{
Console.WriteLine("Loading the connection string...");
return "Test Connection String";
}
// Method to load data
public void LoadData()
{
Console.WriteLine("Loading data...");
}
// Method to save data
public void SaveData()
{
Console.WriteLine("Saving data...");
}
}
// Derived class that inherits from DataAccess
public class SQLDataAccess : DataAccess
{
// Overriding LoadData method to specify SQL data loading
public new void LoadData()
{
Console.WriteLine("Loading SQL data...");
}
// Overriding SaveData method to specify SQL data saving
public new void SaveData()
{
Console.WriteLine("Saving SQL data...");
}
}
// Derived class that inherits from DataAccess
public class SQLiteDataAccess : DataAccess
{
// Overriding LoadData method to specify SQLite data loading
public new void LoadData()
{
Console.WriteLine("Loading SQLite data...");
}
// Overriding SaveData method to specify SQLite data saving
public new void SaveData()
{
Console.WriteLine("Saving SQLite data...");
}
}' Base Class Definition
Public Class DataAccess
' Method to load the connection string
Public Function LoadConnectionString() As String
Console.WriteLine("Loading the connection string...")
Return "Test Connection String"
End Function
' Method to load data
Public Sub LoadData()
Console.WriteLine("Loading data...")
End Sub
' Method to save data
Public Sub SaveData()
Console.WriteLine("Saving data...")
End Sub
End Class
' Derived class that inherits from DataAccess
Public Class SQLDataAccess
Inherits DataAccess
' Overriding LoadData method to specify SQL data loading
Public Shadows Sub LoadData()
Console.WriteLine("Loading SQL data...")
End Sub
' Overriding SaveData method to specify SQL data saving
Public Shadows Sub SaveData()
Console.WriteLine("Saving SQL data...")
End Sub
End Class
' Derived class that inherits from DataAccess
Public Class SQLiteDataAccess
Inherits DataAccess
' Overriding LoadData method to specify SQLite data loading
Public Shadows Sub LoadData()
Console.WriteLine("Loading SQLite data...")
End Sub
' Overriding SaveData method to specify SQLite data saving
Public Shadows Sub SaveData()
Console.WriteLine("Saving SQLite data...")
End Sub
End ClassTimは(3:21)で基底クラスの作成方法を説明しています。 彼はコードをリファクタリングして、LoadConnectionString などの共通メソッドを DataAccess と呼ばれる基底クラスに移動します。 この基底クラスを継承することによって、SQLDataAccess や SQLiteDataAccess などの他のクラスがこれらの共有メソッドにアクセスでき、コードの重複が減少します。
Timは(5:56)で、基本クラスを抽象クラスに移行し、違いを示しています。 彼は DataAccess を抽象クラスに変更して、直接インスタンス化を防ぎます。 代わりに、SQLiteDataAccess や SQLDataAccess のようなこの抽象クラスを継承したクラスのみが、そのメソッドを実装し、共有機能を利用できます。
DataAccess が抽象クラスになったとき、コードは次のように変わります。
// Abstract Base Class Definition
public abstract class AbstractDataAccess
{
// Shared method to load connection string
public string LoadConnectionString()
{
Console.WriteLine("Loading the connection string...");
return "Test Connection String";
}
// Abstract methods that must be implemented by derived classes
public abstract void LoadData();
public abstract void SaveData();
}' Abstract Base Class Definition
Public MustInherit Class AbstractDataAccess
' Shared method to load connection string
Public Function LoadConnectionString() As String
Console.WriteLine("Loading the connection string...")
Return "Test Connection String"
End Function
' Abstract methods that must be implemented by derived classes
Public MustOverride Sub LoadData()
Public MustOverride Sub SaveData()
End ClassTimは(8:34)で、抽象クラスがインターフェースと基本クラスの機能をどのように融合させるかを説明している。 彼は抽象クラス内で public abstract void LoadData(); や public abstract void SaveData(); などの抽象メソッドを宣言し、実装せずに置いておきます。 これにより、派生クラスは、インターフェイスの仕組みと同様に、これらのメソッドを実装しなければならないことが保証されます。
(12:56)のTimは、抽象クラスでメソッドをオーバーライドする方法について説明しています。 彼は基底クラスで virtual としてメソッドを宣言し、派生クラスがそれをオーバーライドできることを示しています。 このアプローチは、派生クラスでのメソッドの実装方法や拡張方法に柔軟性をもたらします。
以下は、メソッドのオーバーライドを示す派生クラスのコードです:
// Derived class from abstract base class
public class SQLDataAccessWithAbstract : AbstractDataAccess
{
// Implementing the abstract LoadData method
public override void LoadData()
{
Console.WriteLine("Loading SQL data...");
}
// Implementing the abstract SaveData method
public override void SaveData()
{
Console.WriteLine("Saving SQL data...");
}
}' Derived class from abstract base class
Public Class SQLDataAccessWithAbstract
Inherits AbstractDataAccess
' Implementing the abstract LoadData method
Public Overrides Sub LoadData()
Console.WriteLine("Loading SQL data...")
End Sub
' Implementing the abstract SaveData method
Public Overrides Sub SaveData()
Console.WriteLine("Saving SQL data...")
End Sub
End ClassTimは(16:01)で、抽象クラスは毎日使うべきではないが、特定のシナリオでは価値があるとアドバイスしている。 彼は、2つのクラスが同じようなコードを共有しているからといって、抽象クラスを使わないように注意しています。 その代わり、"is a "の関係を維持することを強調し、適切な場合には共有コードのヘルパーメソッドやクラスを考慮することを提案している。
以下は、使い方を示す主なプログラムコードです:
// Main Program
class Program
{
static void Main(string[] args)
{
// Using Base Class
SQLDataAccess sqlData = new SQLDataAccess();
Console.WriteLine(sqlData.LoadConnectionString());
sqlData.LoadData();
sqlData.SaveData();
Console.WriteLine("--------------------------");
// Using Derived Class from Abstract Base Class
SQLDataAccessWithAbstract sqlDataAbstract = new SQLDataAccessWithAbstract();
Console.WriteLine(sqlDataAbstract.LoadConnectionString());
sqlDataAbstract.LoadData();
sqlDataAbstract.SaveData();
Console.WriteLine("--------------------------");
// You can't instantiate Abstract Base Class directly
// AbstractDataAccess abstractData = new AbstractDataAccess();
// Error: Cannot create an instance of the abstract class
}
}' Main Program
Class Program
Shared Sub Main(ByVal args As String())
' Using Base Class
Dim sqlData As New SQLDataAccess()
Console.WriteLine(sqlData.LoadConnectionString())
sqlData.LoadData()
sqlData.SaveData()
Console.WriteLine("--------------------------")
' Using Derived Class from Abstract Base Class
Dim sqlDataAbstract As New SQLDataAccessWithAbstract()
Console.WriteLine(sqlDataAbstract.LoadConnectionString())
sqlDataAbstract.LoadData()
sqlDataAbstract.SaveData()
Console.WriteLine("--------------------------")
' You can't instantiate Abstract Base Class directly
' Dim abstractData As New AbstractDataAccess()
' Error: Cannot create an instance of the abstract class
End Sub
End Classティム・コーリーは、C#抽象クラスを深く掘り下げ、その目的、機能、実際のアプリケーションを明確かつ実用的に理解しています。 デモ・アプリケーションを通して、抽象クラスがどのように基本クラスとインターフェースの間のギャップを埋め、開発者が柔軟で保守性の高いコード構造を作成できるようになるかを示す。
適切なシナリオで抽象クラスを使用し、使い過ぎを避けるといったベストプラクティスを強調することで、Timは開発者に十分な情報に基づいた設計の選択を行うためのツールを提供します。 これらの概念をしっかりと理解することで、開発者はオブジェクト指向プログラミングのスキルを向上させ、堅牢なC#アプリケーションを構築することができます。
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy