java第二十五课 —— 多态

2024-06-18 07:36
文章标签 java 多态 第二十五

本文主要是介绍java第二十五课 —— 多态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

多态

传统的方法带来的问题是什么?如何解决?问题是:代码的复用性不高,而且不利于代码维护。

未使用多态时候的例子:

Poly01.java:

package com.hspedu.poly_;public class Poly01 {public static void main(String[] args) {Master master = new Master("Tom");Dog dog = new Dog("旺旺");Bone bone = new Bone("大棒骨");Cat cat = new Cat("喵喵");Fish fish = new Fish("黄花鱼");master.feed(dog, bone);master.feed(cat, fish);}
}

Master.java:

package com.hspedu.poly_;public class Poly01 {public static void main(String[] args) {Master master = new Master("Tom");Dog dog = new Dog("旺旺");Bone bone = new Bone("大棒骨");Cat cat = new Cat("喵喵");Fish fish = new Fish("黄花鱼");master.feed(dog, bone);master.feed(cat, fish);}package com.hspedu.poly_;public class Master {private String name;public Master(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}//主人给小狗吃骨头public void feed(Dog dog, Bone bone){System.out.println("主人 " + name + " 给 " + dog.getName() + " 吃 " + bone.getName());}//主人给小猫吃黄花鱼public void feed(Cat cat, Fish fish){System.out.println("主人 " + name + " 给 " + cat.getName() + " 吃 " + fish.getName());}//如果动物很多,食物很多// ===> feed 方法很多,不利于管理和维护
}

Animal.java:

package com.hspedu.poly_;public class Animal {private String name;public Animal(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

Dog.java:

package com.hspedu.poly_;public class Dog extends Animal{public Dog(String name) {super(name);}
}

Cat.java:

package com.hspedu.poly_;public class Cat extends Animal{public Cat(String name) {super(name);}
}

Food.java:

package com.hspedu.poly_;public class Food {private String name;public Food(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

Bone.java:

package com.hspedu.poly_;public class Bone extends Food{public Bone(String name) {super(name);}
}

Fish.java:

package com.hspedu.poly_;public class Fish extends Food {public Fish(String name) {super(name);}
}

基本介绍

方法对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的

方法的多态

重写和重载就体现多态。

对象的多态

  1. 一个对象的编译类型和运行类型可以不一致。
  2. 编译类型在定义对象时,就确定了,不能改变。
  3. 运行类型是可以变化的。
  4. 编译类型看定义时 = 号的左边,运行类型看 = 号的右边。

对象的多态案例:

Animal animal = new Dog(); animal 编译类型是 Animal,运行类型 Dog。
animal = new Cat(); 编译类型仍然是 Animal,animal 的运行类型变成了 Cat。

PolyObject.java:

package com.hspedu.poly_.objpoly_;public class PolyObject {public static void main(String[] args) {//体验对象多态的特点Animal animal = new Dog();//animal 编译类型就是 Animal,运行类型 Dog//因为运行时 ,执行到改行时,animal 运行类型是 Dog,所以 cry 就是 Dog 的 cryanimal.cry();//小狗汪汪叫//animal 编译类型 Animal,运行类型就是 Catanimal = new Cat();animal.cry();//小猫喵喵叫}
}

Animal.java:

package com.hspedu.poly_.objpoly_;public class Animal {public void cry(){System.out.println("Animal cry() 动物在叫...");}
}

Dog.java:

package com.hspedu.poly_.objpoly_;public class Dog extends Animal{public void cry() {System.out.println("Dog cry() 小狗汪汪叫...");}
}

Cat.java:

package com.hspedu.poly_.objpoly_;public class Cat extends Animal{public void cry() {System.out.println("Cat cry() 小猫喵喵叫...");}
}

使用多态后文章开头例子中的 Master.java 可以修改为:

Master.java:

package com.hspedu.poly_;public class Master {private String name;public Master(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}// 使用多态机制,可以统一的管理主人喂食的问题// animal 编译类型是 Animal,可以指向(接收) Animal 子类的对象// food 编译类型是 Food 可以指向(接收) Food 子类的对象public void feed(Animal animal, Food food){System.out.println("主人 " + name + " 给 " + animal.getName() + " 吃 " + food.getName());}
}

多态的注意事项和细节

  1. 多态的前提是:两个对象(类)存在继承关系。

  2. 多态的 向上转型

    • 本质:父类的引用指向了子类的对象。

    • 语法:父类类型 引用名 = new 子类类型();

    • 特点:编译类型看左边,运行类型看右边。

      可以调用父类中的所有成员(需遵守访问权限)

      不能调用子类中特有成员;因为在编译阶段,能调用哪些成员,是由编译类型来决定的。

      最终运行效果看子类的具体实现! 即调用方法时,按照从子类开始查找方法,然后调用。

例子:

PolyDetail.java:

package com.hspedu.poly_.detail_;public class PolyDetail {public static void main(String[] args) {//向上转型:父类的引用指向了子类的对象//语法:父类类型 引用名 = new 子类类型();Animal animal = new Cat();Object obj = new Cat();//可以吗? 可以 0bject 也是 Cat 的父类//可以调用父类中的所有成员(需遵守访问权限)//animal.catchMouse();错误//最终运行效果看子类的具体实现!animal.eat();//猫吃鱼animal.run();//跑animal.show();//Hello, 你好animal.sleep();//睡}
}

Animal.java:

package com.hspedu.poly_.detail_;public class Animal {String name = "动物";int age = 10;public void sleep(){System.out.println("睡");}public void run(){System.out.println("跑");}public void eat(){System.out.println("吃");}public void show(){System.out.println("Hello, 你好");}
}

Cat.java:

package com.hspedu.poly_.detail_;public class Cat extends Animal{public void eat(){//方法重写System.out.println("猫吃鱼");}public void catchMouse(){//Cat()特有的方法System.out.println("猫抓老鼠");}
}
  1. 多态的 向下转型
    • 语法:子类类型 引用名 = (子类类型) 父类引用;
    • 只能强转父类的引用,不能强转父类的对象。
    • 要求父类的引用必须指向的是当前目标类型的对象。
    • 当向下转型后,可以调用子类类型中所有的成员。

PolyDetail.java:

package com.hspedu.poly_.detail_;public class PolyDetail {public static void main(String[] args) {//向上转型:父类的引用指向了子类的对象//语法:父类类型 引用名 = new 子类类型();Animal animal = new Cat();//希望可以调用Cat的 catchMouse 方法//多态的向下转型//语法:子类类型 引用名=(子类类型)父类引用;//cat 的编译类型 Cat,运行类型是 CatCat cat = (Cat)animal;cat.catchMouse();//要求父类的引用必须指向的是当前目标类型的对象。//Dog dog = (Dog)animal; 错误。父类的引用指向的是 Cat 而不是 Dog}
}
  1. 属性没有重写之说!属性的值看编译类型。

PolyDetail02.java:

package com.hspedu.poly_.detail_;import com.hspedu.super_.B;public class PolyDetail02 {public static void main(String[] args) {//属性没有重写之说!属性的值看编译类型。Base base = new Sub();//向上转型System.out.println(base.count);//10,看编译类型。}
}
class Base{public int count = 10;
}
class Sub extends Base{public int count = 20;
}
  1. instanceof 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型。

练习题

  1. 请说出下面的每条语言,哪些是正确的,哪些是错误的,为什么?

在这里插入图片描述

public class PolyExercise01{
public static void main(String[] args) {double d = 13.4;//oklong l = (long)d;//okSystem.out.println(l);//13int in = 5;//okboolean b =(boolean)in;//不对,boolean 类型不参与转化Object obj = "Hello";//ok,向上转型String objstr = (String)obj;//ok,向下转型System.out.println(objStr);//HelloObject objPri = new Integer(5);//ok,向上转型String str = (String)objPri;//不对,父类的引用指向的是 Integer 而不是 StringInteger str1 =(Integer)objPri;//ok,向下转型
}}
  1. 题目:

在这里插入图片描述

public class PolyExercise02{public static void main(String[] args){Sub s = new Sub();System.out.println(s.count);//20s.display();//20Base b = s;//向上转型System.out.println(b == s);//true,两个对象比较的是地址,都指向了同一个Sub对象。System.out.println(b.count);//10b.display();//20
}}
class Base{//父类int count = 10;public void display(){System.out.println(this.count);
}
class Sub extends Base{//子类int count = 20;public void display(){System.out.println(this.count);
}

这篇关于java第二十五课 —— 多态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1071674

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有