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

本文深入探讨面向对象编程中封装、继承、抽象与多态概念,并通过C++、Java及C#代码示例,详细解释多态性的实现与应用,突出不同语言在多态性处理上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向对象之中,最重要的概念无外乎四个:封装、继承、抽象与多态。

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

C++代码:

[cpp]  view plain copy
  1. #include<iostream>  
  2. using namespace std;  
  3. class father  
  4. {  
  5.       public:  
  6.              virtual void f()  
  7.              {  
  8.                      cout<<"father's f()"<<endl;  
  9.              }  
  10. };  
  11. class son:public father  
  12. {  
  13.       public:  
  14.              virtual void f()  
  15.              {  
  16.                      cout<<"son's f()"<<endl;  
  17.              }  
  18. };  
  19. int main()  
  20. {  
  21.     father *myf=new father();  
  22.     father *mys=new son();  
  23.     myf->f();  
  24.     mys->f();  
  25.     delete myf;  
  26.     delete mys;  
  27.     system("pause");  
  28.     return 0;  
  29. }  

运行结果为:

father's f()

son's f()

对应的JAVA代码为:

[java]  view plain copy
  1. import java.util.*;  
  2. public class test  
  3. {  
  4.     class father  
  5.     {  
  6.         public void f()  
  7.                                {  
  8.                                          System.out.println("father's f()");  
  9.                                 }  
  10.                 }  
  11.                class son extends father  
  12.                 {  
  13.                                public void f()  
  14.                                {  
  15.                                         System.out.println("son's f()");  
  16.                                }  
  17.                 }  
  18.                public void tes()  
  19.                 {  
  20.                                father myf=new father();  
  21.                                father mys=new son();  
  22.                                myf.f();  
  23.                                mys.f();    
  24.                  }  
  25.                 public static void main(String[] args)  
  26.                 {  
  27.                                test myt=new test();  
  28.                                 myt.tes();  
  29.                  }  
  30. }  

运行的结果为:

father's f()

son's f()

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

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

C#代码为:

[c-sharp]  view plain copy
  1. using System;  
  2. public class myt  
  3. {  
  4.                class father  
  5.                {  
  6.                        public virtual void f()  
  7.                        {  
  8.                                Console.WriteLine("father's f()");  
  9.                        }  
  10.                }  
  11.                class son:father  
  12.                {  
  13.                        public override void f()  
  14.                        {  
  15.                               Console.WriteLine("son's f()");  
  16.                         }  
  17.                 }  
  18.                public void func()  
  19.                {  
  20.                         father myf=new father();  
  21.                         myf.f();  
  22.                         father mys=new son();  
  23.                         mys.f();  
  24.                }  
  25.     public static void Main(string[] args)  
  26.                  {  
  27.                          myt t=new myt();  
  28.                          t.func();  
  29.                  }  
  30. }  

运行结果为:

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 plain copy
  1. #include<iostream>  
  2. using namespace std;  
  3. class father  
  4. {  
  5.       public:  
  6.              virtual void f()=0;  
  7. };  
  8. class son:public father  
  9. {  
  10.       public:  
  11.              virtual void f()  
  12.              {  
  13.                      cout<<"son's f()"<<endl;  
  14.              }  
  15. };  
  16. int main()  
  17. {  
  18.     //father *myf=new father();//错误,不能被实例化   
  19.     father *mys=new son();  
  20.     //myf->f();  
  21.     mys->f();  
  22.     //delete myf;  
  23.     delete mys;  
  24.     system("pause");  
  25.     return 0;  
  26. }  

对于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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值