c++最简单的多态例子,class A.classb

c++最简单的多态例子,class A.classb,第1张

C++中的多态(虽然多态不是C++所特有的,但是C++中的多态确实是很特殊的)分为静多态和动多态(也就是静态绑定和动态绑定两种现象),静动的区别主要在于这种绑定发生在编译期还是运行期,发生在编译期的是静态绑定,也就是静多态;发生在运行期的则是动态绑定,也就是动多态。

静多态可以通过模板和函数重载来实现(之所说C++中的多态主要还是因为模板这个东西),下面举两个例子:

1)函数模板

template <typename T>

T max(const T&lsh, const T&rhs)

{

return (lsh >rhs) ? lsh : rhs

}

返回两个任意类型对象的最大值(对象),前提是该类型能够使用>运算符进行比较,并且返回值是bool类型。

使用:

int a = 3int b = 4

cout <<max(a, b) <<endl

float c = 2.4float d = 1.2

cout <<max(c, d) <<endl

输出结果为:

4

2.4

这种绑定发生在编译期,这是由于模板的实例化是发生在编译期的,即在编译时编译器发现你调用max(a, b)时就自动生成一个函数

int max(const int&lsh, const int&rhs)

{

return (lsh >rhs) ? lsh : rhs

}

即将所有的T替换成int

当你调用max(c, d)时就自动生成一个函数

float max(const float&lsh, const float&rhs)

{

return (lsh >rhs) ? lsh : rhs

}

之所以说开始的函数定义是函数模板,就是因为他就像个模子似的,你可以用铝作为原料也可以用石膏或者铜。

2)函数重载:

int max (int a, int b)

{

return (a >b) ? a : b

}

int max (int a, int b, int c)

{

return max(max(a, b), c)

}

两个函数名称一样,参数类型或个数不完全相同,返回值一样(这个不重要)。

使用:

int a = 3, b = 4, c = 5

cout <<max(a, b) <<endl

cout <<max(a, b, c) <<endl

输出结果为:

4

5

确定函数的过程也发生在编译器,当你使用max(a, b),编译器发现只有两个参数,那么就调用只有两个参数的函数版本,当使用max(a, b, c)时,编译器则使用有3个参数的版本。

通过上面的两个例子,你还可以使用更为方便的模板函数重载:

template <typename T>

T max(const T&lsh, const T&rhs)

{

return (lsh >rhs) ? lsh : rhs

}

template <typename T>

T max(const T&a, const T&b, const T&c)

{

return max(max(a, b), c)

}

使用

float a = 3.6, b = 1.2, c = 7.8

cout <<max(a, b, c) <<endl

输出:

7.8

通过参数个数和类型,编译器自动生成和调用对应得函数版本!

动多态则是通过继承、虚函数(virtual)、指针来实现。

class A {

public:

virtual void func() const {

coust <<“A::func()” <<endl

}

}

class B : public A {

public:

virtual void func() const {

coust <<“B::func()” <<endl

}

}

使用:

A a* = B()

a->func()

输出:

B::func()

编译期是不调用任何函数的,编译器编译到a->func()时只是检查有没有语法问题,经过检查没有。编译器并不知道调用的是A版本的func()还是B版本的func(),由于a是一个指向B对象的指针,所以a只知道它指向的是一个A类型(或者能转换成A类型)的对象。通常集成体系就说明了(由于是公有继承)B是一种A。在运行期,a要调用a所指向对象的func()函数,就对它指向的对象下达调用func()的命令,结果a所指向的是一个B对象,这个对象就调用了自己版本(B版)的func()函数,所以输出时B::func()

总结:

在编译期决定你应该调用哪个函数的行为是静态绑定(static-binding),这种现象就是静多态。

在运行期决定应该调用哪中类型对象的函数的行为是动态绑定(dynamic-binding),这种现象就是动多态

using System//调用system类 和C下的include一样

using System.Drawing//调用system.drawing类

using _05_Base //调用自建类05_base

namespace _05_03 //命名空间 05_03

{

public class Class_05_03 //公有类05_03

{

public static void PrintArea(Shape shape)

//公有类 静态 无返回值类 PrintArea(内部数据成员shape,把shape这个单词指定为shape类型,就象int i)

{

Console.WriteLine("Area of {0} is : {1}", shape.Name, shape.Area)

//控制台输出 Area of {0} is : {1} 其中0为shape.Name的数据 1 为shape.Area的数据

}

public static void Main(String[] args)

// 公有类 静态无返回值 主函数()

{

Point p = new Point(0, 0)

为point 分配一新的空间p(0,0)

_05_Base.Rectangle r = new _05_Base.Rectangle()

// 分配一新的空间r ,用05_Base.Rectangle类化

r.Name = "Rectangle r"

r.Width = 10

r.Height = 20

//以上3行为新分配的空间r 写入其类的对应值

Square s = new Square()

s.Name = "Square s"

s.Side = 15

//用Square 类化s 分配空间 赋值

Ellipse e = new Ellipse()

e.Name = "Ellipse e"

e.SemiMajorAxis = 10

e.SemiMinorAxis = 5

//用Ellipse类化e 分配空间 赋值

Circle c = new Circle()

c.Name = "Circle c"

c.Radius = 6

Triangle t = new Triangle()

t.Name = "Triangle t"

t.Point1 = new Point(3, 3)

t.Point2 = new Point(3, 0)

// 这两个自己会看了把??

Shape[] shapes = new Shape[5]

shapes[0] = r

shapes[1] = s

shapes[2] = e

shapes[3] = c

shapes[4] = t

foreach(Shape shape in shapes)

//Shape shape in shapes不懂这是什么意思

{

shape.Position = p

PrintArea(shape)

}

}

}

}

在C++中: classA{public:    A(){}    virtual void foo()    {        cout<<ThisisA.<<endl    }}classB:publicA{public:    B(){}    void foo()    {        cout<<ThisisB.<<endl    }}int main(intargc,char*argv[]){    A* a = new B()    a->foo()    if(a != NULL)    delete a    return0}这将显示:

This is B.

如果把virtual去掉,将显示:

This is A.

前面的多态通过使用虚函数virtual void foo()来实现。

在java中:

多态,是面向对象的程序设计语言最核心的特征。多态,意味着一个对象有着多重特征,可以在特定的情况下,表现不同的状态,从而对应着不同的属性和方法。从程序设计的角度而言,多态可以这样来实现(以java语言为例): public interface Parent//父类接口{    public void simpleCall()}public class Child_A implements Parent{    public void simpleCall()    {    //具体的实现细节;    }}public class Child_B implements Parent{    public void simpleCall()    {    //具体的实现细节;    }}//当然还可以有其他的实现

然后,我们就可以看到多态所展示的特性了:

Parent pa = new Child_A()

pa.simpleCall()则显然是调用Child_A的方法;

Parent pa = new Child_B()

pa.simpleCall()则是在调用Child_B的方法。所以,我们对于抽象的父类或者接口给出了我们的具体实现后,pa 可以完全不用管实现的细节,只访问我们定义的方法,就可以了。事实上,这就是多态所起的作用,可以实现控制反转这在大量的J2EE轻量级框架中被用到,比如Spring的依赖注入机制。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12208438.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存