我正在进行一种研究,对抽象类的概念感到困惑。
就我的理解,抽象类可以包含具体方法和虚方法。它可能包含或不包含抽象方法,并且可能包含字段,限制了直接创建实例。
但其实我们可以在一个简单的基类中实现所有这些功能(增加虚方法即可,因为一个带有虚方法的基类如果没有实现并覆盖虚方法的话,就和抽象方法一样了)。那么既然接口支持多继承和事件,为什么还需要抽象类呢?
我正在进行一种研究,对抽象类的概念感到困惑。
就我的理解,抽象类可以包含具体方法和虚方法。它可能包含或不包含抽象方法,并且可能包含字段,限制了直接创建实例。
但其实我们可以在一个简单的基类中实现所有这些功能(增加虚方法即可,因为一个带有虚方法的基类如果没有实现并覆盖虚方法的话,就和抽象方法一样了)。那么既然接口支持多继承和事件,为什么还需要抽象类呢?
AbstractType a = new AbstractType(); //compiler error
AbstractType d = new DerivedType(); //OK
BaseType b = new BaseType(); //OK
注意变量d
,我们保证了抽象方法已被覆盖(否则DerivedType
类将会有编译错误)。
由于您仍然存在许多困惑,我将给您一个例子,这个例子真正让我明白了这个概念。想象一下你正在制作一个塔防游戏。你有一个塔的类,每个塔都有攻击的能力,所以你可以像这样创建一个抽象的塔类:
abstract class Tower
{
abstract void Attack();
}
class FlameTower : Tower
{
override void Attack()
{
//Shoot flames at everyone
}
}
class IceTower : Tower
{
override void Attack()
{
//Shoot ice everywhere
}
}
List<Tower> towerList = new List<Tower>();
towerList.Add(new FireTower());
towerList.Add(new IceTower());
foreach (Tower t in towerList)
{
t.Attack();
}
towerList.Add(new Tower());
new Tower()
上调用攻击时,它将命中一个空的抽象方法,这不是我们想要的。因此,为了禁止将某些东西声明为通用塔,我们使该类为抽象类,然后我们知道每个东西都将有自己的Attack
定义,并且会执行某些操作。抽象类 Animal
有函数 public abstract void eatStuff()
,那么每个 Animal
的具体实例都知道如何进食。 - musical_coder一个简单的答案可以是:
基类有它们自己的方法实现,这些实现可以在继承类中使用/添加。您可以实例化一个基类。
抽象类声明了类方法。任何继承抽象类的类都必须实现其抽象方法,否则会变成抽象类本身。您不能实例化一个抽象类。
示例:
public abstract class A
{
public void Method1()
{
//method code
}
public abstract void Method2();
public virtual void Method3()
{
//method code for class A, when class A calls Method3, this code is executed
}
}
public class B : A
{
public override void Method2()
{
//this must be implemented here to use it
}
public override void Method3()
{
//method code for class B, when class B calls Method3, this code is executed
//or, if you choose not to override this method, the compiler will use the code in class A
}
}
因为类B继承了类A,所以它仍然可以使用来自类A的Method1。如果类A要被抽象化,那么所有方法都将像Method2一样被声明,并且必须在类B中实现,以便可以使用。
有一些类在现实世界中并不存在,因此应该将其概念上标记为abstract
。例如,考虑抽象类 Animal
。在现实世界中没有“动物”这样的东西。相反,存在具体类型的动物,如Dog
、Cat
等。