黑马程序员技术交流社区
标题: 求大神详细教一下多态的概念 [打印本页]
作者: 马姗姗 时间: 2013-8-19 10:14
标题: 求大神详细教一下多态的概念
父类的引用对应到子类的对象就叫做多态。这句话具体应该怎么理解呢?
有没有一个很好的例子来描述这句话呢?
作者: 黄兴旺 时间: 2013-8-19 10:30
老毕那里面不是有个很好的例子么??亲 好好看看吧
作者: 漪顿 时间: 2013-8-19 11:03
要理解多态性,首先要知道什么是“向上转型”。
我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过
Cat c = new Cat();
实例化一个Cat的对象,这个不难理解。但当我这样定义时:
Animal a = new Cat();//其中Animal a 叫做Animal类型的引用(父类引用), = 叫做指向,new Cat()叫子类对象
这代表什么意思呢?
很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特,
定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;
(就是说 Cat里面有一种吃鱼的方法,而父类Animal中没有,那么Animal a 是不可以调用吃鱼方法的。)
同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
以上是我查阅整理的希望对你有帮助。
作者: 黑马-文鸿利 时间: 2013-8-19 11:28
class Father{
void print(){};
}
class Son extends Father{
void print(){System.out.println("子类中!");}
void show(){System.out.println("show 中!");}
}
class Demo{
public static void main(String args[]){
Father obj=new Son();
obj.print();
obj.show(); //这个调用会报错!
}
}
1 .如果你想实现多态,那么必须有三个条件,父类引用,子类对象,方法覆盖
你这里如果Fathor类有一个show()方法,那么形成方法覆盖,那么此时就可以这么写:obj.show(),此刻形成了多态.
2. 没有方法覆盖,那你这里只能解释为父类引用去访问一个子类的方法,当然,父类引用没有这么大范围的权限,当然会报错
PS:多态实际上是一种机制,在编译时刻,会生成一张虚拟表,来记录所有覆盖的方法,没有被覆盖的方法是不会记录到这张表的.若一个父类引用调用了没有覆盖的子类方法,那么是不符合该表的,那么编译时刻就会报错.
在执行程序的时候,虚拟机会去这张虚拟表中找覆盖的方法,比如引用中实际上存的是一个子类对象引用,那么就会去找子类中的相应的覆盖的方法来执行
作者: 吴光新 时间: 2013-8-19 12:04
请你卖给我一只家禽,你可以给一只小鸡,也可以给一只小鸭,但你不能给一头猪对吧。
家禽是小鸡和小鸭的父类吧?但猪不属于家禽类
可以
家禽 poultry = new 小鸡();
家禽 poultry = new 小鸭();
但不可以
家禽 poultry = new 猪();
这就是你说的:父类的引用对应到子类的对象
作者: 刘劲松 时间: 2013-8-19 12:04
恰好,这里有一个。你看看有没有什么启示:
import java.lang.*
public class OverrideDemo
{
public static void main(String[] args)
{
A2 obj1=new A2();
obj1.showVar1();
System.out.println("obj1.var1="+obj1.var1);
System.out.println("=================");
obj2.showVar1();
System.out.println("obj2.var1="+obj2.var1);
System.out.println("=================");
A2 obj3=new B2();
obj3.showVar1();
System.out.println("obj3.var1="+obj3.var1);
}
}
class A2
{
int var1=100;
protected void showVar1()
{
System.out.println("A2定义的showVar1() var1="+var1);
}
}
class B2 extends A2
{
double var1=1111.111;
public void showVar1()
{
System.out.println("B2定义的showVar1() var1="+var1);
}
}
复制代码执行结果如下:
A2定义的showVar1() var1=100
obj1.var1=100
=================
B2定义的showVar1() var1=1111.111
obj2.var1=1111.111
=================
B2定义的showVar1() var1=1111.111
obj3.var1=100
----------------------------------------------------------------------------
很简单的一个例子,多态中重载的不同,记住成员变量和成员函数重载的不同规则。理解也很容易,
A2 obj3=new B2();
obj3.showVar1();
这种向下转换的方式,开辟的对象是父类类型的对象。
总结为:成员函数在多态调用时,编译看左边(引用型变量所属类中有调用方法,编译通过,没有,编译失败),运行看右边。
成员变量的话,无论编译,运行都看左边。
作者: 黑马-马磊 时间: 2013-8-19 12:38
我的理解不太完全!
父类看成武林高手
子类看成徒弟,菜鸟一只!
父类 变量名=new 子类();
我的理解是
师傅无聊化装成菜鸟的过程!
new 子类()看成化妆目标和过程!//不一定是菜鸟,也可能是一流高手。翻过来就不行了!
作者: EYE_SEE_YOU 时间: 2013-8-19 12:42
好新颖的说法
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |