java多态

原创 2012年03月27日 23:25:40



       提到java的多态,想必是很多java新手一个较难跳跃的坎。
         下面,我将自己理解的多态在这里给总结下。
         多态,分为编译时的多态和运行时多态。
         1.编译时的多态。
         首先,说到一个科学概念的时候,我们应该清楚,这个概念只是描述了一种现象或者         规律的一个抽象词汇,所以我们应该做的是,去查找这个概念真正描述的现象。
         什么是编译时的多态呢?
         其实说白了,就是方法的重载,这种现象就体现了编译时的多态,是面向对象语言的         多态的一种体现。但,它是编译时的多态,后面会说运行时多态。
         就是说,编译器在编译的时候,它会自己去判断,调用哪一个重载的方法。这种机制          ,就体现了多态,而不需要人为的去指定。
         编译器,会自动的根据,方法的参数的个数,类型,自动的调用对应的方法,而不需         要人为的干预,这种现象就体现了多态。
         这种多态一个简单的例子就是

void println(int i){};

     void println(float i){};
     void println(string str){};
          这三个方法在调用的时候,编译器的自动选择,就体现了多态,这种多态比较简单,这里就不再多做解释了。

         2.运行时的多态

          说到运行时的多态,当然还是要去看,什么样的现象我们把它称为多态呢?

          这样一种现象我们把它称为多态:

         

class Employee{
void getDetail(){
     System.out.println("is a Employee");
     }
}
class Manager extends Employee{
void getDetail(){
     System.out.println("is a Manager!");
     }
void getDepartment(){}
}
class Secretary extends Employee{
void getDetail(){
     System.out.println("is a Secretary");
     }
void getSalary(){}
}

//下面那个静态的方法的调用体现了多态。
public class test{
static void getDetails(Employee e){
e.getDetail();
}
public static void main(String[] args){
Manager e= new Manager();
Secretary e1= new Secretary();
Employee e2= new Employee();
  //下面的三个函数的调用体现了多态
  getDetails(e);
  getDetails(e1);
  getDetails(e2);
 }
}
如上面注释中所示,那三个函数就体现了多态这种现象。

        就是说,子类的对象也是父类的对象,我们在用函数调用的时候,如果定义这个函数接口是父类这种类型的,那么所有重写了父类的那些方法的子类,都可以作为这个函数的参数,函数在编译的时候,并不知道,这个参数到底是父类的还是子类的,具体的类型它并不清楚,只有当运行的时候,实实在在的调用的时候,系统会自动的判别是哪种类型,而程序员不用管到底是谁。

        看了这种现象之后,很显然的会有很多的疑问在里面。

        疑问一:

       传过来的那个参数,如果是该类型的子类,那么这个转化合法吗?转换的机理又是什么?

       答:如果传进去的参数是子类,会将子类“上溯造型”,将该变量自动转换为父类那种类型。

         那么什么叫上溯造型呢?

        就是将子类的对象的引用,转换成父类对象的类型的引用,体现了造型,又因为上从下到上的一级转化,又体现了向上,综上可知叫做上溯造型。

      疑问二:

     你怎么知道传进来的那个类型,这个类中会有要调用的那个方法呢?

      答:请看我们多态现象下面的解释,就是说,要实现多态,必须是子类当中重写了父类的方法,这样就可以实现不用管类型,到时候调用的时候运行时自动检测。

     如果深入的理解的话,这个问题其实还要说到,上溯造型上,一般课本讲述的时候,会先讲述上溯造型,这里我们是先看多态这个现象,然后看上溯造型,所有这点有点不好理解。

      其实呢,本质上,那个传值的过程就是个上溯造型的过程,如Employee e=e1//e1=new manager();就是说,把e1上溯造型为Employee类型的,下面说下上溯造型一些要点。

      上溯造型:

      把子类的对象的引用,转化为父类类型的变量,那么这个变量就属于父类类型了。

     注意:

     1.该变量可以调用父类中所有的方法成员。

     2.该变量还可以调用子类中重写了父类的方法。

     3.该变量不可以调用子类中特有的方法。

