多态

   多态也称作动态绑定,也叫池绑定,对应于静态绑定。动态绑定是在**程序执行期间**,根据隐参的实际类型调用方法。静态绑定是在**程序编译期间**。编译器准确的调用private,static,final修饰的方法或者构造器。总体来说,**静态绑定的效率高,动态绑定的扩展性好**。
   实现多态有三个条件:
 1:继承
 2:重写
 3:父类引用指向子类对象

结合下面代码来具体讲解,同时区分于重写。

class Animal {
  private String name;
  Animal(String name) {this.name = name;}
  public void enjoy(){
    System.out.println("叫声......");
  }

  //public abstract void enjoy();

}
class Cat extends Animal {
  private String eyesColor;
  Cat(String n,String c) {super(n); eyesColor = c;}

  public void enjoy() {
    System.out.println("猫叫声......");
  }

}
class Lady {
    private String name;
    private Animal pet;
    Lady(String name,Animal pet) {
        this.name = name; this.pet = pet;
    }
    public void myPetEnjoy(){pet.enjoy();}
}

public class Test {
    public static void main(String args[]){
        Cat c = new Cat("catname","blue");
        Lady l1 = new Lady("l1",c);
        l1.myPetEnjoy();
    }
}
   分析上面代码,首先是new一个Cat对象,Cat对象***继承***Animal类,**重写**了enjoy方法。然后new一个Lady对象,这里就是多态实现的关键点了。看Lady的构造方法,**接收的是一个Animal类,而new的时候传进去的是一个Cat类**,当调用l1的myPetEnjoy方法时,根据Lady的成员变量pet来实际确定调用哪个方法,实现动态绑定。(根据实际类型来确定调用哪个方法,而不是根据引用类型来确定)
   当需要添加一个别的动物,只需要添加一个类,然后在main函数中new一个新类就可以了。不需要去修改lady的代码,不需要对现存的代码进行修改,为将来的扩展性提供一个很好的基础。
   关于区分重写,前面提到,要想实现多态,必须要有重写。
   多说一句,还是上面的例子,父类引用指向子类对象后可以调用子类的方法,但是不能访问子类的成员变量。这里涉及到的是成员变量和方法不同的调用机制,成员变量存放在heap区,方法存放在code区,由heap区的对象通过引用指向方法。编译器会在编译阶段获取所有可能被调用的方法,如果每次调用都去搜索的话,时间开销相当大。因此虚拟机预先为每个类创建一个方法表(method table),这样在真正调用的时候查找表就可以了。
   当然,在上面的例子中,Animal类的enjoy方法是一定会被子类重写的,所以可声明为抽象方法,同时修改Animal为抽象类。这样能让代码更好的被他人辨识,知道这个抽象方法是一定要重写的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值