Java三大特性——多态

多态

面向对象的计算机编程语言的三大特点:
继承,封装,多态

  • 多态:一个引用,能表现出多种形态。
  • 多态的条件:
  1. 继承(查看之前博客——继承

  2. 重写 即子类实现父类的同名方法,且参数类型与参数个数与父类同名方法完全相同。
    ①. 重写注意事项:
      重写的方法不能是private
      重写中子类的方法的访问权限不能低于父类的方法访问权限.
      普通方法可以重写, static 修饰的静态方法不能重写.

public class Animal { 
 protected String name; 
 public Animal(String name) { 
 this.name = name; 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小动物"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
} 
// Bird.java 
public class Bird extends Animal { 
 public Bird(String name) { 
 super(name); 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小鸟"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
}
//Bird中eat方法即是对父类eat方法的重写

  ②.重写与重载的区别:

重写重载
方法名称、参数列表、返回值类型完全相同方法名称相同,参数列表不同,返回值不做要求
作用在子类与父类之间作用在同一个类
访问控制权限不可比父类严格访问控制权限不做要求
  1. 向上转型
    ①.向上转型与向下转型
      向上转型:把子类对象转化为父类对象。
      向下转型:把父类对象转化为子类对象。
public class Animal { 
 protected String name; 
 public Animal(String name) { 
 this.name = name; 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小动物"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
} 
// Bird.java 
public class Bird extends Animal { 
 public Bird(String name) { 
 super(name); 
 } 
 public void eat(String food) { 
 System.out.println("我是一只小鸟"); 
 System.out.println(this.name + "正在吃" + food); 
 } 
}
public class Test {
 public void static main(String[] args){
 Animal a=new Bird();//向上转型
 Bird b=(Brid)a;//向下转型
 Animal a1=new Animal();
 Bird b1=(Brid)a1;//错误示范
 }
}

    该代码中Animal a=new Bird();即是向上转型,使父类的引用a指向子类对象Bird;而Bird b=(Brid)a;即是向下转型:将父类对象转为子类对象。但由于此时父类对象a是指向子类对象的,因此父类对象a则可转化为子类对象b。但底下错误示范中,父类对象a1是指向父类对象的,此时子类引用b1不能直接指向父类对象a1。
  ②.注意事项:
    父类引用可以直接指向子类对象,而子类引用不可直接指向父类对象;即向上转型可直接发生,向下转型不可。
    发生向下转型前,必须要先发生向上转型。且需要强制转换,即a前边必须要加上(Bird)。

  • 多态的实现——动态绑定
    ①. 动态绑定与静态绑定:
      在Java中,当你调用一个方法时,可能会在编译时期(compile time)解析(resolve),也可能实在运行时期(runtime)解析,这全取决于到底是一个静态方法(static method)还是一个虚方法(virtual method)。如果是在编译时期解析,那么就称之为静态绑定(static binding),如果方法的调用是在运行时期解析,那就是动态绑定(dynamic binding)或者延迟绑定(late binding)。
      多态使得父类型的引用变量可以引用子类型的对象。如果调用子类型对象的一个虚方法(非private,final or static),编译器将无法找到真正需要调用的方法,因为它可能是定义在父类型中的方法,也可能是在子类型中被重写(override)的方法,这种情形,只能在运行时进行解析,因为只有在运行时期,才能明确具体的对象到底是什么。这也是我们俗称的运行时或动态绑定(runtime or dynamic binding)。
      另一方面,private static和final方法将在编译时解析,因为编译器知道它们不能被重写,所有可能的方法都被定义在了一个类中,这些方法只能通过此类的引用变量进行调用。这叫做静态绑定或编译时绑定(static or compile time binding)。所有的private,static和final方法都通过静态绑定进行解析。这两个概念的关系,与“方法重载”(overloading,静态绑定)和“方法重写”(overriding,动态绑定)类似。动态绑定只有在重写可能存在时才会用到,而重载的方法在编译时期即可确定(这是因为它们总是定义在同一个类里面)
    以上内容摘自博客园《Java多态与动态是如何实现的》点击原文查看
class Shape { 
 public void draw() { 
 //没有操作
 } 
} 
class Cycle extends Shape { 
 @Override //重写标识符
 public void draw() { 
 System.out.println("○"); 
 } 
} 
class Rect extends Shape { 
 @Override 
 public void draw() { 
 System.out.println("□"); 
 } 
} 
class Flower extends Shape { 
 @Override 
 public void draw() { 
 System.out.println("♣"); 
 } 
} 

public class Test { 
 public static void main(String[] args) { 
 Shape shape1 = new Flower(); 
 Shape shape2 = new Cycle(); 
 Shape shape3 = new Rect(); 
 drawMap(shape1); 
 drawMap(shape2); 
 drawMap(shape3); 
 } 
 // 打印单个图形
 public static void drawShape(Shape shape) { 
 shape.draw(); 
 } 
}

  当类的调用者在编写 drawShape 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当前的 shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现(和 shape 对应的实例相关), 这种行为就称为多态.

  • 多态的优点
    ①.可替换性(substitutability)。多态对已存在代码具有可替换性。
    ②.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
    ③.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
    ④.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
    ⑤.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值