注意的三点,很好理解,因为这个变量已经造型为父类类型,那么它就不可以随随便便的调用子类的东西了,它只能要么调用父类中的东西,要么调用父类和子类的共有的东西,反正就是它属于父类,它可以调用父类所有东西,包括哪些被子类重写了的方法,我们多态就是体现在那些被子类重写了的方法上,就是特别的该变量在调用重写的那些方法时,系统怎么判断该调用谁呢?是父类的呢?还是子类的呢?就看运行时这个变量是谁了。这就是多态。

         疑问三:

       上溯造型可以调用重写的方法,那么那些子类中特有的成员变量被隐藏,那么在多态时候,我如果想调用那些子类的特有的东西的时候该怎么办呢?

      答:问的好!我们在多态的时候引用,子类特有的成员呢?ok

         我们的强制类型转换应运而生,我们来看看啥是强制类型转换呢?

           强制类型转换:

        通俗的说,就是把一个对象类型转化为另一个对象类型。(有点像,一般的类型转换机制,但是它又有所自己的限制)

      限制:

     1、这些类必须之间有继承关系,无关系者不能乱转化。

     2.目标对象类型一定是当前转化类型的子类,否则就是上溯造型了,不需要强制转化。

     其实呢,这个强制转化是与上溯造型,是同生共死的,就是说,有了上溯造型必然有强制转化,这样为我们多态是访问子类的特有成员,提供方便,不然全是访问的共有的。

     所以说,在多态的时候,很多时候,我们会用到强制类型转化,去访问子类的特有成员。

      疑问四:

      说了这么多,这个强制类型到底杂用啊?来个实例看看。。

   好吧!

  下面上实例

     

static void getDetails(Employee e){
if(e instanceof Manager){
Manager m = (Manager)e;
m.getDepartment();
}
e.getDetail();
}
上面的这个方法中,加了一些东西

instanceof 是个关键字,作用是检测,左边的变量是否是右边类型的引用。

第三行,进行强制类型转换,

第四行,调用子类特有的方法。

下面都相同。

////

说了这么多,这些东西都是联系在一起的,先辅相成的,所以不要把上溯造型和,多态,强制类型割裂开来。


       下面附上课上老师的讲义,好好琢磨下那几个类,差不多都理解了。
// ------------------------
public class pa {
  public static void main(String[] args){
    Employee emp = new Employee("zhao",28,500.0F);
    Manager  mgr = new Manager("xu",35,800.0F,200.0F);
    Director dor = new Director("huang",45,1000.0F,500.0F,"2222","d01");
    System.out.println(emp.getInfo());
    System.out.println(mgr.getInfo());
    System.out.println(dor.getInfo());
    System.out.println();
  }
}

class Employee {
  String  name ;
  int  age ;
  float  salary = 300 ;

  Employee(String n,int a,float s){
    name = n ;
    if(a>=18 && a<=60) age = a ;
     else {System.out.println("illegal age");
           System.exit(1); }
    salary = s;
  }
  
  Employee( String n , int a ) {
    this(n ,a ,300 ) ;   
 }
  void  upSalary(float inc) {
    salary = salary + inc ;
  }
  String getInfo() {
    return "employee :" + name + "\t" + "salary: " + salary ;
  }
}

class  Manager extends Employee {
   float  allowance;
   Manager(String n,int a,float s , float aa){
     super(n,a,s);
     allowance = aa ;
   }
   void setAllowance(float a) {
     allowance = a ;
   }
  String getInfo() {
    return super.getInfo() + "\t" + "allowance :" + allowance ;
   }
}
class Director extends  Manager {
   String  telephone  ;
   String  department ;
   Director(String n,int a,float s,float aa,String tel,String dep){
     super(n,a,s,aa);
     telephone = tel ;
     department = dep;
   }
   void setTel(String tel) {
     telephone = tel ;
   }
   String getInfo() {
     return name + "  is the management of " + department ;
   }
}
//------------------多态--------------
class pb {
  public static void main(String[] args){
    Employee e1 = new Employee("wang1",30,500);
    Employee e2 = new Manager("wang2",40,800,200);
    Employee e3 = new Director("wang3",50,1000,500,"3333","d02");
    if(e2 instanceof Director)System.out.println("e2 is a Director class!");
    else System.out.println("e2 is Manager!");
    System.out.println(e2.name);
 //   System.out.println(e2.allowance);
    
    e2.upSalary(200.0F);
 //   e2.setAllowance(500.0F) ;
    

    e3.age = 55 ; 
//    e3.department = "d03";
    
    e3.upSalary(500);
  //  e3.setTel("8888");
    

    System.out.println(e1.getInfo());
    e2 = new Employee("wang122",30,500);
    System.out.println(e2.getInfo());
    System.out.println(e3.getInfo());
  }
}

