- 关于C#,C++,Java在继承,覆盖和多态,抽象类等几个方面的比较归纳。
- C#,C++用visual studio2005编译通过;java代码用JDK1.4.2编译通过。
- 一、继承中的带参数构造函数
- =============================
- C#示例:
- //myClass.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace myClass
- class myFirst{
- int value_myFirst;
- public myFirst(int f)
- {
- value_myFirst = f;
- }
- }
- class mySecond : myFirst{
- int value_mySecond;
- //构造函数传递参数时,采用base关键字,s在base()中不需重新声明类型int
- public mySecond(int s)
- : base(s)
- {
- value_mySecond = s;
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- }
- }
- }
- ============================
- C++示例:
- #include "stdafx.h"
- class myFirst{
- private:
- int value_myFirst;
- public:
- myFirst(int f){
- value_myFirst = f;
- }
- };
- //继承需要声明继承的方式,此处是public
- class mySecond : public myFirst{
- private:
- int value_mySecond;
- public:
- //构造函数传递参数时,用基类类名,s基类类名()中不需声明类型int
- mySecond(int s) : myFirst(s){
- value_mySecond = s;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- return 0;
- }
- =============================
- java示例:
- package com;
- class myFirst{
- int value_myFirst;
- public myFirst(int f){
- value_myFirst = f;
- }
- }
- //继承采用extends关键字
- class mySecond extends myFirst{
- int value_mySecond;
- public mySecond(int s){
- //传递给基类构造函数时,采用super关键字,而且必须是第一条语句。
- super(s);
- value_mySecond = s;
- }
- }
- public class myCon{
- public static void main(String[] args){
- }
- }
- 注意:
- 1.注释中给出了三者的不同点。
- 2.另外,C++语法中定义的类后面必须加上分号";"
- 3.访问控制权限public等的格式,C#和java比较类似,C++相差很大。
- 二、方法覆盖与多态
- C#示例:
- //myClass.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace myClass
- {
- class myFirst
- {
- int value_myFirst;
- public myFirst(int f)
- {
- value_myFirst = f;
- }
- public void f1()
- {
- System.Console.WriteLine("myFirst.f1()!");
- }
- public virtual void f2() //virtual也可以提到最前面
- {
- System.Console.WriteLine("myFirst.f2()!");
- }
- }
- class mySecond : myFirst
- {
- int value_mySecond;
- public mySecond(int s)
- : base(s)
- {
- value_mySecond = s;
- }
- //使用关键字new覆盖基类中的同名方法
- public new void f1() //new也可以提到最前面
- {
- System.Console.WriteLine("mySeconde.f1()!");
- }
- //error当基类函数myFirst.f1()没有声明为virtual,abstract时不能override!
- //public override void f1()
- //{
- // System.Console.WriteLine("mySeconde.f1()!");
- //}
- //基类函数中虽然声明是virtual,但是仍然可以用new覆盖。
- //public new void f2()
- //{
- // System.Console.WriteLine("mySeconde.f2()!");
- //}
- 基类函数中虽然声明是virtual,用override覆盖。
- public override void f2() //override也可以提到最前面
- {
- System.Console.WriteLine("mySeconde.f2()!");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- myFirst mf = new myFirst(1);
- mySecond ms = new mySecond(2);
- mf.f1(); //myFirst.f1()!
- mf.f2(); //myFirst.f2()!
- ms.f1(); //mySeconde.f1()!
- ms.f2(); //mySeconde.f2()!
- mf = ms; //向上转型之后
- mf.f1(); //myFirst.f1()!
- //mySeconde.f2()! 这是用override的运行结果;
- //如果是new那么,结果是myFirst.f2()!
- mf.f2();
- }
- }
- }
- =============================
- C++示例
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- class myFirst{
- private:
- int value_myFirst;
- public:
- myFirst(int f){
- value_myFirst = f;
- }
- void f1(){
- cout<<"myFirst.f1()!"<<endl;
- }
- vitual void f2(){ //声明为虚函数
- cout<<"myFirst.f2()!"<<endl;
- }
- };
- class mySecond : public myFirst{
- private:
- int value_mySecond;
- public:
- mySecond(int s) : myFirst(s){
- value_mySecond = s;
- }
- //直接覆盖基类函数,无需C#中的new
- void f1(){
- cout<<"mySecond.f1()!"<<endl;
- }
- //覆盖基类需函数
- void f2(){
- cout<<"mySecond.f2()!"<<endl;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- myFirst *mf = new myFirst(1);
- mySecond *ms = new mySecond(1);
- mf->f1(); //myFirst.f1()!
- mf->f2(); //myFirst.f2()!
- ms->f1(); //mySecond.f1()!
- ms->f2(); //mySecond.f2()!
- mf = ms; //向上转型
- mf->f1(); //myFirst.f1()!
- mf->f2(); //mySecond.f2()!
- myFirst mf1(1); //也可以
- mf1.f1();
- return 0;
- }
- =============================
- java示例
- //myCon.java
- package com;
- class myFirst{
- int value_myFirst;
- public myFirst(int f){
- value_myFirst = f;
- }
- public void f1(){
- System.out.println("myFirst.f1()!");
- }
- }
- class mySecond extends myFirst{
- int value_mySecond;
- public mySecond(int s){
- super(s);
- value_mySecond = s;
- }
- public void f1(){
- System.out.println("mySecond.f1()!");
- }
- }
- class myThird extends myFirst{
- int value_myThird;
- public myThird(int t){
- super(t);
- value_myThird = t;
- }
- public void f1(){
- System.out.println("myThird.f1()!");
- }
- }
- public class myCon{
- public static void main(String[] args){
- myFirst mf = new myFirst(1);
- mySecond ms = new mySecond(1);
- myThird mt = new myThird(1);
- mf.f1(); //myFirst.f1()!
- ms.f1(); //mySecond.f1()!
- mt.f1(); //myThird.f1()!
- //向上转型,由于java的动态绑定机制,
- //使得java能够调用派生类mySecond的f1()
- mf = ms;
- mf.f1(); //mySecond.f1()!
- mf = mt;
- mf.f1(); //myThird.f1()!
- }
- }
- 为了实现多态:
- 1.C#基类方法要声明为virtual,派生类覆盖时要用override;
- 2.C++基类方法要声明为virtual,派生类方法直接覆盖;
- 3.java直接覆盖就可以实现多态。
- 三、抽象类
- C#示例
- 上面已经说明,虽然基类方法声明为virtual,以便派生类用override覆盖,但是派生类仍然可以用
- new关键字覆盖(不具有多态性)。
- 可以强制让派生类覆盖基类的方法,将基类方法声明为抽象的,采用abstract关键字。
- 抽象方法没有方法体,由派生类来提供。
- 如果派生类不实现基类的抽象方法,则派生类也需要声明为abstract类
- //myClass.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace myClass{
- //类中只要存在抽象方法,就必须声明为抽象类
- abstract class myFirst
- {
- int value_myFirst;
- public myFirst(int f)
- {
- value_myFirst = f;
- }
- //抽象方法没有方法体,以分号结尾。
- public abstract void f1();
- public void f2()
- {
- System.Console.WriteLine("myFirst.f2()!");
- }
- public virtual void f3()
- {
- System.Console.WriteLine("myFirst.f3()!");
- }
- }
- class mySecond : myFirst
- {
- int value_mySecond;
- public mySecond(int s)
- : base(s)
- {
- value_mySecond = s;
- }
- //覆盖基类抽象方法
- public override void f1()
- {
- System.Console.WriteLine("mySeconde.f1()!");
- }
- //覆盖基类一般方法
- public new void f2()
- {
- System.Console.WriteLine("mySeconde.f2()!");
- }
- //覆盖基类虚拟方法
- public override void f3()
- {
- System.Console.WriteLine("mySecond.f3()!");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- //抽象类和接口不能声明对象
- //myFirst mf = new myFirst(1);
- mySecond ms = new mySecond(2);
- ms.f1(); //mySeconde.f1()!
- ms.f2(); //mySeconde.f2()!
- ms.f3(); //mySecond.f3()!
- //这里向上转型采用强类型转换的方式
- ((myFirst)ms).f1(); //mySeconde.f1()!
- ((myFirst)ms).f2(); //myFirst.f2()!
- ((myFirst)ms).f3(); //mySecond.f3()!
- }
- }
- }
- =============================
- C++示例
- 纯虚函数是在基类中只宣布某个虚函数的原型,并且为了明确通知编译系统,
- 该虚函数在基类中不再定义具体操作代码,而在函数原型结束分号的左侧写
- "=0"标识。这个不包含任何代码的虚函数被成为纯虚函数。
- 抽象类是含有纯虚函数的类,这种类不能声明任何对象,其作用就是为它的
- 派生类提供一种规定输入数据和返回类型接口的模板。
- 从抽象类派生的派生类,必须对基类的纯虚函数进行覆盖;否则编译系统将
- 报错。
- 基类中虚函数被派生类覆盖,则派生类对象调用的是派生类中重新定义的函
- 数代码。
- 基类中虚函数没有被派生类覆盖,则派生类对象调用的是基类中定义的函数
- 代码。
- 基类的纯虚函数在其派生类中必须被覆盖。
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- class myFirst{ //抽象类
- private:
- int value_myFirst;
- public:
- myFirst(int f){
- value_myFirst = f;
- }
- void f1(){ //一般函数
- cout<<"myFirst.f1()!"<<endl;
- }
- virtual void f2(){ //虚函数
- cout<<"myFirst.f2()!"<<endl;
- }
- virtual void f3()=0; //纯虚函数
- };
- class mySecond : public myFirst{
- private:
- int value_mySecond;
- public:
- mySecond(int s) : myFirst(s){
- value_mySecond = s;
- }
- void f1(){ //覆盖基类一般函数
- cout<<"mySecond.f1()!"<<endl;
- }
- void f2(){ //覆盖基类虚函数
- cout<<"mySecond.f2()!"<<endl;
- }
- void f3(){ //覆盖基类纯虚函数
- cout<<"mySecond.f3()!"<<endl;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- //myFirst *mf = new myFirst(1); //抽象类不能创建对象
- mySecond *ms = new mySecond(1);
- ms->f1(); //mySecond.f1()!
- ms->f2(); //mySecond.f2()!
- ms->f3(); //mySecond.f3()!
- //向上转型采用强类型转换
- ((myFirst *)ms)->f1(); //myFirst.f1()!
- ((myFirst *)ms)->f2(); //mySecond.f2()!
- ((myFirst *)ms)->f3(); //mySecond.f3()!
- return 0;
- }
- =============================
- java示例
- java提供了抽象方法的机制abstract method,这种方法不完整,仅有声明
- 没有方法体
- abstract void f();
- 包含抽象方法的类叫抽象类,如果类中包含一个或多个抽象方法,则该类必
- 须被声明为抽象类,用abstract来修饰抽象类。
- 如果从一个抽象类继承,并创建这个新类的对象,必须给抽象基类中所有抽
- 象方法提供方法定义,否则,派生类也是抽象类,也用abstract修饰。
- package com;
- abstract class myFirst{
- int value_myFirst;
- public myFirst(int f){
- value_myFirst = f;
- }
- public void f1(){
- System.out.println("myFirst.f1()!");
- }
- public abstract void f2(); //抽象方法
- }
- //继承采用extends关键字
- class mySecond extends myFirst{
- int value_mySecond;
- public mySecond(int s){
- //传递给基类构造函数时,采用super关键字,而且必须是第一条语句。
- super(s);
- value_mySecond = s;
- }
- public void f1(){
- System.out.println("mySecond.f1()!");
- }
- public void f2(){ //覆盖基类抽象方法
- System.out.println("mySecond.f2()!");
- }
- }
- //如果不实现基类抽象方法,那么此派生类也必须用abstract修饰
- abstract class myThird extends myFirst{
- int value_myThird;
- public myThird(int t){
- super(t);
- value_myThird = t;
- }
- public void f1(){
- System.out.println("myThird.f1()!");
- }
- }
- public class myCon{
- public static void main(String[] args){
- //myFirst mf = new myFirst(1); //抽象函数不能创建对象
- mySecond ms = new mySecond(1);
- //myThird mt = new myThird(1);
- ms.f1(); //mySecond.f1()!
- ms.f2(); //mySecond.f2()!
- ((myFirst)ms).f1(); //mySecond.f1()!
- ((myFirst)ms).f2(); //mySecond.f2()!
- }
- }
- 关于抽象方法和抽象类java和C#比较类似;
- 而C++叫纯虚函数和抽象类。
- 四、接口
- C++中的没有接口的概念,它本身就可以多继承。
- java中接口interface比抽象类abstract更进了一步,可看做"纯粹的抽象类"。
- 它允许创建者为一个类建立其形式,方法名,参数列表,返回类型,但没有
- 任何方法体。接口中也可以包含成员函数,但是他们都是隐含的public和
- final。
- 创建接口时用interface来代替class,前面可以有public,如果不加访问权
- 限,那么它就是默认的包访问权限。
- 接口中的方法默认为public。
- 类实现接口要用implements关键字。
- 接口便于实现多重继承的效果,此处不作具体讨论。
- package com;
- interface myFirst{
- int value_myFirst=1;
- public void f1();
- }
- class mySecond implements myFirst{
- int value_mySecond;
- public mySecond(int s){
- value_mySecond = s;
- }
- public void f1(){
- System.out.println("mySecond.f1()!");
- }
- }
- public class myCon{
- static void play(myFirst mf){
- mf.f1();
- }
- public static void main(String[] args){
- //myFirst mf = new myFirst(1);
- mySecond ms = new mySecond(1);
- ms.f1(); //mySecond.f1()!
- play(ms); //向上转型 mySecond.f1()!
- ((myFirst)ms).f1(); 向上转型 mySecond.f1()!
- }
- }
Java,C#,C++在继承,覆盖和多态,抽象类等几个方面的比较归纳
最新推荐文章于 2024-07-09 16:46:46 发布