Java,C#,C++在继承,覆盖和多态,抽象类等几个方面的比较归纳

  1. 关于C#,C++,Java在继承,覆盖和多态,抽象类等几个方面的比较归纳。
  2. C#,C++用visual studio2005编译通过;java代码用JDK1.4.2编译通过。 
  3. 一、继承中的带参数构造函数
  4. =============================
  5. C#示例:
  6. //myClass.cs 
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text; 
  10. namespace myClass
  11. class myFirst{
  12. int value_myFirst;
  13. public myFirst(int f)
  14. {
  15. value_myFirst = f; 
  16. }
  17. }
  18. class mySecond : myFirst{
  19. int value_mySecond;
  20. //构造函数传递参数时,采用base关键字,s在base()中不需重新声明类型int
  21. public mySecond(int s)
  22. base(s) 
  23. {
  24. value_mySecond = s; 
  25. }
  26. }
  27. class Program
  28. {
  29. static void Main(string[] args)
  30. {
  31. }
  32. }
  33. ============================ 
  34. C++示例:
  35. #include "stdafx.h" 
  36. class myFirst{
  37. private:
  38. int value_myFirst;
  39. public:
  40. myFirst(int f){
  41. value_myFirst = f; 
  42. }
  43. }; 
  44. //继承需要声明继承的方式,此处是public
  45. class mySecond : public myFirst{ 
  46. private:
  47. int value_mySecond;
  48. public:
  49. //构造函数传递参数时,用基类类名,s基类类名()中不需声明类型int
  50. mySecond(int s) : myFirst(s){ 
  51. value_mySecond = s; 
  52. }
  53. }; 
  54. int _tmain(int argc, _TCHAR* argv[])
  55. {
  56. return 0;
  57. ============================= 
  58. java示例:
  59. package com; 
  60. class myFirst{
  61. int value_myFirst;
  62. public myFirst(int f){
  63. value_myFirst = f; 
  64. }
  65. //继承采用extends关键字
  66. class mySecond extends myFirst{
  67. int value_mySecond;
  68. public mySecond(int s){
  69. //传递给基类构造函数时,采用super关键字,而且必须是第一条语句。
  70. super(s); 
  71. value_mySecond = s; 
  72. }
  73. public class myCon{
  74. public static void main(String[] args){
  75. }
  76. 注意:
  77. 1.注释中给出了三者的不同点。
  78. 2.另外,C++语法中定义的类后面必须加上分号";"
  79. 3.访问控制权限public等的格式,C#和java比较类似,C++相差很大。 
  80. 二、方法覆盖与多态 
  81. C#示例:
  82. //myClass.cs 
  83. using System;
  84. using System.Collections.Generic;
  85. using System.Text; 
  86. namespace myClass
  87. {
  88. class myFirst
  89. {
  90. int value_myFirst;
  91. public myFirst(int f)
  92. {
  93. value_myFirst = f;
  94. }
  95. public void f1()
  96. {
  97. System.Console.WriteLine("myFirst.f1()!");
  98. }
  99. public virtual void f2() //virtual也可以提到最前面
  100. {
  101. System.Console.WriteLine("myFirst.f2()!");
  102. }
  103. class mySecond : myFirst
  104. {
  105. int value_mySecond; 
  106. public mySecond(int s)
  107. base(s)
  108. {
  109. value_mySecond = s;
  110. }
  111. //使用关键字new覆盖基类中的同名方法
  112. public new void f1() //new也可以提到最前面
  113. {
  114. System.Console.WriteLine("mySeconde.f1()!");
  115. }
  116. //error当基类函数myFirst.f1()没有声明为virtual,abstract时不能override!
  117. //public override void f1() 
  118. //{
  119. // System.Console.WriteLine("mySeconde.f1()!");
  120. //}
  121. //基类函数中虽然声明是virtual,但是仍然可以用new覆盖。
  122. //public new void f2()
  123. //{
  124. // System.Console.WriteLine("mySeconde.f2()!");
  125. //}
  126. 基类函数中虽然声明是virtual,用override覆盖。
  127. public override void f2() //override也可以提到最前面
  128. {
  129. System.Console.WriteLine("mySeconde.f2()!");
  130. }
  131. class Program
  132. {
  133. static void Main(string[] args)
  134. {
  135. myFirst mf = new myFirst(1);
  136. mySecond ms = new mySecond(2);
  137. mf.f1(); //myFirst.f1()!
  138. mf.f2(); //myFirst.f2()!
  139. ms.f1(); //mySeconde.f1()!
  140. ms.f2(); //mySeconde.f2()! 
  141. mf = ms; //向上转型之后
  142. mf.f1(); //myFirst.f1()!
  143. //mySeconde.f2()! 这是用override的运行结果;
  144. //如果是new那么,结果是myFirst.f2()!
  145. mf.f2(); 
  146. }
  147. }
  148. ============================= 
  149. C++示例 
  150. #include "stdafx.h"
  151. #include <iostream>
  152. using namespace std; 
  153. class myFirst{
  154. private:
  155. int value_myFirst;
  156. public:
  157. myFirst(int f){
  158. value_myFirst = f; 
  159. void f1(){
  160. cout<<"myFirst.f1()!"<<endl;
  161. }
  162. vitual void f2(){ //声明为虚函数
  163. cout<<"myFirst.f2()!"<<endl;
  164. }
  165. }; 
  166. class mySecond : public myFirst{
  167. private:
  168. int value_mySecond;
  169. public:
  170. mySecond(int s) : myFirst(s){
  171. value_mySecond = s; 
  172. }
  173. //直接覆盖基类函数,无需C#中的new
  174. void f1(){
  175. cout<<"mySecond.f1()!"<<endl;
  176. }
  177. //覆盖基类需函数
  178. void f2(){
  179. cout<<"mySecond.f2()!"<<endl;
  180. }
  181. }; 
  182. int _tmain(int argc, _TCHAR* argv[])
  183. {
  184. myFirst *mf = new myFirst(1);
  185. mySecond *ms = new mySecond(1);
  186. mf->f1(); //myFirst.f1()!
  187. mf->f2(); //myFirst.f2()! 
  188. ms->f1(); //mySecond.f1()! 
  189. ms->f2(); //mySecond.f2()! 
  190. mf = ms; //向上转型
  191. mf->f1(); //myFirst.f1()!
  192. mf->f2(); //mySecond.f2()!
  193. myFirst mf1(1); //也可以
  194. mf1.f1();
  195. return 0;
  196. ============================= 
  197. java示例
  198. //myCon.java 
  199. package com; 
  200. class myFirst{
  201. int value_myFirst;
  202. public myFirst(int f){
  203. value_myFirst = f; 
  204. }
  205. public void f1(){
  206. System.out.println("myFirst.f1()!"); 
  207. class mySecond extends myFirst{
  208. int value_mySecond;
  209. public mySecond(int s){ 
  210. super(s); 
  211. value_mySecond = s; 
  212. }
  213. public void f1(){
  214. System.out.println("mySecond.f1()!"); 
  215. class myThird extends myFirst{
  216. int value_myThird;
  217. public myThird(int t){ 
  218. super(t); 
  219. value_myThird = t; 
  220. }
  221. public void f1(){
  222. System.out.println("myThird.f1()!"); 
  223. public class myCon{
  224. public static void main(String[] args){
  225. myFirst mf = new myFirst(1);
  226. mySecond ms = new mySecond(1);
  227. myThird mt = new myThird(1);
  228. mf.f1(); //myFirst.f1()! 
  229. ms.f1(); //mySecond.f1()! 
  230. mt.f1(); //myThird.f1()! 
  231. //向上转型,由于java的动态绑定机制,
  232. //使得java能够调用派生类mySecond的f1() 
  233. mf = ms; 
  234. mf.f1(); //mySecond.f1()!
  235. mf = mt;
  236. mf.f1(); //myThird.f1()! 
  237. }
  238. 为了实现多态:
  239. 1.C#基类方法要声明为virtual,派生类覆盖时要用override
  240. 2.C++基类方法要声明为virtual,派生类方法直接覆盖;
  241. 3.java直接覆盖就可以实现多态。 
  242. 三、抽象类 
  243. C#示例
  244. 上面已经说明,虽然基类方法声明为virtual,以便派生类用override覆盖,但是派生类仍然可以用
  245. new关键字覆盖(不具有多态性)。
  246. 可以强制让派生类覆盖基类的方法,将基类方法声明为抽象的,采用abstract关键字。
  247. 抽象方法没有方法体,由派生类来提供。 
  248. 如果派生类不实现基类的抽象方法,则派生类也需要声明为abstract类 
  249. //myClass.cs 
  250. using System;
  251. using System.Collections.Generic;
  252. using System.Text; 
  253. namespace myClass{
  254. //类中只要存在抽象方法,就必须声明为抽象类
  255. abstract class myFirst 
  256. {
  257. int value_myFirst;
  258. public myFirst(int f)
  259. {
  260. value_myFirst = f;
  261. }
  262. //抽象方法没有方法体,以分号结尾。
  263. public abstract void f1();
  264. public void f2()
  265. {
  266. System.Console.WriteLine("myFirst.f2()!");
  267. public virtual void f3()
  268. {
  269. System.Console.WriteLine("myFirst.f3()!");
  270. }
  271. class mySecond : myFirst
  272. {
  273. int value_mySecond; 
  274. public mySecond(int s)
  275. base(s)
  276. {
  277. value_mySecond = s;
  278. }
  279. //覆盖基类抽象方法
  280. public override void f1() 
  281. {
  282. System.Console.WriteLine("mySeconde.f1()!");
  283. //覆盖基类一般方法 
  284. public new void f2()
  285. {
  286. System.Console.WriteLine("mySeconde.f2()!");
  287. //覆盖基类虚拟方法
  288. public override void f3()
  289. {
  290. System.Console.WriteLine("mySecond.f3()!");
  291. }
  292. class Program
  293. {
  294. static void Main(string[] args)
  295. {
  296. //抽象类和接口不能声明对象
  297. //myFirst mf = new myFirst(1); 
  298. mySecond ms = new mySecond(2);
  299. ms.f1(); //mySeconde.f1()!
  300. ms.f2(); //mySeconde.f2()!
  301. ms.f3(); //mySecond.f3()! 
  302. //这里向上转型采用强类型转换的方式
  303. ((myFirst)ms).f1(); //mySeconde.f1()! 
  304. ((myFirst)ms).f2(); //myFirst.f2()!
  305. ((myFirst)ms).f3(); //mySecond.f3()!
  306. }
  307. }
  308. ============================= 
  309. C++示例 
  310. 纯虚函数是在基类中只宣布某个虚函数的原型,并且为了明确通知编译系统,
  311. 该虚函数在基类中不再定义具体操作代码,而在函数原型结束分号的左侧写
  312. "=0"标识。这个不包含任何代码的虚函数被成为纯虚函数。 
  313. 抽象类是含有纯虚函数的类,这种类不能声明任何对象,其作用就是为它的
  314. 派生类提供一种规定输入数据和返回类型接口的模板。 
  315. 从抽象类派生的派生类,必须对基类的纯虚函数进行覆盖;否则编译系统将
  316. 报错。 
  317. 基类中虚函数被派生类覆盖,则派生类对象调用的是派生类中重新定义的函
  318. 数代码。
  319. 基类中虚函数没有被派生类覆盖,则派生类对象调用的是基类中定义的函数
  320. 代码。
  321. 基类的纯虚函数在其派生类中必须被覆盖。 
  322. #include "stdafx.h"
  323. #include <iostream>
  324. using namespace std; 
  325. class myFirst{ //抽象类
  326. private:
  327. int value_myFirst;
  328. public:
  329. myFirst(int f){
  330. value_myFirst = f; 
  331. void f1(){ //一般函数
  332. cout<<"myFirst.f1()!"<<endl;
  333. }
  334. virtual void f2(){ //虚函数
  335. cout<<"myFirst.f2()!"<<endl;
  336. virtual void f3()=0; //纯虚函数
  337. }; 
  338. class mySecond : public myFirst{
  339. private:
  340. int value_mySecond;
  341. public:
  342. mySecond(int s) : myFirst(s){
  343. value_mySecond = s; 
  344. void f1(){ //覆盖基类一般函数
  345. cout<<"mySecond.f1()!"<<endl;
  346. void f2(){ //覆盖基类虚函数
  347. cout<<"mySecond.f2()!"<<endl;
  348. }
  349. void f3(){ //覆盖基类纯虚函数
  350. cout<<"mySecond.f3()!"<<endl;
  351. }
  352. }; 
  353. int _tmain(int argc, _TCHAR* argv[])
  354. {
  355. //myFirst *mf = new myFirst(1); //抽象类不能创建对象
  356. mySecond *ms = new mySecond(1); 
  357. ms->f1(); //mySecond.f1()!
  358. ms->f2(); //mySecond.f2()!
  359. ms->f3(); //mySecond.f3()! 
  360. //向上转型采用强类型转换
  361. ((myFirst *)ms)->f1(); //myFirst.f1()!
  362. ((myFirst *)ms)->f2(); //mySecond.f2()!
  363. ((myFirst *)ms)->f3(); //mySecond.f3()! 
  364. return 0;
  365. ============================= 
  366. java示例 
  367. java提供了抽象方法的机制abstract method,这种方法不完整,仅有声明
  368. 没有方法体
  369. abstract void f();
  370. 包含抽象方法的类叫抽象类,如果类中包含一个或多个抽象方法,则该类必
  371. 须被声明为抽象类,用abstract来修饰抽象类。
  372. 如果从一个抽象类继承,并创建这个新类的对象,必须给抽象基类中所有抽
  373. 象方法提供方法定义,否则,派生类也是抽象类,也用abstract修饰。 
  374. package com; 
  375. abstract class myFirst{
  376. int value_myFirst;
  377. public myFirst(int f){
  378. value_myFirst = f; 
  379. }
  380. public void f1(){
  381. System.out.println("myFirst.f1()!"); 
  382. public abstract void f2(); //抽象方法 
  383. //继承采用extends关键字
  384. class mySecond extends myFirst{
  385. int value_mySecond;
  386. public mySecond(int s){
  387. //传递给基类构造函数时,采用super关键字,而且必须是第一条语句。
  388. super(s); 
  389. value_mySecond = s; 
  390. }
  391. public void f1(){
  392. System.out.println("mySecond.f1()!"); 
  393. public void f2(){ //覆盖基类抽象方法
  394. System.out.println("mySecond.f2()!"); 
  395. //如果不实现基类抽象方法,那么此派生类也必须用abstract修饰
  396. abstract class myThird extends myFirst{ 
  397. int value_myThird;
  398. public myThird(int t){ 
  399. super(t); 
  400. value_myThird = t; 
  401. }
  402. public void f1(){
  403. System.out.println("myThird.f1()!"); 
  404. public class myCon{
  405. public static void main(String[] args){
  406. //myFirst mf = new myFirst(1); //抽象函数不能创建对象
  407. mySecond ms = new mySecond(1);
  408. //myThird mt = new myThird(1); 
  409. ms.f1(); //mySecond.f1()!
  410. ms.f2(); //mySecond.f2()!
  411. ((myFirst)ms).f1(); //mySecond.f1()!
  412. ((myFirst)ms).f2(); //mySecond.f2()!
  413. }
  414. 关于抽象方法和抽象类java和C#比较类似;
  415. 而C++叫纯虚函数和抽象类。 
  416. 四、接口
  417. C++中的没有接口的概念,它本身就可以多继承。 
  418. java中接口interface比抽象类abstract更进了一步,可看做"纯粹的抽象类"
  419. 它允许创建者为一个类建立其形式,方法名,参数列表,返回类型,但没有
  420. 任何方法体。接口中也可以包含成员函数,但是他们都是隐含的public
  421. final。 
  422. 创建接口时用interface来代替class,前面可以有public,如果不加访问权
  423. 限,那么它就是默认的包访问权限。
  424. 接口中的方法默认为public。 
  425. 类实现接口要用implements关键字。 
  426. 接口便于实现多重继承的效果,此处不作具体讨论。 
  427. package com; 
  428. interface myFirst{
  429. int value_myFirst=1; 
  430. public void f1();
  431. class mySecond implements myFirst{
  432. int value_mySecond;
  433. public mySecond(int s){ 
  434. value_mySecond = s; 
  435. }
  436. public void f1(){
  437. System.out.println("mySecond.f1()!"); 
  438. }
  439. public class myCon{
  440. static void play(myFirst mf){
  441. mf.f1(); 
  442. }
  443. public static void main(String[] args){
  444. //myFirst mf = new myFirst(1);
  445. mySecond ms = new mySecond(1); 
  446. ms.f1(); //mySecond.f1()! 
  447. play(ms); //向上转型 mySecond.f1()!
  448. ((myFirst)ms).f1(); 向上转型 mySecond.f1()!
  449. }
  450. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值