我正在做某种研发,对抽象类的概念感到困惑。
我对抽象类的了解是它可能包含具体方法,也可能包含虚拟方法。它可能包含也可能不包含抽象方法,它可能包含字段并限制实例的直接创建。
但是我们可以在一个简单的基类中实现所有这些(添加虚拟方法会做很多事情,因为具有不包含实现和覆盖的虚拟方法的基类与抽象方法相同)。那么为什么我们需要一个抽象类,虽然接口支持多重继承和事件呢?
我正在做某种研发,对抽象类的概念感到困惑。
我对抽象类的了解是它可能包含具体方法,也可能包含虚拟方法。它可能包含也可能不包含抽象方法,它可能包含字段并限制实例的直接创建。
但是我们可以在一个简单的基类中实现所有这些(添加虚拟方法会做很多事情,因为具有不包含实现和覆盖的虚拟方法的基类与抽象方法相同)。那么为什么我们需要一个抽象类,虽然接口支持多重继承和事件呢?
但是我们可以在一个简单的基类中实现所有这些
不,你不能。您不能拥有具有抽象方法的非抽象类(定义了签名但没有给出实现的方法,因此强制派生类提供实现)。
抽象类的存在使得它们可以提供实现方法和抽象方法的组合。
您可以尝试abstract
通过使用不做任何事情的具体实现来避免使用类,但它有许多缺点:
还要考虑没有抽象的世界中的非空方法。他们将需要抛出(即NotImplementedException
)或返回无效值(即null
)。这可能比什么都不做的方法要糟糕得多。
主要区别在于编译器不会让您实例化抽象类,而您可以实例化基类(这可能没有意义)。
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
并且它会做一些事情。
一个简单的答案可能是:-
基类有自己的方法实现,这些实现可以在继承的类中使用/添加。您可以实例化一个基类
抽象类具有类方法的声明。任何继承抽象类的类都必须实现它的抽象方法或成为抽象自己。你不能实例化一个抽象类
例子:-
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 类中的 Method1,因为它是继承的。如果类 A 是抽象的,那么所有的方法都将被声明为 Method2 并且必须在类 B 中实现才能使用它。
有些类在现实世界中根本不存在,因此在概念上应标记为abstract
. 例如,考虑abstract class Animal
. 现实世界中没有“动物”这样的东西。相反,有一些具体类型的动物,例如Dog
,Cat
等。