Java基础-多态性

简介: Java基础-多态性

关于java语言当中出现的多态语法机制:【基础语法】


1.Animal,Cat,Bird三个类之间的关系:


Cat继承Animal

Bird继承Animal

Cat和Bird之间没有任何的继承关系


2.关于多态中涉及到的几个概念:


向上转型 (upcasting)


子类型 -->父类型 又被称为:自动类型转换

向下转型(downcasting)

向下转型(downcasting)


父类型 -->子类型 又被称为:强制类型转换【需要加强制类型转换符】


3.需要记忆:


无论是向上转型还是向下转型,两种类型之间必须要有继承关系


没有继承关系,程序时无法编译通过的。


示例代码:


public class Test {
  /**
  * @param args
  */
  public static void main(String[] args) {
  //以往的对象创建方式
  Animal a1 = new Animal();
  a1.move();
  Cat c1 = new Cat();
  c1.move();
  c1.CatCatch();
  Bird b1 = new Bird();
  b1.move();
  //多态的方式创建
        /**
         * 1.Animal和Cat之间存在继承关系,Animal是父类,Cat是子类
         * 
         * 2.Cat is a Animal【合理的】
         * 
         * 3.new Cat()创建的对象的类型是Cat,a2这个引用的数据类型是Animal,可见
         * 他们进行了类型转换,子类型转换成父类型,称为向上类型转换/upcasting,又称为自动类型转换
         * 
         * 4.java中允许这种语法:父类型引用指向子类型对象.
         * */
  Animal a2 = new Cat();
  a2.move();
  /**
   * 分析以下程序为什么不能直接调用?
   *    因为编译阶段编译器检查到a2的类型是Animal类型
   *    从Animal.class字节码文件当中查找Catcatch()
   *    方法,最终没有找到该方法,导致静态绑定失败,没有绑定
   *    成功,也就是说编译失败了,别谈运行了。
   *    
   *    1.java程序永远都分为编译阶段和运行阶段
   *    
   *    2.先分析编译阶段,在分析运行阶段,编译无法通过,根本无法运行
   *    
   *    3.编译器编译阶段检查a2这个引用的数据类型为Animal,由于Animal.class
   *    字节码当中move()方法,所以编译通过了。这个过程我们称为静态绑定,编译阶段绑定
   *    只有静态绑定成功之后才有后续的运行
   *    
   *    4.在程序运行阶段,JVM堆内存中真实创建的对象的是Cat对象,那么以下程序在运行
   *    阶段一定会调用Cat对象的move()方法,此时放生了程序的动态绑定,运行阶段绑定。
   *    5.无论是Cat类有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为底层
         * 真实对象就是Cat对象
         * 
         *    6.父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同的形态
         * 这种机制可以成为一种多态语法机制
   * */
  //a2.Catch();编译报错。
  /**
   * 需求:
   * 假设想让以上的对象执行Catch()方法,怎么办?
   *     a2是无法直接调用的,因为a2的类型Animal,Animal中没有Catch()方法;
   *     我们可以将a2强制类型转换为Cat类型
   *     a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下类型转换/downcasting/强制类型转换
   * 
   * 注:向下转型也需要两种类型之间必须有继承关系。不然编译报错。强制诶性转换需要加强制类型转换符
   * 
   * 什么时候需要使用向下转型呢?
   *   当调用的方法是子类型中特有的,在父类型当中不存在,必须进行向下转型
   * 
   * */
  Cat c2 = (Cat)a2;
  c2.move();
  c2.CatCatch();//猫抓老鼠
  //父类型引用指向子类型对象【多态】
  Animal a3 = new Bird();
  /**
   * 1.以下程序编译是没有问题的,因为编译器检查到a3的数据类型是Animal
   * Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型
   * 父类型转换成子类型叫做向下转型,语法合格
   * 
   * 2.程序虽然编译通过了,但是程序在运行阶段会出现异常,因为JVM堆内存
   * 当中真实存在的对象是Bird类型,Bird对象无法转换成Cat对象,因为
   * 两种类型之间不存在继承关系,此时出现异常
   *      java.lang.ClassCastException
   * 
   * */
  //Cat c3 = (Cat)a3;
  /**
   * 1.以上异常只有在强制类型转换的时候会发生,也就是说“向下转型”存在隐患(编译过了,但是运行错了)
   * 2.向下转型只要编译通过,运行一定不会出问题:Animal a = new Cat();
   * 3.向下转型编译通过,运行可能错误:Animal a3 = new Bird(); Cat c3 = (Cat)a3;
   * 4.怎么避免向下转型出现的ClassCastException呢?
   *    使用instanceof运算符可以避免出现以上的异常
   * 5.instanceof运算符怎么用?
   *     5.1. 语法格式:
   *         (引用 instanceof 数据类型名)
   *     5.2.以上运算符的执行结果是布尔类型,结果可能是true/false
   *     5.3.关于运算结果true/false:
   *        假设:(a instanceof Animal)
   * 6.java规范中要求:在进行强制类型转换之前,建议采用instanceof运算符进行判断,避免ClassCastException异常
   * 
   * */
  if(a3 instanceof Bird){//a3是一个Bird类型的对象
    Bird b2 = (Bird)a3;
    b2.move();
    b2.fly();
  }else if(a3 instanceof Cat){//a3是一个Cat类型的对象
    Cat c3 = (Cat)a3;
    c3.move();
    c3.CatCatch();
  }
  }
}
/*class 人{
  public void 跑步(){
  System.out.println("锻炼身体!");
  }
}
class 运动员 extends 人{
  public void 跑步(){
  System.out.println("在比赛!");
  }
  public static void main(String[] args) {
        人 李四 = new 人();//不存在类型转换
    李四.跑步();
    人 张三 = new 运动员();
    张三.跑步();
  }
}*/
class Animal {
  public void move(){
  System.out.println("动物在移动!");
  }
}
class Bird extends Animal {
  public void move() {
   System.out.println("鸟儿会飞翔!");
  }
  //子类特有事物行为/动作
  public void fly() {
  System.out.println("Bird Fly!");
  }
}
class Cat extends Animal {
  //重写父类中继承过来的方法
  public void move() {
   System.out.println("猫在走猫步!");
  }
  //不是父类中继承的方法
  //这个方法是子类对象特有的行为【不是说所有的动物都能抓老鼠!】
  public void CatCatch(){
  System.out.println("猫会抓老鼠!");
  }
}
相关文章
|
8月前
|
设计模式 存储 Java
多态性在Java中的应用场景广泛
【4月更文挑战第7天】多态性在Java中的应用场景广泛
112 1
|
8月前
|
Java
在Java中,多态性是通过继承和接口实现的
【4月更文挑战第7天】在Java中,多态性是通过继承和接口实现的
79 1
|
30天前
|
Java 程序员 开发者
Java 中的多态性
Java中的多态性是面向对象编程的重要特性之一,允许一个接口或基类引用指向其不同子类的对象,实现“一种接口,多种方法”。通过方法重写和动态绑定,多态性提高了代码的灵活性和可扩展性。
67 3
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
95 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
7月前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
226 2
|
3月前
|
设计模式 算法 Java
Java中的多态性:深入理解与应用
【10月更文挑战第16天】 在Java编程的广阔天地中,多态性作为一种强大的面向对象特性,扮演着至关重要的角色。它允许我们以统一的方式处理不同类型的对象,极大地提高了程序的灵活性和可扩展性。本文将深入浅出地探讨Java中多态性的概念、实现机制以及在实际开发中的应用,帮助读者更好地理解和运用这一特性。
|
4月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
|
7月前
|
安全 Java
|
7月前
|
Java 编译器
在 Java 中,重写(Override)和重载(Overload)是两种不同的概念,用于实现多态性。它们有着不同的作用和使用场景。
在 Java 中,重写(Override)和重载(Overload)是两种不同的概念,用于实现多态性。它们有着不同的作用和使用场景。
|
7月前
|
搜索推荐 算法 Java
【Java基础】 几种简单的算法排序
几种简单的JAVA算法排序
56 4