03 面向对象(多态,接口)

2023-11-14

如果要求程序员必须在某个类中特定的方法中实现一个特定的功能, 应该如何实现?

使用抽象方法或者使用接口(interface)

抽象方法只能单继承,不能多继承,子类必须使用里面的抽象方法

接口可以多继承,实现类必须重写里面的方法

接口的作用?

接口是一种约定的规范,体现了规范和实现分离的思想

体现低耦合思想(减少依赖关系)

接口和接口实现类定义的语法

接口的语法


public interface 接口名{
void walk();//抽象方法1,里面没有语体
//有默认的实现方法
default void A(){
    System.out.println("有默认实现的方法, 属于对象");
    }
 static void defaultMethod(){
        System.out.println("有默认实现的方法, 属于类");
    }
}
}

一个子类接口可以继承多个接口:

public interface IAmphibiable  extends IWalkable,ISwimable{

}

实现类(implements)的语法:

public class A implements IAmphibiable{
    //重写覆盖IAmphibiable里面的抽象方法
    
}

注意:

//接口名命名规范:I+驼峰命名法
//接口不能创建对象,必须有子类

实现类在实现一个接口的时候, 需要注意哪些问题?

作用:实现接口里面的抽象方法,完成功能具体的实现

1.必须覆盖接口里面的抽像方法

2.可以同时实现多个接口,并且继承在前,实现在后

3.必须完全实现接口中的所有抽象方法,或者他自己也是一个抽象类,直到里面的抽象方法被子类完全实现.

4.实现类的访问修饰符的权限必须大于接口的访问权限

接口和抽象类的区别?
分析
相同点:
1、都可以定义抽象方法
2、都不能创建对象
  
不同点:
1、接口里面全部必须是抽象方法,抽象类中可以定义普通方法。
2、接口可以多继承,抽象类只能单继承。
3、抽象类是用于约定子类应该具备的功能;接口约定的是实现类应该具备的功能;
当需要实现某个功能时,关心的侧重点不同,接口关注的是你有没有这个功能,你是谁他不关心;
抽象类需要关心功能的同时,还得关心你是不是该类的子类。
所以,接口未来用于解耦,体现了软件开发的低耦合要求。
如何理解编译类型和运行类型?

例子

 Animal d2=new Dog();//只要是Animal的子类型,d2里面的方法都有,这样的功能扩展性更好
        //编译时类型-->Animal d2,声明对象变量的类型,编译通过了再到运行时期,否则报错
        //运行时类型__>new Dog,对象的真实类型
        d2.eat();//先找父类有不有这个方法,有的话找子类有不有这个方法覆盖重写,有的话执行子类,否则执行父类
       

编译类型和运行类型只在创建对象的时候进行使用,

编译类型可以是类和接口,并且是运行类型的父类或者接口,而运行类型不可以是抽象类

什么是多态? 如何体现多态?好处是什么?

多态含义:当编译类型和运行类型不一致,一个对象具有多种状态

注意:编译类型必须是运行类型的父类或者接口

如何实现示例:

Dog 	d 	= 	new Dog();  	//创建一只狗对象,赋给子类类型变量

Animal  a  	=	new Cat();    	//创建一只猫对象,赋给父类类型变量

好处:

1.对已存在代码具有可替换性

2.增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作

3.向子类提供了一个共同接口

操作多态继承关系

语法:

父类 变量名 = new 子类();
变量名.方法();
public class Animal {
	public void shut() {
		System.out.println("Animal...shout...");
	}
}
public class Cat extends Animal{
	public void shut() {
		System.out.println("妙妙妙...");
	}
}
public static void main(String[] args) {
        // 创建Cat对象
       Animal animal = new Cat();
		animal.shut();
    
    //妙妙妙...

结论:父类引用变量指向于子类对象,调用方法时实际调用的是子类的方法。

操作实现关系

接口 变量名 = new 子类();
变量名.方法();
public interface ISwimable{
	void swim();
}
public class Fish implements ISwimable{
    void swim(){
        System.out.println("自由遨游");
    }
}
public static void main(String[] args){
    ISwimable fish=new Fish();
    fish.swim();

}
//运行结果:自由遨游

结论:接口引用变量指向实现类对象,调用方法时实际调用的是实现类实现接口的方法。

多态情况下, 方法访问的流程?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UOIc8FRX-1684759193666)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230228201405261.png)]

