您好, 访客   登录/注册

C++和Java中OOP机制之差异性分析

来源:用户上传      作者: 冯高峰 冯艳茹 原佩剑

  摘要:C++和Java是目前使用相当广泛的两种面向对象程序设计语言,该文对二者的OOP实现机制之差异性进行分析,从封装性、继承性和多态性三个方面进行探讨,为熟练使用C++和Java进行OOP编程提供帮助。
  关键词:封装性;继承性;多态性;差异性
  中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)03-0599-02
  C++和Java是目前主流的两种面向对象的程序设计语言。C++是编译型,而Java是解释型。C++执行速度快,而Java可移植性好,C++适合底层编程,而Java擅长于WEB系统和嵌入式消费电子设备编程。C++和Java都于基于OOP理论设计出来的,所以它们在基本语法和核心概念上有许多相似之处,然而它们之间在OOP的实现机制上存在不容忽视的差异。本文分析C++和Java在OOP实现机制上的差异。
   1 OOP基本概念分析
  OOP(Object-Oriented Programming)面向对象编程是目前最主流的程序设计思想,其核心内容由三部分组成:封装性、继承性和多态性。
  1.1封装性
  封装就是把数据和操作数据的方法结合在一起,形成一个类,外面的类不能随意访问这些数据,通常提供公用方法来访问数据。类和方法是封装性的核心概念。类是一类事物的抽象,包含这类事物的描述和可进行的动作。按照类的模板建立的实例,叫做对象。例如“教师”就可以抽象为一个类,其数据包括教师编号、姓名、性别等,其方法包括备课、讲课、辅导等,具体到某一个教师如“李华老师”,他就是一个对象。
  1.2继承性
  继承性所表达的是类之间的相互关系,为程序代码的复用提供了良好的支持。继承机制的核心概念是父类和子类,也叫基类和派生类。派生类继承基类的数据和操作,也就是说允许派生类使用基类的数据和操作。同时派生类也可以增加新的数据和操作。例如汽车可以抽象为一个基类,警车类可以作为派生类,它继承了汽车类的有四个车轮及可以移动的特性,还可以增加新的特性,如有警灯、警笛和优先通行等特性。
  1.3多态性
  多态性指不同的对象收到相同的消息时产生多种不同的行为方式。例如一个司机的车停在了别人的车位上,司机可能会收到别人给他的消息―“请把您的车挪开”,在图书馆里司机的凳子挡住了别人的去路,司机可能会收到别人给他的消息―“请把您的凳子挪开”。在这两种情况下司机收到的都是“挪开”一样东西的消息,但是在听到“挪开”请求以后的行为是截然不同的。这就是多态性,多态性的核心概念是重载和覆盖。
   2封装性之差异性分析
  C++拥有OOP的特性,同时也继承了C的许多面向过程的特性,如全局变量、结构体和枚举等,所以C++包含了面象过程编程和面向对象编程的双重概念。然而Java却是一种完全面向对象的编程语言,它所有的程序都是由类或者说类的定义组成的。
  2.1类的定义之差异
  类的组成通常是数据和操作,它们在C++中通常称为成员数据和成员函数,在Java中通常称为属性和方法。在C++中函数可以定义在类中,作为成员函数,也可以不定义在类中,作为独立的函数;数据可以定义在类中,作为成员数据,也可以定义在类外,作为全局变量。在Java所有的方法和属性必须定义在某个类中,禁止在类外对方法和属性进行定义,更符合其完全面向对象的特点。
  在C++中不可以在一个类的内部定义另一个类,也就是说不支持类的嵌套定义,而Java支持类的嵌套定义,称之为内部类。
  2.2对象的建立与销毁之差异
  C++和Java对象建立过程中分配空间的时机不同。假若有一个类Point,语句Point p在C++中的含义是定义一个对象p,同时为 对象p分配存储空间;语句Point p在Java中含义却只是定义一个实例变量p,并没有分配存储空间,只有执行了p=new Point()后才完成了存储空间的分配,生成了对象。
  C++中对象的生成和销毁都是通过编程人员编写程序代码来完成的,对象的生成需要编写构造函数,对象的销毁需要编写析构函数,在需要生成对象时自动调用构造函数,在对象销毁时自动调用析构函数,内存空间是由编程人员负责管理的。
  Java中对象的生成需要调用构造方法,这和C++中一样。但在Java中为简化编程,对象销毁时的空间回收是由系统的垃圾回收机制自动完成的,Java不支持析构方法,在必要的时候也可以创建一个方法来完成存储空间的回收。
  当由已经存在的对象建立一个新对象时,C++使用拷贝构造函数,将参数代表的对象逐域拷贝到新创建的对象中。在Java中没有拷贝构造函数,因为实例变量是按引用传递的。
  3.1多重继承与接口
  多重继承是指一个子类可以有一个以上的直接父类。C++支持多重继承,而Java不支持多重继承,而是使用接口来实现多重继承的功能。接口就是方法定义和常量值的集合,一个接口可以继承多个父接口,子接口继承父接口中所有的常量和方法。在Java中一个类只能有一个父类,却可以实现多个接口,达到了比多重继承更强的功能。
  3.2继承方式
  C++中的继承方式有公有继承、保护继承和私有继承,在Java中只有一种继承,那就是公有继承,所以在Java中继承不会改变父类成员的保护级别。
   4多态性之差异性分析
  多态性是指用一个名字定义不同的函数,即函数名相同而函数体不同,也就是用同样的接口访问功能不同的函数,实现了“一个接口,多种方法”。多态性分为静态多态性和动态多态性。在程序运行之前就可以确定要调用哪个函数,称为静态多态性也叫静态绑定;一直要到程序运行时才能确定调用哪个函数,称为动态多态性也叫动态绑定。
  4.1静态多态性差异性分析
  静态多态性在C++中是通过函数重载和运算符重载来实现的,Java只支持方法重载不支持运算符重载。函数重载如果发生在一个类中,那么函数的形式参数的类型或者个数必须要有所不同,如果函数重载时函数的参数类型和参数个数完全相同,这时通常是发生在有继承关系的不同类中。后者常称为覆盖。
  4.2动态多态性差异性分析
  在C++中是通过基类指针变量和虚函数来实现的,在Java中是通过基类对象的引用来实现的。下面比较两者实现的差异。
  在C++中基类指针变量可以指向基类对象或者其派生类对象。例如有基类Shape和基类指针变量Shape *p,基类Shape中一个成员函数area()在其派生类Rectangle和Circle中被覆盖,这时无论基类指针变量p指向基类对象或者派生类Rectangle及Circle对象,通过基类指针变量来访问成员函数area(),即p-> area(),所执行的函数均为基类Shape中的area()函数,而不会根据基类指针变量p指向不同的派生类对象而执行相应的派生类中的函数,并没有实现动态多态性。
  要想实现多态性需要把基类Shape中的成员函数area()定义为虚函数,即在函数头前面加上关键字Virtual,这时通过基类指针变量p来访问成员函数area(),即p-> area(),就会根据p所指向的对象的不同,而调用相应对象的area()函数,实现了动态多态性。
  在Java中基类变量可以引用基类对象或者其派生类对象,与上例类似假如有基类Shape和基类变量Shape p,基类Shape中一个成员函数area()在其派生类Rectangle和Circle中被覆盖,这时通过基类变量p来访问成员函数area(),即p.area(),就会根据p所引用的对象的不同,而调用相应对象的area()函数,实现动态多态性,Java没有虚函数的概念。
  纯虚函数和抽象方法。在上例中基类Shape体现了一个抽象的概念,在其中定义函数area()显然是无意义的,此时可以只定义其函数头,不定义其函数体,基类Shape的各派生类可根据需要实现属于自己的函数area()。在这种情况下,在C++中,基类Shape中的函数area()称为纯虚函数,定义格式为virtual void area()=0;在Java中基类Shape中的函数area()称为抽象方法,定义格式为abstract void area()。在C++中含有一个或多个纯虚函数的类及在Java中含有一个或多个抽象方法的类,称之为抽象类。抽象类不能实例化,即不能生成对象。
   5结束语
  以上对C++和Java在面向对象编程方面的基本概念进行了差异分析,当然它们的差异还有很多,本文只是对较为常用的方面进行了简单的比较与分析。这种分析不在于分出两种语言的高下,而在于更好地运用OOP思想并灵活运用高级语言去设计程序,解决问题。
  参考文献:
  [1]戴特尔.C++大学教程[M] .张引,译.7版.北京:电子工业出版社,2010.
  [2]戴特尔. java大学基础教程[M].刘晓莉,周璐,钱方,译.6版.北京:电子工业出版社,2007.
  [3]张国梁.解析Java中的封装性[J].电脑编程技巧与维护,2012(22).
  [4]邵艳玲.OOP中继承机制剖析[J].电子设计与工程,2011(4).


转载注明来源:https://www.xzbu.com/8/view-1604678.htm