"I am Father(还是传入一个子类的实例)"
实际上需要向上转型,需要强制转换!
我跟你改写后的程序:<try it!>
//Father.java
public class Father{
public void draw(Father Iam){
System.out.println("I am Father");
}
}
//Son.java
public class Son extends Father{
public void draw(Son Iam){
System.out.println("I am Son");
}
}
//MainTest.java
public class MainTest{
public void test(Father a){
a.draw(a);
}
public static void main(String[] args){
Father father=new Father();
Son son=new Son();
MainTest m=new MainTest();
m.test(father);
m.test(son);
}
}
实际上需要向上转型,需要强制转换!
我跟你改写后的程序:<try it!>
//Father.java
public class Father{
public void draw(Father Iam){
System.out.println("I am Father");
}
}
//Son.java
public class Son extends Father{
public void draw(Son Iam){
System.out.println("I am Son");
}
}
//MainTest.java
public class MainTest{
public void test(Father a){
a.draw(a);
}
public static void main(String[] args){
Father father=new Father();
Son son=new Son();
MainTest m=new MainTest();
m.test(father);
m.test(son);
}
}
我不知道什么是late binding机制,但是,这在java里是绝对做不到的。
但是在C++里可以做到://Father.h
#ifndef _FATHER__
#define _FATHER__
#include <iostream>
using namespace std;class Father{
public:
virtual void draw(){
cout<<"I am Father"<<endl;
};
};
#endif //_FATHER__
//Son.h
#ifndef _SON__
#define _SON__
#include "Father.h"class Son : public Father{
public:
virtual void draw(){
Father::draw();
//cout<<"I am son"<<endl;
};
};
#endif //_SON__//main.cpp
#include "Son.h"
#include "Father.h"void test(Father * param)
{
param->draw();
}void main()
{
Father *father=new Father();
Son *son=new Son();
test(father);
test(son);
}//运行结果为:
I am Father
I am Father
我在你的draw函数中加入一个参数,使draw具备“型别检查的能力”。
你在调用MainTest的test函数时,由于Test要求的是Father型,
son此时被强制转型为Father型了。这样,调用就是Father的draw。
UP的UP superLee(superLee)你的方法a.draw(a);这里哪个a是public void test(Father a)传递的a啊?
Father::draw()或者cout<<"I am son"<<endl中一个,就可以完成两种效果。在java中可行么?按照superLee给的代码,在不改动父类的情况下是要永远打印I am Father了对么?也就是说,我希望可以在子类中自由选择override or not.
但是superLee给出的方法很巧妙,能不能给我解释一下为什么加入参数就可以强制类型转换呢?而如果我在MainTest中写m.test((Father)son)毫无用处,仍然打印I am Son
superlee的做法很巧妙,但是不能达到需要的效果,同时也没有用到多态,用到了方法名重载,Son里的draw(Son son)重载了Father的draw(Father father)。这样一来,Son里就有了两个方法,
一个是继承自父类的draw(Father father),另外一个是自己的draw(Son son);
在调用draw的时候,会根据输入参数的类型来做判断,如果输入参数类型是Son 型,
就调用draw(Son son);如果是Father 类型和Father 的其他子类,那么就调用draw(Father father)。对于 NickPac (悠悠) 提出的要求,其实还有一个很简单的方法,既然在Son中想调用Father的draw方法,那么,在Son中就不overwrite父类的draw方法:
//Father.java
public class Father{
public void draw(){
System.out.println("I am Father");
}
}
//Son.java
public class Son extends Father{
}
//MainTest.java
public class MainTest{
public void test(Father a){
a.draw();
}
public static void main(String[] args){
Father father=new father();
Son son=new Son();
MainTest m=new MainTest();
m.test(father);
m.test(son);
}
}
我做的作业
会有用的
通俗的解释多态性:
多态性:“同名”但“不同的功能实现形式”(即在基类中提供一种方法的实现,但可以在子类对
该方法加以重写并给出自己的实现但要求保持功能的实现形式相同)。
重载是多态的一种实现形式,所以在我的代码里面用到了多态!这一点可以说是勿庸置疑的!
2、为什么只出现一种结果,请看一下下面的代码:
//MainTest.java
public class MainTest{
public void test(Son a){
a.draw(a);
}
public static void main(String[] args){
Father father=new Father();
Son son=new Son();
MainTest m=new MainTest();
//m.test(father);
m.test(son);
}
}
3、为什么java里面需要加入参数的形式才能打印出I am Father而“MainTest中写m.test
((Father)son)毫无用处,仍然打印I am Son”
是这样,java里面对于向上转型有很严格的规定,必须用显式的方法来进行。
而对于向下转型要严格的多,我在函数里加入参数,正是为了让它显式的转型。
对于java的转型记得有这样一个比喻:
父母<相当于父类>可以随便干预子女的事情<转型到子类>,
而子女是不可以随便干预父母的事情的<转型到父类>,
但如果你提出申请<显式的方法转型>,还是可以通融一下。
最后提一下:java的转型<cast>与C++是不一样的!
楼上的仁兄,对于多态,重载,覆盖的概念,我想你还不是很理解。
有必要澄清一下,多态是指,对象在调用某个方法(假设为:void methodA())的时候,是根据对象的类类型来做判断,如果这个类中有methodA()方法,并且要有同样的参数和返回值,那么它就调用这个方法,如果没有methodA()方法,那么就到它的直接父类取找,如果还是没有,在往上找,直到找到为止,肯定是能找到的,如果找不到的话,编译都通不过。覆盖,子类重写父类的方法,所谓重写,那么,方法名、返回值和参数都要相同才叫重写。重载,方法名相同,返回值相同,但是参数不同。因此多态是依靠覆盖来实现的。在你的程序中,是方法名相同,返回值相同,但参数不同,只能算是重载,根本没有覆盖一说,所以多态就谈不上了。你可以看看这篇文章,
http://www.c-view.org/journal/004/cpp_critique.htm