您的位置:首页 > 编程语言 > C语言/C++

C++、JAVA与C#中的多态虚函数、纯虚函数(抽象函数)

2014-12-19 11:23 337 查看
面向对象之中,最重要的概念无外乎四个:封装、继承、抽象与多态。

其他三个很好理解,但多态,总是一个不大不小容易模糊的问题。多态,定义为,不同对象调用同一方法的不同行为。具体的见代码,就会感觉很明晰:

C++代码:

[cpp] view
plaincopy

#include<iostream>

using namespace std;

class father

{

public:

virtual void f()

{

cout<<"father's f()"<<endl;

}

};

class son:public father

{

public:

virtual void f()

{

cout<<"son's f()"<<endl;

}

};

int main()

{

father *myf=new father();

father *mys=new son();

myf->f();

mys->f();

delete myf;

delete mys;

system("pause");

return 0;

}

运行结果为:

father's f()

son's f()

对应的JAVA代码为:

[java] view
plaincopy

import java.util.*;

public class test

{

class father

{

public void f()

{

System.out.println("father's f()");

}

}

class son extends father

{

public void f()

{

System.out.println("son's f()");

}

}

public void tes()

{

father myf=new father();

father mys=new son();

myf.f();

mys.f();

}

public static void main(String[] args)

{

test myt=new test();

myt.tes();

}

}

运行的结果为:

father's f()

son's f()

可以看到,JAVA中没有虚函数的概念,它的普通函数就相当于C++中的虚函数。

需要注意的是,C++代码中将virtual修饰去掉,也可以编译通过,不过运行出来的结果就是两次都调用的是father类中的f()函数。

C#代码为:

[c-sharp] view
plaincopy

using System;

public class myt

{

class father

{

public virtual void f()

{

Console.WriteLine("father's f()");

}

}

class son:father

{

public override void f()

{

Console.WriteLine("son's f()");

}

}

public void func()

{

father myf=new father();

myf.f();

father mys=new son();

mys.f();

}

public static void Main(string[] args)

{

myt t=new myt();

t.func();

}

}

运行结果为:

father's f()

son's f()

可以看到,C#同C++一样,也是保留了virtual函数修饰符的,而且,它如果子类要重写的话,必须加上override。同样,如果去掉virtual和override,那么两次都是调用的父类的f()函数。会有一个警告,myt.son.f()隐藏了myt.father.f()。

如果不是标记为virtual的父类的函数,是override不了的。

接下来,再讨论一下纯虚函数。

在C++中,标记为virtual的函数必须得有函数体,哪怕函数体为空都可以。要不然虽然可以通过编译,但是会发生link错误。

C++中的纯虚函数为:

virtual void f()=0;纯虚函数可以没有函数体。

含有纯虚函数的类不能被实例化,它必须得有子类。子类重写了它的纯虚函数之后,才能够实例化。

[cpp] view
plaincopy

#include<iostream>

using namespace std;

class father

{

public:

virtual void f()=0;

};

class son:public father

{

public:

virtual void f()

{

cout<<"son's f()"<<endl;

}

};

int main()

{

//father *myf=new father();//错误,不能被实例化

father *mys=new son();

//myf->f();

mys->f();

//delete myf;

delete mys;

system("pause");

return 0;

}

对于java而言,纯虚函数的修饰符为abstract,当然,它不叫纯虚函数,而叫做抽象函数。

抽象函数得定义在抽象类中,抽象函数没有函数体。当然,抽象类中还可以包括非抽象函数。

abstract class father

{

public abstract void f();

public void f1()

{

System.out.println("f1");

}

}

对于C#而言,virtual函数必须得有函数体。它的抽象函数(纯虚函数)为:

public abstract class Book

{

//抽象方法,不含主体,抽象方法所在类必须为抽象类,派生类必须实现该方法

public abstract void Introduce();

}

public class JavaBook : Book

{

//实现抽象方法,必须实现,必须添加override关键字

public override void Introduce()

{

Console.WriteLine("I'm Java");

}

}

同JAVA一样,也是用abstrace作为修饰。

综上所述:

C++:

虚函数,virtual,有函数体。纯虚函数=0,没有函数体。多态用虚函数实现。包含纯虚函数的类不能实例化。子类可以实现也可以不实现纯虚函数。

JAVA:

没有虚函数,重写(多态)用纯虚函数即可。抽象函数abstract没有函数体,必须放在abstract类中。abstract类不能实例化。abstract的子类可以不实现父类的abstract方法,不是abstract的子类必须实现。

C#:

虚函数为virtual,有函数体,子类重写用override。抽象函数为abstract,与JAVA相同。只是子类实现时也要加上override。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: