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

C++与JAVA多态相同与不同

2017-03-10 21:25 190 查看
C++与Java中继承与多态是十分重要的特性,但在学习中发现并没有一篇将这两者做比较与总结,所以写下自己观点,本文中有自己的原创,也有引用网上经典的分析与例子,引用部分会说明并贴出链接。不足之处希望大家指正。

首先说一下Java与C++继承的不相同特性,也是最容易让人混淆的三个概念:重载,重写,重定义

重载overload:重载是同名函数具有不同的形参列表(参数类型或数量),只有在同一个类内的函数才能叫做重载。

重写Overriding:重写是C++中的概念,子类与父类有同名函数,仅仅只需要函数名称相同,形参表可以不同,则子类会覆盖父类的函数。虽然很多人在Java中也提到了重写的概念,但实际上是重定义(很快会给出解释),因为在Java中子类会继承父类同名但参数不同的函数,作为重载,而在C++中父类的同名函数是不会继承的。下面分别给出C++和Java的例子。

C++

class A
{
public:
void show(string s)
{
cout << s;
}
};
class B:public A
{
public:
void show(int i)
{
cout << i;
}

};
int main()
{
int i = 0;
string s = "1";
B b;
b.show(i);
b.show(s);

}


以上代码编译后出现error C2664: “void B::show(int)”: 无法将参数 1 从“std::string”转换为“int”

可以看出B并没有继承A的参数为string的show函数,与此类似,但是在Java中就不一样了

Java

public class A {
public void show(String s)
{
System.out.println(s);
}
}
public class B extends A{
public void show(int i)
{
System.out.println(i);
}
static public void main(String[]args){
int i=0;
String s="1";
B b=new B();
b.show(i);
b.show(s);

}

}


以上代码会输出0,1;可以看出Java会继承父类的同名但形参不同的函数

重定义redefining:重定义是重写的加强版本,必须要求子类中函数名以及形参和父类完全相同,在C++中,子类不会继承父类同名函数,所以重定义自然在子类中唯一;在Java中由于函数与父类完全相同,所以重定义会覆盖父类的同名同参函数(这也是为什么上面我说很多人把重定义当成了重写),重定义是实现多态的关键技术

下面来说多态,多态的实现机制C++与Java几乎是相同的。首先解释一下什么叫做多态。

多态是指父类引用子类对象,但是能够表现出子类的特性(调用子类的函数或方法)。

多态分为静态多态与动态多态,静态多态即使我不讲,你也已经会用了(只是你自己不知道);动态多态的实现需要两个关键技术:父类对子类的引用;子类重定义父类的虚函数

在Java中,父类对子类的引用很自然,就像声明一个对象一样,而在C++中必须使用指针;另外Java中没有修饰符的函数都默认为虚函数,所以在子类中只需要重定义父类函数即可,而C++必须显示加上virtual修饰符,再重定义才可以。

下面分别是C++多态实现和Java多态实现。

C++

class A
{
public:
virtual void show()
{
cout <<"A";
}
};
class B:public A
{
public:
void show()
{
cout << "B";
}

};
int main()
{
A*p = new B();
p->show();
}


运行之后输出B,可以看出A的指针却调用了B类中的show函数。

Java

public class A {
public void show()
{
System.out.println("A");
}
}
public class B extends A{
public void show()
{
System.out.println("B");
}
static public void main(String[]args){
A p=new B();
p.show();

}

}


运行结果同样为B

以上为原创部分,割;接下来就要在理解清楚概念的基础上来点小练习了,下面的例子为转载,也很经典。

首先是Java的继承经典题目。引用自深入理解Java多态性

public class A {
public String show(D obj) {
return ("A and D");
}

public String show(A obj) {
return ("A and A");
}

}

public class B extends A{
public String show(B obj){
return ("B and B");
}

public String show(A obj){
return ("B and A");
}
}

public class C extends B{

}

public class D extends B{

}

public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();

System.out.println(a1.show(b));   ①
System.out.println(a1.show(c));   ②
System.out.println(a1.show(d));   ③
System.out.println(a2.show(b));   ④
System.out.println(a2.show(c));   ⑤
System.out.println(a2.show(d));   ⑥
System.out.println(b.show(b));    ⑦
System.out.println(b.show(c));    ⑧
System.out.println(b.show(d));    ⑨
}
}

答案:
①   A and A
②   A and A
③   A and D
④   B and A
⑤   B and A
⑥   A and D
⑦   B and B
⑧   B and B
⑨   A and D


具体解释大家可以阅读原文,已经解释的十分清楚了,我想重点强调的是调用的优先问题 ,优先级由高到低依次为:this.show(Object)、super.show(O)、this.show((super)O)、super.show((super)O)。

接下来是C++的多态题目,引用自从一个面试题谈C++多态性

class A
{
public:
void foo()
{
printf("1\n");
}
virtual void fun()
{
printf("2\n");
}
};
class B : public A
{
public:
void foo()
{
printf("3\n");
}
void fun()
{
printf("4\n");
}
};
int main(void)
{
A a;
B b;
A *p = &a;
p->foo();
p->fun();
p = &b;
p->foo();
p->fun();
return 0;
}

答案:1214
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java c语言 多态 继承