6.7面向对象的多态

news2024/11/15 23:58:51

7. 面向对象特征三:多态性

概念
多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
变色龙
女朋友养宠物
王者荣耀英雄

7.1 多态的形式和体现

7.1.1 对象的多态性
多态性,是面向对象中最重要的概念,
在 Java 中如何体现的:对象的多态性:父类的引用指向子类的对象
格式:父类 变量名 = new 子类;(Father a = new Son();)

2 . 特点
多态的前提1:是继承
多态的前提2:要有方法的重写

练习:多态入门案例
创建包: cn.tedu.oop
创建类: TestDemo.java

package cn.tedu.oop2;
/*本类用作多态的入门案例*/
public class TestDemo {
    public static void main(String[] args) {
        //6.创建“纯纯的”对象用于测试
        Animal a = new Animal();
        Cat c = new Cat();
        Dog d = new Dog();
        a.eat();//小动物Animal吃啥都行~调用的是父类自己的功能
        c.eat();//小猫爱吃小鱼干~调用的是子类重写后的功能
        d.eat();//小狗爱吃肉骨头~调用的是子类重写后的功能
        /*2.父类对象不可以使用子类的特有功能*/
        //a.jump();//报错,Animal类里并没有这个方法
        //a.run();//报错,Animal类里并没有这个方法
        c.jump();//小猫Cat跳的老高啦~,子类可以调用自己的功能
        d.run();//小狗Dog跑的老快啦~,子类可以调用自己的功能

        //7.创建多态对象进行测试
        /*3.口诀1:父类引用指向子类对象
        * 解释:创建出来的子类对象的地址值,交给父类类型的引用类型变量来保存*/
        Animal a2 = new Cat();//Cat类对象的地址值交给父类型变量a2来保存
        Animal a3 = new Dog();//Dog类对象的地址值交给父类型变量a3来保存
        //8.测试多态对象
        /*4.口诀2:编译看左边,运行看右边
        * 解释:必须要在父类定义这个方法,才能通过编译,把多态对象看作是父类类型
        *      必须要在子类重写这个方法,才能满足多态,实际干活的是子类*/
        a2.eat();//小猫爱吃小鱼干~,多态对象使用的是父类的定义,子类的方法体
    }
}
/*1.多态的前提:继承+重写*/
//1.创建父类
class Animal{
    //3.创建父类的普通方法
    public void eat(){
        System.out.println("小动物Animal吃啥都行~");
    }
}
//2.1创建子类1
class Cat extends Animal{
    //4.1添加重写的方法
    public void eat(){
        System.out.println("小猫爱吃小鱼干~");
    }
    //5.1添加子类的特有功能
    public void jump(){
        System.out.println("小猫Cat跳的老高啦~");
    }
}
//2.2创建子类2
class Dog extends Animal{
    //4.2添加重写的方法
    @Override
    public void eat(){
        System.out.println("小狗爱吃肉骨头~");
    }
    //5.2添加子类的特有功能
    public void run(){
        System.out.println("小狗Dog跑的老快啦~");
    }
}

父类引用指向子类对象,如:Animal a = new Cat();
多态中,编译看左边,运行看右边
在这里插入图片描述

  1. 练习:多态成员使用测试
    创建包: cn.tedu.oop
    创建类: TestDemo2.java
package cn.tedu.oop2;
/*本类用于测试多态成员的使用情况*/
public class TestDemo2 {
    public static void main(String[] args) {
        //7.创建纯纯的子类对象
        Dog2 d = new Dog2();
        System.out.println(d.sum);//20,子类自己的属性
        d.eat();//小狗爱吃肉包子,子类自己的方法

        //8.创建多态对象
        /*口诀1:父类引用指向子类对象*/
        /*口诀2:编译(保存)看左边,运行(效果)看右边*/
        Animal2 a = new Dog2();
        /*多态中,成员变量使用的是父类的*/
        System.out.println(a.sum);//10
        /*多态中,方法的声明使用的是父类的,方法体使用的是子类的*/
        a.eat();//小狗爱吃肉包子
        /*多态中,调用的静态方法是父类的,因为多态对象把自己看作是父类类型
        * 直接使用父类中的静态资源*/
        a.play();//没有提示,玩啥都行~
        Animal2.play();
    }
}
//1.创建父类
class Animal2{
    //3.创建父类的成员变量
    int sum = 10;
    //4.创建父类的普通方法
    public void eat(){
        System.out.println("吃啥都行~");
    }
    //9.1定义父类的静态方法play
    public static void play(){
        System.out.println("玩啥都行~");
    }
}
//2.创建子类
class Dog2 extends Animal2{
    //5.定义子类的成员变量
    int sum = 20;
    //6.重写父类的方法
    @Override
    public void eat(){
        System.out.println("小狗爱吃肉包子");
    }
    //9.2创建子类的静态方法play
    //@Override
    /*这不是一个重写的方法,只是恰巧在两个类中出现了一模一样的两个静态方法
    * 静态方法属于类资源,只有一份,不存在重写的现象
    * 在哪个类里定义,就作为哪个类的资源使用*/
    public static void play(){
        System.out.println("小狗喜欢玩皮球~");
    }
}