流程:

编译时期:先去父类中寻找该方法,找到的话就到裕兴时期,否则报错

运行时期:继续去子类找有不有该方法,有的话就运行子类的方法,没有的话就执行父类的方法

多态中的类型转换(概念和数组一样)

1.自动类型转换:把子类对象赋给父类变量(多态)

语法

父类 变量=new 子类对象();

//该变量只拥有父类自己的方法

Animal a = new Dog();//Animal是DOg的父类
Object  obj = new Dog();	//Object是所有类的根类

2.强制类型转换:把父类类型对象赋给子类类型变量,父类不能直接调用子类的方法时使用强转,否则编译报错

子类类型 变量=(子类变量) 父类对象;

//该变量同时具有父类和子类的方法

由于父类没有这个方法,且需要使用子类这个方法就要强转

**注意:**父类对象的真实类型必须是子类类型

instanceof关键字

作用:判断对象是否是指定的类型

语法格式:
boolean b = 对象A   instanceof  类B;  //判断 A对象是否是 B类的实例?如果是,返回true

综合总结

需求中的功能做接口来用:
package cn.wolfcode._10_network;

public interface IFunction {
    //共同的上网(IInternet)和打电话(ICall)的功能
    void iInternet();
    void iCall();
}

需求中相同的行为做父类方法,字段来使用或者抽象类(abstract)来使用(少用)
public class NetworkOperator {
    //网络类型
private String type;

    public NetworkOperator() {
    }

    public NetworkOperator(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "网络类型是:" + type ;
    }
    //安装宽带(installBroadband)和安装有线电视(installCableTV)的行为.
    public void installBroadband(){
        System.out.println("可以安装宽带");
    }
    public void installCableTV(){
        System.out.println("可以安装有线电视");
    }


需求中自己特有的行为在子类中定义一个方法使用

需要继承父类的方法和功能,实现接口的功能

public class ChinaMobile extends NetworkOperator implements IChat,IFunction{//继承两个接口,并且必须重写父类的方法
    public ChinaMobile(String type){
        setType(type);//用来接收测试类传进来的实参
    }
    //中国移动
    @Override
    public void ichat() {
        System.out.println("通过飞信实现了聊天");
    }

    @Override
    public void iInternet() {
        System.out.println("实现了上网");
    }

    @Override
    public void iCall() {
        System.out.println("实现了打电话");
    }

}

测试类用来创建对象,做类型转换,instanceof用作对象类型的比较

package cn.wolfcode._10_network;

public class Demo {
    public static void main(String[] args) {
        NetworkOperator m=new ChinaMobile("DT-LTE");
        dowork(m);
        System.out.println("=========");
        NetworkOperator u=new ChinaUnicom("WCDMA");
        dowork(u);
        System.out.println("=========");
        NetworkOperator t=new ChinaTelecom("LTE");
        dowork(t);

    }
    public static void dowork(NetworkOperator n){
        if(n instanceof ChinaUnicom){//使用instanceof进行类型的判断,instanceof用作对象类型的比较
            ChinaUnicom u=(ChinaUnicom) n;
            System.out.println("中国联通:");
            System.out.println(u);
            u.installBroadband();
            u.installCableTV();
            u.iCall();
            u.iInternet();

        }
        if(n instanceof ChinaTelecom){
            ChinaTelecom t=(ChinaTelecom) n;
            System.out.println("中国电信:");
            System.out.println(t);
            t.installBroadband();
            t.installCableTV();
            t.iCall();
            t.iInternet();

        }
        if(n instanceof ChinaMobile){
            ChinaMobile m=(ChinaMobile) n;
            System.out.println("中国移动:");
            System.out.println(m);
            m.installBroadband();
            m.installCableTV();
            m.iCall();
            m.iInternet();
            m.ichat();

        }
    }
}

();
t.iInternet();

    }
    if(n instanceof ChinaMobile){
        ChinaMobile m=(ChinaMobile) n;
        System.out.println("中国移动:");
        System.out.println(m);
        m.installBroadband();
        m.installCableTV();
        m.iCall();
        m.iInternet();
        m.ichat();

    }
}

}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

