在OOP中需要多态性是什么?

Vij*_*M M 5 c++ oop polymorphism virtual

我对OOP概念有愚蠢的问题,我们选择多态的原因是什么?

C++中的简单代码:

class Shape{
public:
virtual void draw(){ cout<<"Shape"<<endl;};
};

class Traingle: public Shape
{
public: void draw(){cout<<"Triangle"<<endl;}
};

class Rectangle: public Shape
{
public: void draw (){cout<<"Rectangle"<<endl;}
};

int main(){
Shape *ptr= new Traingle();
ptr->draw();
delete ptr;
return 7;
}
Run Code Online (Sandbox Code Playgroud)

这里ptr-> draw()函数会调用Triangle绘制,如果指向Rectangle然后是Rectangle draw,这是后期绑定.

创建Base类指针并将其指向不同类的必要性是什么?我们可以创建单独的类对象而不需要任何虚函数,并且可以调用whicever.喜欢

int main(){
    Traingle tObj; 
    tObj->draw();
    Rectangle rObj; 
    rObj->draw();
}
Run Code Online (Sandbox Code Playgroud)

基本上做同样的事情;

为什么多态基本上?为什么虚拟?

它有什么需要或者使用这个属性有什么区别?真实案例会有所帮助!!

eer*_*ika 3

多态性允许对相关类型的对象进行相同的处理,从而允许重用代码。

考虑一下您可能需要数十个行为不同的子类:

struct Shape1: public Shape { /* .. */ }; // triangle
struct Shape2: public Shape { /* .. */ }; // rectangle
// ...
struct ShapeN: public Shape { /* .. */ }; // projection of rhombic triacontahedron
Run Code Online (Sandbox Code Playgroud)

考虑到您可能需要处理由指针数组指向的对象Shape

对于多态性,您需要一个向量和一个带有虚函数调用的循环:

std::vector<Shape*> v = get_shape_vector();
for(Shape* s : v)
    s->draw();
Run Code Online (Sandbox Code Playgroud)

如果没有多态性,您将为每种类型管理一个单独的数组并单独处理它们:

std::vector<Shape1> v1 = get_shape1_vector();
std::vector<Shape2> v2 = get_shape2_vector();
// ...
std::vector<ShapeN> vN = get_shapeN_vector();

for(Shape1& s : v1)
    s.draw();
for(Shape2& s : v2)
    s.draw();
// ...
for(ShapeN& s : vN)
    s.draw();
Run Code Online (Sandbox Code Playgroud)

使用多态性的 3 行代码比不使用多态性的 3*N 行代码更容易维护。

考虑您可能需要修改该流程。也许您想在绘图之前添加函数调用。当你有多态性时,这很简单:

void pre_draw(Shape*);

for(Shape* s : v) {
    pre_draw(s);
    s->draw();
}
Run Code Online (Sandbox Code Playgroud)

如果没有多态性,您需要定义数十个函数并修改十几个循环中的每一个:

void pre_draw1(Shape1&);
void pre_draw2(Shape2&);
// ...
void pre_drawN(ShapeN&);

for(Shape1& s : v1) {
    pre_draw1(s);
    s.draw();
}
for(Shape2& s : v1) {
    pre_draw2(s);
    s.draw();
}
// ...
for(ShapeN& s : v1) {
    pre_drawN(s);
    s.draw();
}
Run Code Online (Sandbox Code Playgroud)

请考虑稍后添加形状。使用多态性,您只需定义新类型和虚函数。您只需将指向它的指针添加到数组中,它们就会像其他所有兼容类型的对象一样被处理。

struct ShapeN1: public Shape { /* .. */ }; // yet another shape
Run Code Online (Sandbox Code Playgroud)

如果没有多态性,除了定义新类型之外,您还必须为其创建一个新数组。并且您需要创建一个新pre_draw函数。并且您需要添加一个新循环来处理它们。

void pre_drawN1(ShapeN1&);
// ...
std::vector<ShapeN1> vN1 = get_shapeN1_vector();
// ...
for(ShapeN1& s : vN1) {
    pre_drawN1(s);
    s.draw();
}
Run Code Online (Sandbox Code Playgroud)

事实上,您需要遍历整个代码库以查找处理每种形状类型的位置,并在其中添加新类型的代码。


现在,N 可能很小也可能很大。 N越大,多态性避免的重复越多。但是,无论您有多少子类,在添加新子类时不必查看整个代码库都是一个很大的好处。