黑马程序员技术交流社区

标题: 多态的问题 [打印本页]

作者: 子康JAVA    时间: 2013-6-5 18:41
标题: 多态的问题
本帖最后由 子康JAVA 于 2013-6-5 21:09 编辑

新手上路,感觉java的多态性太难理解了,能不能给我详细的解释下

作者: yp324    时间: 2013-6-5 18:49
class Father{
public void A(){}
public static void S(){}
}
class Son{
public void B(){}
public void A(){//TODO}
public static void S(){//TODO}
}
1.多态的体现
   a.父类引用指向子类对象。
   b.父类的引用也可以接收自己的子类对象。
  2.多态的前提
   必须是类与类之间有父子关系(继承或是实现)。
   父类引用指向子类对象,但在使用子类对象方法功能时,必须是自己中也有该方法(功能)的定义。
  3.多态的好处
   a.多态的出现大大的提高了程序的扩展性。
  4.多态的弊端

Father father = new Father(); Father son = new Son();这就是多态
另外提醒你需要注意的问题:
1、成员函数在多太调用时,编译看左边,运行看右边
Father  son = new Son();
son.B();
编译报错,因为父类没有A方法
son.A();
编译正确,执行son中的A方法
2、静态函数的特点:无论编译和运行,都参考左边,原理:静态继承不会覆盖父类函数
son.S(){}
执行父类的方法,因为S方法是静态的

作者: 郭天龚    时间: 2013-6-5 18:56
        每个Java程序的引用变量(你这个里面引用变量就是a),都有编译类型和运行类型。编译就是将 .java文件编译成 .class文件,而运行就是 .class文件在操作系统上运行。
那么,这个时候,就出现多态了,一个类,他在编译时期和运行时期相同的动作却出现了不同的结果。Animal a = new Cat(); 如你的这个,a在编译的时候,只能调用Animal里面的方法和属性,而不能调用Cat的方法和属性。
        要注意的是,这样写Animal a = new Cat(); 后面的Cat必须继承Animal类,为了出现多态,Cat类中必须重写Animal的方法。所谓重写,就是要有和父类Animal中有一模一样的方法。
编译的时候,a调用的是自己的方法,我们可以预测结果,但是运行的时候,却出现了不同的结果,因为他这个时候调用的是Cat的方法,这就是多态.面向对象吗,动物是总类,他又自己特定方法,继承与他的其他动物也有这个特定方法,但是他们方法结果不一样的。多态,也仅仅是指类的方法,与属性没有任何关系。
  Animal a = new Cat(); a这个引用变量指向了Cat这个对象。在运行的时候调用的是Animal的子类Cat的非静态成员函数。
作者: 夏一站    时间: 2013-6-5 19:21
SUN目前的JVM实现机制,类实例的引用就是指向一个句柄(handle)的指针,这个句柄是一对指针:  
一个指针指向一张表格,实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型);  另一个指针指向一块从java堆中为分配出来内存空间。
1、通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
2、不能把父类对象引用赋给子类对象引用变量。
3、一个类型引用只能引用引用类型自身含有的方法和变量。[code]package domatic;   
//定义超类superA  class superA
 {  int i = 100;   
void fun(int j) {  j = i;  
System.out.println("This is superA");  }  }  
 
// 定义superA的子类subB 
 class subB extends superA 
{  int m = 1;   
void fun(int aa)
 {  
System.out.println("This is subB");  
}
  }  
// 定义superA的子类subC  
class subC extends superA
 {  int n = 1;   
void fun(int cc) 
{  
System.out.println("This is subC"); 
 }
  }   
class Test
 {  
public static void main(String[] args)
 {  superA a = new superA();  
subB b = new subB();  
subC c = new subC(); 
 a = b;  a.fun(100);
  a = c;  a.fun(200); 
 } 
 }  

上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,    c,
通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
作者: 子康JAVA    时间: 2013-6-5 21:09
谢谢各路大神的细心讲解,很受益




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2