03 面向对象(多态,接口) 的相关文章

  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • 将 MOXy 设置为 JAXB 提供程序,而在同一包中没有属性文件

    我正在尝试使用 MOXy 作为我的 JAXB 提供程序 以便将内容编组 解组到 XML JSON 中 我创建了 jaxb properties 文件 内容如下 javax xml bind context factory org eclip
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • Spring Boot Data JPA 从存储过程接收多个输出参数

    我尝试通过 Spring Boot Data JPA v2 2 6 调用具有多个输出参数的存储过程 但收到错误 DEBUG http nio 8080 exec 1 org hibernate engine jdbc spi SqlStat
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 使用 CXF-RS 组件时,为什么我们使用 而不是普通的

    作为后续这个问题 https stackoverflow com questions 20598199 对于如何正确使用CXF RS组件我还是有点困惑 我很困惑为什么我们需要
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后

随机推荐

  • Oracle检查点队列–实例崩溃恢复原理剖析

    检查点队列 实例崩溃恢复原理剖析 什么叫检查点队列 检查点队列是将脏块连接起来 按照第一次脏的数据块依次往后串联起来 形成一个队列 检查点的作用是什么 检查点只是一个数据库事件 它存在的根本意义在于减少崩溃恢复时间 Oracle8i以前是没
  • PHPStorm.WebStrom等系列官方开发工具配置本地项目与运程服务器同步

    PHPStorm WebStrom配置本地项目与运程服务器同步 说明 PHPStorm WebStrom等官方的系统开发工具配置本地项目与运程服务器同步的方法都基本一致没有 几乎没有什么不同之处 我们拿WebStorm为例说一下具体的配置过
  • 背光补偿

    背光补偿能提供在非常强的背景光线前面目标的理想的曝光 无论主要的目标移到中间 上下左右或者荧幕的任一位置 背光补偿也称作逆光补偿或逆光补正 它可以有效补偿摄像机在逆光环境下拍摄时画面主体黑暗的缺陷 当摄像机处于逆光环境中拍摄时 画面会出现黑
  • windows,IDEA各种常用快捷键积累

    windows IDEA各种常用快捷键积累 windows快捷键 1 win shfit s 拖动截屏 2 ctrl alt s 系统录屏 IDEA 1 快速形成main方法 psvm 回车 2 快速形成输出语句 sout 回车 3 内容提
  • [转载]推荐:互联网思维必读十本书

    原文地址 推荐 互联网思维必读十本书 作者 梧桐雨 推荐 互联网思维必读十本书 最近在商界最流行的词汇 莫过于 互联网思维 了 互联网思维 就像一部让人垂涎的武林秘籍 得之可化腐朽为神奇 无论是小米 阿芙精油 或是卖煎饼的黄太吉 都宣称自己
  • 神经网络bn公式_BN、LN、IN、GN、SN归一化

    作者 泛音 公众号 知识交点 该小伙子文章写得不错 感兴趣的大家可以关注下 公众号 知识交点 内容包含 BatchNormalization LayerNormalization InstanceNorm GroupNorm Switcha
  • 解决Docker中运行的MySQL8.0中文乱码

    解决Docker中MySQL8 0乱码问题 环境 Ubuntu版本 21 10 64位 Docker版本 20 10 MySQL版本 8 0 27 正文 MySQL命令行无法展示中文 如下图 进入MySQL容器 docker exec it
  • doris同步作业配置参数修改和注意事项

    创建同步作业 创建数据同步作业的的详细语法可以连接到 Doris 后 执行 HELP CREATE SYNC JOB 查看语法帮助 这里主要详细介绍 创建作业时的注意事项 job name job name是数据同步作业在当前数据库内的唯一
  • 5-FreeSwitch-freeswitch开启录音和使用

    文章目录 一 开启 usr local freeswitch conf dialplan 后面的default添加配置 二 在freeswitch重新加载 F6 或者 reloadxml 三 使用录音 3 1单腿录音 方法一 API 方法二
  • Android Studio 运行 遇到 Failed to read key from keystore

    分享一下我老师大神的人工智能教程 零基础 通俗易懂 风趣幽默 还带黄段子 希望你也加入到我们人工智能的队伍中来 https blog csdn net jiangjunshow Error Execution failed for task
  • 成交量加权动量交易系统

    策略说明 基于动量系统 通过交易量加权进行判断 系统要素 用VWM上穿零轴判断多头趋势 入场条件 价格高于VWM上穿零轴时价格通道 且在SetupLen的BAR数目内 做多 出场条件 空头势多单出场 import DataAPI impor
  • 左式堆的合并

    二叉堆对于合并操作是困难的 因为需要把一个数组拷贝到另一个数组 左式堆可以高效的地支持合并操作 左式堆与二叉树之间唯一区别是 左式堆不是平衡的 可能非常趋向不平衡 左式堆的结构 typedef struct TreeNode element
  • DirectX12 3D游戏开发实践(龙书)第四章 Direct3D的初始化

    目录 Direct3D的初始化 预备知识 Direct3D概述 组件对象模型 纹理格式 Textures Formats 交换链和页面翻转 深度缓冲 资源与描述符 多重采样技术的原理 利用Direct3D进行多重采样 功能级别 Direct
  • 客观面试题--32.说下springmvc的五个常用注解?

    1 Controller 在SpringMVC 中 控制器Controller 负责处理由DispatcherServlet 分发的请求 它把用户请求的数据经过业务处理层处理之后封装成一个Model 然后再把该Model 返回给对应的Vie
  • Jenkins集成及在服务器上发布异常 解决方案汇总

    一 在jenkins上构建时出现问题 如下图所示 解决方案 1 单击红色圆球 找到控制台输出 根据错误提示 检查上传到SVN的代码是否完整无错 检出SVN所提交的代码在本地运行 看是否能够成功 二 未能找到类型或命名空间名称 是否缺少 us
  • lvgl-文本框学习篇(五)

    lvgl 文本框学习篇 五 学习材料 工具 QT Creator 5 12 3 lvgl 源代码 lvgl 官方标签例程 极客笔记 学习内容 过程 零件和样式 用法 添加文字 占位符 删除字符 移动光标 隐藏光标 光标闪烁时间 单行模式 密
  • 1050 螺旋矩阵

    本题要求将给定的 N 个正整数按非递增的顺序 填入 螺旋矩阵 所谓 螺旋矩阵 是指从左上角第 1 个格子开始 按顺时针螺旋方向填充 要求矩阵的规模为 m 行 n 列 满足条件 m n 等于 N m n 且 m n 取所有可能值中的最小值 输
  • idea设置JVM运行参数

    对JVM运行参数进行修改是JVM性能调优的重要手段 下面介绍在应用程序开发过程中JVM参数设置的几种方式 方式一 java程序运行时指定 Dproperty value 该参数通常用于设置系统级全局变量值 如配置文件路径 保证该属性在程序中
  • linux 虚拟化

    主旨 日常我们都在自己的windows或者mac电脑上 安装vmware软件 来虚拟linux服务器 那么我们是不是也可以通过在linux服务器上安装vmware软件 来虚拟出来其他的服务器呢 开整 优点 可以在一台服务器上虚拟出来几台服务
  • 03 面向对象(多态,接口)

    如果要求程序员必须在某个类中特定的方法中实现一个特定的功能 应该如何实现 使用抽象方法或者使用接口 interface 抽象方法只能单继承 不能多继承 子类必须使用里面的抽象方法 接口可以多继承 实现类必须重写里面的方法 接口的作用 接口是