一个具体类和一个抽象类有什么区别? [英] What is the difference between a concrete class and an abstract class?

查看:121
本文介绍了一个具体类和一个抽象类有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习C ++,但我对抽象类和具体类感到困惑。

I am learning C++, but I am confused about abstract class and concrete class. Some real world examples would be appreciated.

推荐答案

抽象类是一个或多个方法声明但未定义的类,意味着编译器知道这些方法是类的一部分,但不是那个方法要执行的代码。这些被称为抽象方法。这是一个抽象类的例子。

An abstract class is a class for which one or more methods are declared but not defined, meaning that the compiler knows these methods are part of the class, but not what code to execute for that method. These are called abstract methods. Here is an example of an abstract class.

class shape {
public:
  virtual void draw() = 0;
};

这声明一个抽象类,它指定类的任何后代都应该实现draw方法是具体的。你不能实例化这个类,因为它是抽象的,毕竟,如果你调用成员绘制,编译器不知道执行什么代码。所以你不能这样做:

This declares an abstract class which specifies that any descendants of the class should implement the draw method if the class is to be concrete. You cannot instantiate this class because it is abstract, after all, the compiler wouldn't know what code to execute if you called member draw. So you can not do the following:

shape my_shape();
my_shape.draw();

为了能够真正使用draw方法,你需要从这个抽象类派生类,请实现draw方法,使类具体:

To be able to actually use the draw method you would need to derive classes from this abstract class, which do implement the draw method, making the classes concrete:

class circle : public shape {
public:
  circle(int x, int y, int radius) {
    /* set up the circle */
  }
  virtual draw() {
    /* do stuff to draw the circle */
  }
};

class rectangle : public shape {
public:
  rectangle(int min_x, int min_y, int max_x, int max_y) {
    /* set up rectangle */
  }
  virtual draw() {
    /* do stuff to draw the rectangle */
  }
};



现在,您可以实例化具体对象圆和矩形,并使用它们的绘制方法:

Now you can instantiate the concrete objects circle and rectangle and use their draw methods:

circle my_circle(40, 30, 10);
rectangle my_rectangle(20, 10, 50, 15);
my_circle.draw();
my_rectangle.draw();

现在的问题是,为什么要这样做?你不能只是已经定义了圆形和矩形类,并已完成了整个形状类?你可以,但是你不能利用它们的继承:

Now of course the question is, why would you want to do this? Couldn't you just as well have defined the circle and rectangle classes and have done away with the whole shape class? You could, but then you wouldn't be able to take advantage of their inheritance:

std::vector<shape*> my_scene;
my_scene.push_back(new circle(40, 30, 10));
my_scene.push_back(new rectangle(20, 10, 50, 15));
std::for_each(my_scene.begin(), my_scene.end(), std::mem_fun_ref(&shape::draw)

这段代码让你将所有的形状收集到一个容器中,这使得在你的场景中有很多形状和许多不同的形状,一次绘制所有的形状,并且这样做的代码甚至不需要知道我们有不同类型的形状。

This code let's you collect all your shapes into one container. This makes it a lot easier if you have a lot of shapes and many different shapes in your scene. For example we can now draw all the shapes in one go, and the code that does so doesn't even need to know about the different types of shapes we have.

现在最终我们需要知道为什么形状的绘制函数是抽象的,而不只是一个空函数,即为什么我们不是定义:

Now finally we need to know why the draw function of shape is abstract, and not just an empty function, i.e. why didn't we just define:

class shape {
public:
  virtual void draw() {
    /* do nothing */
  }
};

这样做的原因是我们不希望类型为shape的对象,他们不会是真实的东西,他们将是抽象的。所以它没有任何意义来定义一个实现的绘制方法,甚至一个空的。使形状类抽象阻止我们错误地实例化形状类,或错误地调用基类的空绘制函数,而不是绘制派生类的函数。实际上,我们为任何类想定义一个形状定义一个接口,我们说任何这样的类应该有一个draw方法,看起来像我们已经指定它应该。

The reason for this is that we don't really want objects of type shape, they wouldn't be real things anyway, they would be abstract. So it doesn't make any sense to define an implementation for the draw method, even an empty one. Making the shape class abstract prevents us from mistakenly instantiating the shape class, or mistakenly calling the empty draw function of the base class instead of the draw function of the derived classes. In effect we define an interface for any class that would like to behave like a shape, we say that any such class should have a draw method that looks like we have specified it should.

为了回答你最后一个问题,没有任何类似正常派生类的东西,每个类都是抽象的或具体的。具有任何抽象方法的类是抽象的,任何不是具体的类。这只是一种区分两种类型的类的方法。基类可以是抽象的或具体的,派生类可以是抽象的或具体的:

To answer you last question, there isn't any such thing as a 'normal derived class' every class is either abstract or concrete. A class that has any abstract methods is abstract, any class that doesn't is concrete. It's just a way to differentiate the two types of classes. A base class can be either abstract or concrete and a derived class can be either abstract or concrete:

class abstract_base {
public:
  virtual void abstract_method1() = 0;
  virtual void abstract_method2() = 0;
};

class concrete_base {
public:
  void concrete_method1() {
    /* do something */
  }
};

class abstract_derived1 : public abstract_base {
public:
  virtual void abstract_method3() = 0;
};

class abstract_derived2 : public concrete_base {
public:
  virtual void abstract_method3() = 0;
};

class abstract_derived3 : public abstract_base {
public:
  virtual abstract_method1() {
    /* do something */
  }
  /* note that we do not provide an implementation for
     abstract_method2 so the class is still abstract */
};

class concrete_derived1 : public concrete_base {
public:
  void concrete_method2() {
    /* do something */
  }
};

class concrete_derived2 : public abstract_base {
public:
  virtual void abstract_method1() {
    /* do something */
  }
  virtual void abstract_method2() {
    /* do something */
  }
  /* This class is now concrete because no abstract methods remain */
};

这篇关于一个具体类和一个抽象类有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