7 拓展 (选讲)
7.1 设计汽车综合案例
创建包: cn.tedu.oopexec
创建类: DesignCar.java



package cn.tedu.oop2;
/*本类用于完成汽车设计案例*/
public class DesignCar {
    public static void main(String[] args) {
        //9.创建一个纯纯的父类对象进行测试
        Car c = new Car();
        System.out.println(c.getColor());//null
        c.start();
        c.stop();
        //c.swim();//报错,父类对象不可以调用子类的特有功能

        //10.创建纯纯的子类对象做测试
        BMW b = new BMW();
        System.out.println(b.color);//五彩斑斓的黑
        System.out.println(b.getColor());//null
        b.start();//都让开,我的车要起飞啦~
        b.stop();//唉呀妈呀熄火了~

        //11.创建多态对象进行测试
        Car c2 = new TSL();
        //System.out.println(c2.color);
        System.out.println(c2.getColor());
        c2.stop();
        c2.start();
        //c2.swim();
    }
}
//1.通过分析,抽象形成一个汽车类
class Car{
    //2.定义并封装汽车类的属性--成员变量
    private String brand;//品牌
    private String color;//颜色
    private int id;//编号
    private double price;//价格

    //3.定义功能
    public void start(){
        System.out.println("我的小车车启动啦~");
    }
    public void stop(){
        System.out.println("唉呀妈呀熄火了~");
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

//4.创建子类
class BMW extends Car{
    String color = "五彩斑斓的黑";
    //5.重写父类的方法
    @Override
    public void start(){
        System.out.println("都让开,我的车要起飞啦~");
    }
}
//6.创建子类2
class TSL extends Car{
    //7.重写父类的方法
    @Override
    public void stop(){
        System.out.println("唉呀妈,怎么停不下来呢");
    }
    //8.添加子类的特有功能
    public void swim(){
        System.out.println("没想到吧,我还是个潜水艇");
    }
}

7.2 多态为了统一调用标准 (选讲)

package cn.tedu.oop2;

public class TestFruit {
    public static void main(String[] args) {
        Fruit f = new Fruit();
        Apple a = new Apple();
        Orange o = new Orange();
        get(f);
        get(a);
        get(o);
    }
    //只需要创建一个方法,就可以执行截然不同的效果
    //忽略子类对象的差异统一看作父类类型
    public static void get(Fruit f){
        f.clean();
    }
}
class Fruit{
    public void clean(){
        System.out.println("水果要洗洗再吃");
    }
}
class Apple extends Fruit{
    @Override
    public void clean(){
        System.out.println("苹果需要削皮");
    }
}
class Orange extends Fruit{
    @Override
    public void clean(){
        System.out.println("橙子需要剥皮");
    }
}

多态的好处和弊端

好处:变量引用的子类对象不同,执行的方法就不同,实现动态绑定。代码编
写更灵活、功能更强大,可维护性和扩展性更好了。

弊端:一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,
那么该变量就不能再访问子类中添加的属性和方法。

向上转型与向下转型

在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
那么在这个过程中就存在着多态的应用。存在着两种转型方式,分别是:向上转型和向下转型。
向上转型:可以把不同的子类对象都当作父类来看,
比如:父类Parent,子类Child
父类的引用指向子类对象:Parent p=new Child();

说明:向上转型时,子类对象当成父类对象,
比如:花木兰替父从军,大家都把花木兰看做她爸,但是实际从军的是花木兰,而且,花木兰只能做她爸能做的事,在军营里是不可以化妆的。

向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。这个是之前向上造型过的子类对象仍然想执行子类的特有功能,所以需要重新恢复成子类对象
Parent p = new Child();//向上转型,
此时,p是Parent类型Child c = (Child)p;//此时,把Parent类型的p转成小类型Child

比如:花木兰打仗结束,就不需要再看做是她爸了,就可以”对镜贴花黄”了

7.6.2 如何向上或向下转型 (选讲)
向上转型:自动完成
向下转型:(子类类型)父类变量

package com.tedu;

import java.sql.SQLOutput;

public class Test1 {

    public static void main(String[] args) {

        Fruit fruit=new Apple();
        fruit.eat();
        //fruit.p();报错,不能使用子类的功能

        System.out.println(fruit.age);
        System.out.println(fruit.name);

//向上转型我们只能使用父类的功能,但是如果我们想要使用子类的功能怎么办
              //向下转型
        Apple apple=(Apple) fruit;
//我们通过向下转型就可以使用父类的功能
        System.out.println(apple.sex);
           apple.p();
//instancof的测试
//使用bana类测试向下转型

       //Bana bana=(Bana) fruit;
       /**
        * 这里之所以运行会报错是因为,开辟空间的时候只开辟了
        * apple类的内存空间,但是在这里却要指向bana类所以报错类
        *
        * 由于fruit对象是由Fruit类创建完成的,向下转型是只能转换成Fruit类型
        * */
      // bana.eat();//这个时候会报错


       /** 为了解决这样的一个错误我们使用一个instanceof关键字进行与类型的判断
        *
        * 父类对象 instanceof 子类类型,如果成立则为true 否则为false
        * 为了确保转型成功我们先进行变量的验证
        * */


       if (fruit instanceof Fruit){

           Fruit fruit1=(Fruit)fruit;
           fruit1.eat();

       }

       if (fruit instanceof Bana){

            Bana bana1=(Bana)fruit;

       }else {
           System.out.println("转型失败");
       }

    }
}
class Fruit{

    String name="水果";
    int age=33;
    public void eat(){
        System.out.println("水果要洗洗再吃");



    }
}
class Apple extends Fruit{

String sex="男";

public  void p(){

    System.out.println("这是一个玩耍的方法");
}

}

class  Bana extends Fruit{

    String color="黄色";

    public void c(){

        System.out.println("这是一个颜色方法");
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

副业变现:Midjourney绘画赚钱的6种方式

今年被称为AI元年,其中最火的两款AI工具非ChatGpt和Midjourney莫属。究其原因,无非两点:第一,它提高了生产力,之前需要两年完成的工作,使用ChatGpt两天就完成。 第二,它带来了副业收入&#xff…

短视频seo源代码部署步骤

一、 部署短视频SEO矩阵系统源代码,您需要遵循以下步骤: 准备服务器环境 首先,您需要准备一个服务器环境来托管源代码。您可以选择云服务器(例如AWS,阿里云等)或自己的私人服务器。 安装所需软件 在服务器…

Android系统Binder详解

Android系统启动篇 1,《android系统启动流程简介》 2,《android init进程启动流程》 3,《android zygote进程启动流程》 4,《Android SystemServer进程启动流程》 5,《android launcher启动流程》 6,…

visual studio编译c++问题处理

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2760 语法错误: 意外的令牌“标识符”,预期的令牌为“;” 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C7510 “string_view”: 类型 从属名称的使用必须…

RocketMQ_介绍以及基础入门

目录 一、什么是MQ 1、应用解耦 2、流量削峰 3、数据分发 二、MQ的优缺点 三、各种MQ产品的对比 四、RocketMQ快速入门(单机版本) 一、什么是MQ 在学习RocketMQ之前,我们先来了解什么是MQ,以及为什么要用MQ。MQ的英文全称是(Massage Q…

2023首届盘古石杯晋级赛复盘

晋级赛通排61,学生组39,折在大小写格式上的题太多了qaq 容器密码:usy1UN2Mmgram&^d?0E5r9myrk!cmJGr Android程序分析 1.涉案应用刷刷樂的签名序列号是(答案格式:123ca12a)(★☆☆☆☆) 11fcf899 雷电APP跑的时候前面加…

LeetCode 2481. 分割圆的最少切割次数

【LetMeFly】2481.分割圆的最少切割次数 力扣题目链接:https://leetcode.cn/problems/minimum-cuts-to-divide-a-circle/ 圆内一个 有效切割 ,符合以下二者之一: 该切割是两个端点在圆上的线段,且该线段经过圆心。该切割是一端…

【Flutter】Flutter 如何使用 flutter_swiper

文章目录 一、前言二、flutter_swiper 的概念三、Flutter 中的 flutter_swiper1. 使用的库2. 方法介绍 四、代码示例1. 简单示例2. 完整示例 五、总结 一、前言 在移动应用开发中,轮播图是一种常见的 UI 元素,它可以用来展示一系列的图片或者内容。在 F…

ACL 2023 | 利用思维链(CoT)推理隐式情感,狂涨50%

©PaperWeekly 原创 作者 | 费豪 单位 | 新加坡国立大学 题目: Reasoning Implicit Sentiment with Chain-of-Thought Prompting 作者: 费豪,李波波,刘乾,邴立东⁴,李霏,Chua Tat-Seng 新加…

聚观早报|青年失业率处在高位;滴滴租车在全国300个城市上线服务

今日要闻:青年失业率处在高位;滴滴租车在全国300个城市上线服务;特斯拉提供三个月免费充电服务;苹果新专利Apple Watch;甲骨文宣布裁员数百人 青年失业率处在高位 6 月 15 日,国新办举行 5 月份国民经济运…

signoz调研部署及log收集体验

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党 背景 最近一直在调研监控、log收集,tracing相关的开源项目,以便使用。 前段时间一直调研使用的是skywalking。后来发现在log收集存储这一…

Ubuntu18编译内核源码,并调整版本号

​ 目标 下载ubuntu18 4.15.0-20-generic内核源码,默认情况下编译的内核版本会是4.15.17,我们需要调整版本号跟系统默认的一致,即4.15.0-20-generic 1 下载内核源码 sudo apt install linux-source-4.15.0 默认情况下,上面的…

苹果iOS 17新功能:iPhone激活Apple Watch铃声反向查找手表

苹果 Apple Watch 此前一直有查找 iPhone 的功能,用户可以点击表盘的电话图标(或者长按)来激活 iPhone 的铃声,从而找到附近的 iPhone 手机。 在最新的 iOS 17 测试版本中,苹果为 iPhone 也添加了这一功能的反向版本&a…

STM32速成笔记—串口通信

文章目录 一、什么是串口通讯二、串口通讯有什么用三、STM32的串口通信四、串口通信相关概念4.1 波特率4.2 全双工和半双工4.3 同步通信和异步通信 五、硬件连接六、串口通讯程序配置6.1 使能串口时钟和GPIO时钟6.2 初始化GPIO6.3 初始化串口参数6.4 使能串口6.5 串口接收中断6…

3ds MAX 多维材质

有的时候,我们想在一个图形中添加两个材质 比如我们绘制了一个球体,想要表示这是足球,但是没有黑白方块的贴图 除了绘制一个贴图外,我们可以用多维材质直接实现。 这里给茶壶对象的盖子和壶身设置两种贴图: 首先打…

MVI设计模式

一.各种框架对比 https://blog.csdn.net/qq_36390114/article/details/126160017 1. MVC(Model-View-Controller) 模型-视图-控制器 MVC的目的就是为了M和V代码分离,降低耦合性。 Model:数据来源,网络请求数据和数据…

DJ8-1 shell 的启动和终止、重定向、管道

目录 8.1 shell 的启动和终止 8.2 输入输出重定向 8.2.0 标准输入输出 8.2.1 输出重定向 > 8.2.2 输入重定向 < 8.2.3 常见输入输出重定向形式 8.2.4 标准错误输出重定向 8.3 管道 Linux 系统中的 shell 具有两大功能&#xff1a; 是一个命令解释器&…

express框架学习笔记

express简介 express是一个基于Node.js平台的极简的、灵活的WEB应用开发框架。express是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发WEB应用&#xff08;HTTP服务&#xff09; express使用 新建express文件夹新建文件test01.js&#xff0c;代码如…

特征点Features2D类介绍

文章目录 Features2D类介绍1. cv::AgastFeatureDetector2. cv::AKAZE3. cv::BRISK4. cv::FastFeatureDetector5. cv::GFTTDetector6. cv::KAZE7. cv::MSER8. cv::SimpleBlobDetector9. cv::StarDetector10. cv::SIFT11. cv::SURF12. cv::FastFeatureDetector13. cv::AgastFeatu…

leetcode2385. 感染二叉树需要的总时间(java)

感染二叉树需要的总时间 感染二叉树需要的总时间递归 dfs代码演示 二叉树专题 感染二叉树需要的总时间 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/amount-of-time-for-binary-tree-to-be-infected 给你一棵二叉树的…