什么是C#中的抽象类。何时、何地以及为何使用它。
简介
抽象类和接口是最常被问到的面试问题之一。
抽象类:
就像类一样,Abstract 关键字用于创建抽象类。抽象类是不完整的,因此不能被实例化。抽象类只能是基类。抽象类可以同时具有抽象方法和非抽象方法(具体方法)。
例子:
abstract class Customer // Using abstract keyword to create abstract class.
{
public void Print1() // Non Abstract method
{
}
public abstract void Print2(); // Abstract method
}
如果我们声明抽象方法的主体,那么它会报错,因为我们不能声明抽象类的主体。
例子:
abstract class Customer // Using abstract keyword to create abstract class.
{
public void Print1() // Non Abstract method
{
}
public abstract void Print2(); // Declaring body for Abstract method // Error-Invalid token '{' in class, struct,
// or interface member declaration
{
}
}
由于抽象类是不完整的类,因此创建抽象类的实例没有意义。抽象类不能实例化,只能作为基类使用。
例子:
namespace ConsoleApplication
{
abstract class Customer // Using abstract keyword to create abstract class.
{
public void Print1() // Non Abstract method
{
}
public abstract void Print2(); // Abstract method
{
}
}
class Program
{
static void Main(string[] args)
{
Customer c = new Customer(); //can't create instance of Abstract
// class or Interface 'Customer'
}
}
}
如果一个类是从抽象类继承的,那么该类将负责定义该抽象方法,否则会报错。
例子:
abstract class Customer
{
public abstract void Print2(); // Abstract method
}
class Program : Customer
{
static void Main(string[] args)
{
// Program doesn’t implemented Abstract method
}
}
如果一个类继承了一个抽象类,那么该类有两种选择
选项 1 :为从基本抽象类继承的所有抽象成员提供实现。
例子:
abstract class Customer
{
public abstract void Print2(); // Abstract method
}
class Program : Customer
{
public override void Print2()
{
Console.WriteLine("Print2 method");
}
static void Main(string[] args)
{
}
}
选项 2:如果类不希望为从抽象类继承的所有抽象成员提供实现,则必须将该类标记为抽象类。
例子:
abstract class Customer
{
public abstract void Print2(); // Abstract method
}
abstract class Program : Customer // Marked as Abstract
{
static void Main(string[] args)
{
}
}
我们不能创建抽象类的实例,但是抽象类引用变量可以指向基类对象。
例子:
abstract class Customer
{
public abstract void Print2(); // Abstract method
}
class Program : Customer
{
public override void Print2()
{
Console.WriteLine("Print2 method");
}
static void Main(string[] args)
{
Customer objCustomer = new Program();// base class reference variable
//pointing derived class object
}
}
抽象类不能标记为密封的,因为它们相互矛盾。
例子:
abstract class Customer
{
public abstract void Print2(); // Abstract method
}
抽象类意味着客户类总是可以用作基类。
尽管
密封意味着客户类不能用作基类。
abstract sealed class Customer // An Abstract class cannot be sealed or static
{
public abstract void Print2();
}
抽象类可以包含抽象成员(方法、属性、索引器和事件),但不是强制性的。
何时使用抽象类:
当您要求基类应提供某些方法的默认实现而其他方法应开放以被子类覆盖时,请使用抽象类。
抽象类的目的是提供多个派生类可以共享的基类的通用定义。
例如,一个类库可能会定义一个抽象类,用作其许多函数的参数,并要求使用该库的程序员通过创建派生类来提供他们自己的类实现。