//----------------up cast  -------------------

class pc {
  public static void main(String[] args){
    Director d = new Director("Jack",45,1000.0F,500.0F,"4444","d03");;

    Manager m =d ;     // need? Manger m = (Manger)d
    d.setAllowance(500);
    if(m instanceof Director)System.out.println("m is a Director");
    else System.out.println("m is a Manager");
    System.out.println(m.getInfo());
    System.out.println();
  //  m.setTel("2222");         
    
    Employee e = d ;          // need? Employee e = (Employee)d
    e.upSalary(1000.0F) ;
    System.out.println(e.getInfo());
  }
}

//-----------------down cast--------------------

class pd {
  public static void main(String[] args){
    Employee e1 = new Employee("Tom",30,500);
 //   Manager m1 = e1;            
//    Manager m2 = (Manager)e1;    

    Employee e2 = new Director("Bob",50,1000,500,"5555","d04");
    if (e2 instanceof Employee) {
      //System.out.println( (Director)(e2)).telephone);
      System.out.println("e2 is a Employee!");
      Director d = (Director)e2 ;
      d.setTel("9999");
      d.department="d05";
      System.out.println(d.getInfo());
    }
  }
}


Java多态性理解,好处及精典实例

核心: 1、多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编译时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到...
  • Jian_Yun_Rui
  • Jian_Yun_Rui
  • 2016年10月26日 20:12
  • 9555

[java面试]关于多态性的理解

运行时多态性是面向对象程序设计代码重用的一个最强大机制,Java多态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法...
  • kuaisuzhuceh
  • kuaisuzhuceh
  • 2015年07月02日 14:28
  • 1659

java中实现多态的机制是什么?

面向对象编程有三大特性:封装、继承、多态。 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。 ...
  • BornLiLi
  • BornLiLi
  • 2017年02月15日 18:31
  • 8364

JavaWeb接口的多态现实

JavaWeb接口的多态现实
  • zx520sun
  • zx520sun
  • 2016年11月04日 10:50
  • 364

java中的对于多态的理解

面向对象:      类:具体的对象抽象而来,可以抽象的表示一类具有相同特征和行为的对象      对象:是由类的实例化而来,对象是类的一个实例 java中关于多态的理解 打个比方 父...
  • woshiermingerming
  • woshiermingerming
  • 2016年08月26日 08:29
  • 7210

【超经典】Java多态有什么好处?怎样用?

多态可以分为变量的多态,方法的多态,类的多态.我这里强调的是类的多态,这是在以后的工作中经常会用到的。多态的表现形式有方法重载,方法改写,多态变量和泛型。重载是一种静态的多态性,在程序编译时确定被调用...
  • guomutian911
  • guomutian911
  • 2015年10月06日 23:05
  • 1999

Java 多态缺陷

Java 多态缺陷 ( 1.缺陷 : “覆盖”私有方法 output:    print A private方法被自动认为是final方法,而且对子类是屏蔽的。因此,在...
  • mwq30123
  • mwq30123
  • 2014年06月04日 10:42
  • 465

java多态的实现主要体现在哪些方面

thinking in java3中的多态 People are often confused by other, non-object-oriented features of Java, like...
  • u012110719
  • u012110719
  • 2015年09月16日 17:35
  • 4934

对多态的理解(附经典练习题)

(以下综合了多篇多态的文字,总结而得) 定义:指不同类的对象对同一函数做出不同响应。 实现方式:1.继承父类,方法重写(包括接口实现);2.同一个类中进行方法重载。 存在的三个必...
  • a_long_
  • a_long_
  • 2016年07月28日 15:57
  • 2124

Java技术----多态的实现原理

0.前言 多态在Java技术里有很重要的地位,在面试中也会经常被问到。 多态的使用大家应该都比较了解,但是多态的实现原理就有点抽象了,查了很多很多资料,连续几天断断续续的看,有时候看着...
  • sinat_34311901
  • sinat_34311901
  • 2016年08月15日 09:51
  • 6134
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java多态
举报原因:
原因补充:

(最多只允许输入30个字)