多态:简单的说就是父类型的引用指向子类型的对象。 形式 : Father father = new Son ();但是通过引用类型的变量可以调用的是子类的方法(指向谁调用谁),但是调用子类的方法时,首先要看是不是子类重写了父类的方法;如果子类重写了这个父类的方法,就可以通过父类型的引用子类的方法。 Father father = new Son();这个过程体现了类型类型的转化; 有向上类型的转化与向下类型的转化;但是向下类型的转化,必须要强制转化。例如: Father father = new Son(); Son son =(son) father;//强制类型的转化 son.method(); 在向下强制类型转换的过程中,要转换成那个子类的引用,在父类实例化时,父类的引用就要指向这个子类的对象。 如果是:Father father = new father(); Son son = (Son)father; son.method();//如果父类的引用指向 父类的对象,再强制转化时,就会报异常 ClassCastException 多态的简单代码形式: public class Test { public static void main(String [] args) { Father father = new Son(); Son son = (Son) father; son.method(); } } class Father { public void method() { System.out.println("Father"); } } class Son extends Father { public void method() { System.out.println("Son"); } }
#include <iostream> using namespace std; class IHello{ public: virtual void Hello(); };class IWorld{ public: virtual void World(); };class HelloWorld: public IHello, public IWorld{};void IHello::Hello(){ cout<<"Hello"<<endl; }void IWorld::World(){ cout<<"World"<<endl; }int main(){ IHello* hello = new HelloWorld; IWorld* world = (IWorld*)(void*)hello; world->World(); }
其实多态的实现,通常分成两种方式:重载和覆盖 重载,就是方法名相同而参数结构不同,能实现同一个参数名的不同实现。 覆盖,就是子类重写父类的同名同参数结构方法,然后同一个父类引用,使用不同的具体子类,能实现不同的功能。 而父类引用调用子类,这属于比较核心的一块。楼主的疑问:【向上向下的转型老是不知谁指向谁】 简单的举个例子: Person p = new Son(); 之前看过一句很经典的话:编译看左,运行看右! 就是说,Person能调用Son,这是在编译的时候检查的,只要有继承实现关系,都能通过检查; 而运行时,实际上调用的是Son类。(这就是楼主的问题答案,实际调用的都是右边的)
形式 : Father father = new Son ();但是通过引用类型的变量可以调用的是子类的方法(指向谁调用谁),但是调用子类的方法时,首先要看是不是子类重写了父类的方法;如果子类重写了这个父类的方法,就可以通过父类型的引用子类的方法。
Father father = new Son();这个过程体现了类型类型的转化;
有向上类型的转化与向下类型的转化;但是向下类型的转化,必须要强制转化。例如:
Father father = new Son();
Son son =(son) father;//强制类型的转化
son.method();
在向下强制类型转换的过程中,要转换成那个子类的引用,在父类实例化时,父类的引用就要指向这个子类的对象。
如果是:Father father = new father();
Son son = (Son)father;
son.method();//如果父类的引用指向 父类的对象,再强制转化时,就会报异常 ClassCastException
多态的简单代码形式:
public class Test
{
public static void main(String [] args)
{
Father father = new Son();
Son son = (Son) father;
son.method();
}
}
class Father
{
public void method()
{
System.out.println("Father");
}
}
class Son extends Father
{
public void method()
{
System.out.println("Son");
}
}
#include <iostream>
using namespace std;
class IHello{
public:
virtual void Hello();
};class IWorld{
public:
virtual void World();
};class HelloWorld: public IHello, public IWorld{};void IHello::Hello(){
cout<<"Hello"<<endl;
}void IWorld::World(){
cout<<"World"<<endl;
}int main(){
IHello* hello = new HelloWorld;
IWorld* world = (IWorld*)(void*)hello;
world->World();
}
重载,就是方法名相同而参数结构不同,能实现同一个参数名的不同实现。
覆盖,就是子类重写父类的同名同参数结构方法,然后同一个父类引用,使用不同的具体子类,能实现不同的功能。
而父类引用调用子类,这属于比较核心的一块。楼主的疑问:【向上向下的转型老是不知谁指向谁】
简单的举个例子:
Person p = new Son();
之前看过一句很经典的话:编译看左,运行看右!
就是说,Person能调用Son,这是在编译的时候检查的,只要有继承实现关系,都能通过检查;
而运行时,实际上调用的是Son类。(这就是楼主的问题答案,实际调用的都是右边的)
谢谢。看到了一些“持有对方的引用”
就是比如子类里
Person p;
Son(Person p)
{
this.p = p;
}
这样的,有什么作用?
这个需要结合实际情况分析了!
比如说:有时候有一些层级关系的结构会这么做,例如Person链,那么这个this.p就可以看成是next指针,一层一层传下去!
具体还是得看什么场景,才能分析他的企图。