Java SE 抽象类与接口(二):接口(下)

news2024/11/15 11:10:14

2.5 实现多个接口

在Java语言中,类和类之间是单继承关系,一个类只可以有一个父类,即Java中不支持多继承关系但是一个类可以实现多个接口,下面通过Animal类来具体说明

class Animal {
	protected String name;
	public Animal(String name) {
		this.name = name;
	}
}

另外我们再提供一组接口,分别表示这个动物会跑,会游泳,会飞

interface IFlying {
	void fly();
}
interface IRunning {
	void run();
}
interface ISwimming {
	void swim();
}

接下来是具体的动物类,比如青蛙是两栖动物,既会跑,有会游泳

class Frog extends Animal implements IRunning, ISwimming {//可以实现多个接口
	public Frog(String name) {
		super(name);
	}
@Override
	public void run() {
		System.out.println(this.name + "正在往前跳");
	}
@Override
	public void swim() {
		System.out.println(this.name + "正在蹬腿游泳");
	}
}

注意:在一个类实现多接口的时候,每一个接口的方法都必须被重写,我们在idea编译器中,可以使用Ctrl+i快速实现接口

再比如鸭子,既会跑,又会游泳,又会飞

class Duck extends Animal implements IRunning, ISwimming, IFlying {
	public Duck(String name) {
		super(name);
	}
@Override
	public void fly() {
		System.out.println(this.name + "正在用翅膀飞");
	}
@Override
	public void run() {
		System.out.println(this.name + "正在用两条腿跑");
	}
@Override
	public void swim() {
		System.out.println(this.name + "正在漂在水上");
	}
}

上面展示了Java中面相对象中最常见的一种用法:一个类继承一个父类,同时实现多个接口
继承表达的含义是is a,即一个类属于什么大类,接口则表示的是can xxx,即一个类具有什么样的特性或能力
这样设计的好处在哪里呢?时刻牢记多态的好处,它可以让程序员忘记类型,有了接口之后,就不必关心具体的类型,而是关注某个类是否具有某种能力

面试题:什么时候会发生多态

在不同类继承一个父类,并且重写了父类中的方法,并且通过父类引用创建的子类对象调用了重写的方法,此时会发生动态绑定并发生向上转型,此时就会发生多态

只要这个类的东西具有某种能力,就可以实现一个接口,比如实现上述接口的类不一定必须是动物类,还可以是其他类,比如机器人也会跑

class Robot implements IRunning {
	private String name;
	public Robot(String name) {
		this.name = name;
	}
	@Override
	public void run() {
		System.out.println(this.name + "正在用轮子跑");
	}
}

2.6 接口之间的继承

在Java中,类和类之间是单继承关系,一个类可以实现多个接口,接口与接口之间可以多继承,即接口可以达到多继承的目的
接口可以继承一个接口,达到复用的效果,使用extends关键字

interface IRunning {
	void run();
}
interface ISwimming {
	void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {

}
class Frog implements IAmphibious {

}

通过一个创建一个新接口IAmphibious,并继承了IRunning, ISwimming,来达到合并两个接口的目的,在Frog类中,还需要继续重写run方法和swim方法

2.7 接口的经典使用案例

  1. 给对象数组排序
    如果我们有一个数组,这个数组中的数据类型是学生类
public class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}

public class Main {
    public static void main(String[] args) {
        Student[] student = new Student[]{
                new Student("zhangsan",95),
                new Student("lisi",89),
                new Student("wangwu",88),
                new Student("zhaoliu",98),
        };
        }
    }

比如我们在这里要对这个数组中的学生按照成绩进行排序,数组中我们有sort方法,能否直接使用这个方法呢?
在这里插入图片描述
在这里我们可以看出,编译器在这个地方抛出了异常,为什么呢,是因为一个数组中的对象有两个成员,一个是姓名,一个是成绩,编译器并不知道你要通过哪个成员来比较对象,所以我们这里引入了Comparable接口,通过重写该接口中的compareTo方法来实现对象的比较

public class Student implements Comparable {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Object o) {//重写compareTo方法
        Student s = (Student) o;//object类强转为Student类
        if (this.score > s.score){
            return -1;
        }else if (this.score<s.score){
            return 1;
        }else {
            return 0; 
        }
    }
}

在sort方法中,会自动调用重写的compareTo方法
然后比较当前对象和参数对象的大小关系(按分数来算).
如果当前对象应排在参数对象之前, 返回小于 0 的数字;
如果当前对象应排在参数对象之后, 返回大于 0 的数字;
如果当前对象和参数对象不分先后, 返回 0;
之后的运行就符合预期了
在这里插入图片描述
注意事项: 对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.

在这里我们给出几种更加灵活的方法,利用比较器,即实现Compartor接口

public class nameCompare implements Comparator<Student> {//比较什么,尖括号里就写什么
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class sorceCompare implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.score > o2.score){
            return -1;
        }else if (o1.score<o2.score){
            return 1;
        }else {
            return 0;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Student[] student = new Student[]{
                new Student("zhangsan",95),
                new Student("lisi",89),
                new Student("wangwu",88),
                new Student("zhaoliu",98),
        };
        Arrays.sort(student);
        System.out.println(Arrays.toString(student));
        nameCompare comparator1 = new nameCompare();
        sorceCompare comparator2 = new sorceCompare();
        System.out.println(comparator1.compare(student[0],student[1]));
        System.out.println(comparator2.compare(student[0],student[1]));
        }
}

在这里插入图片描述
在这里我们可以看出,与Comparable接口不同的是,它不是在想要比较的类上直接添加,而是单独创建了一个类并创建对象,可以根据成绩比较,可以根据名字比较,返回的是一个整数,若我们想利用比较器对数组进行排序,可不可以实现呢,当然可以,我们在上述代码的基础上稍作改动

public class Main {
    public static void main(String[] args) {
        Student[] student = new Student[]{
                new Student("zhangsan",95),
                new Student("lisi",89),
                new Student("wangwu",88),
                new Student("zhaoliu",98),
        };
        Arrays.sort(student);
        System.out.println(Arrays.toString(student));
        nameCompare comparator1 = new nameCompare();
        sorceCompare comparator2 = new sorceCompare();
        System.out.println(comparator1.compare(student[0],student[1]));
        System.out.println(comparator2.compare(student[0],student[1]));
        Arrays.sort(student,comparator1)//传入比较器
        System.out.println(Arrays.toString(student));
        }
    }

在数组类的sort方法中,我们传入了一个关于名字的比较器,是sort的一个重载方法,那么运行结果就会根据名字字母的先后顺序进行排序,运行结果如下
在这里插入图片描述
在这里我们给出重载sort方法的源码,方便大家理解

 public static <T> void sort(T[] a, Comparator<? super T> c) {//在这里我们可以看到该方法有比较器的形式参数
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

2.8抽象类与接口的区别

抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! 常见面试题).
核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.
如之前写的 Animal 例子. 此处的 Animal 中包含一个 name 这样的属性, 这个属性在任何子类中都是存在的. 因此此处的 Animal 只能作为一个抽象类, 而不应该成为一个接口.

class Animal {
	protected String name;
	public Animal(String name) {
		this.name = name;
	}
}

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

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

相关文章

phpcms上传漏洞

原始漏洞 漏洞原理&#xff1a;我们上传一个zip的压缩包&#xff0c;它会解压然后删除其中不是.jpg .gig .png的文件 function check_dir($dir)&#xff1a;这是一个PHP函数的定义&#xff0c;它接受一个参数 $dir&#xff0c;代表要检查的目录路径。 $handle opendir($dir)…

MySQL学习Day32——数据库备份与恢复

在任何数据库环境中&#xff0c;总会有不确定的意外情况发生&#xff0c;比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的&#xff0c;这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时&#xff0c;会出现主从服…

C语言程序环境和预处理Pt.1 - 预处理指令|预处理操作符

电脑所能识别的语言为二进制指令&#xff0c;而我们所写的C语言代码是文本信息。为了能使计算机识别并执行C语言代码&#xff0c;就需要翻译环境&#xff0c;使C语言代码翻译为二进制的指令。 1.按下编译按钮的幕后 - 程序的翻译环境 从C语言源代码到计算机可识别的二进制文件…

【前端】 响应式布局

目录 1.媒体查询 2.BootStrap 2.1BootStrap引入 2.2BootStrap栅格系统 2.3BootStrap手册查询 1.媒体查询 响应式布局&#xff1a;显示区域改变&#xff0c;布局随之改变&#xff0c;即同一套代码适配不同大小的显示器 媒体查询&#xff1a;检测视口宽度&#xff0c;设置差…

案例分析篇12:可靠性设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

信号与系统学习笔记——信号的分类

目录 一、确定与随机 二、连续与离散 三、周期与非周期 判断是否为周期函数 离散信号的周期 结论 四、能量与功率 定义 结论 五、因果与反因果 六、阶跃函数 定义 性质 七、冲激函数 定义 重要关系 作用 一、确定与随机 确定信号&#xff1a;可以确定时间函数…

【AIGC】重磅消息,GPT-4.5 Turbo将在6月发布?

2024 年 AI 辅助研发趋势 文章目录 强烈推荐GPT-4.5 Turbo竞争对手Anthropic的Claude 3谷歌的Gemini 1.5 Pro 总结强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击…

酷开系统走在前列,品牌重启增长,酷开科技成为品牌商合作目标

区别于火热的移动端&#xff0c;手机屏作为私密屏&#xff0c;往往面向的是用户个体&#xff0c;而电视作为家庭连接的重要枢纽&#xff0c;不仅仅定位于公共屏&#xff0c;同时也面向客厅场景发挥着其大屏传播的作用&#xff0c;这里不仅牵扯到大屏营销&#xff0c;也关联着大…

低代码开发平台,快速搭建开源MES系统

MS低代码云MES作为一家专注于提供生产制造数字化方案的服务商&#xff0c;“以客户为中心”、以“数据驱动、智能化、互联化”为企业的核心标签&#xff0c;以低代码平台为切入点&#xff0c;帮助企业构建以人为本的未来供应链生态系统&#xff0c;实现制造企业的智能化转型。 …

基于uniapp的旅游景点入园预约系统 微信小程序0220o

技术要求&#xff1a; a) 操作系统&#xff1a;Windows、Linux等&#xff1b; b) 开发工具&#xff1a;Android Studio、pycharm等&#xff1b; c) 数据库&#xff1a;Oracle、MySQL等&#xff1b; d) 开发语言&#xff1a;python&#xff1b; e) 技术框架&#xff1a;采用MVC模…

【MyBatis面试题】

目录 前言 1.MyBatis执行流程。 2.Mybatis是否支持延迟加载&#xff1f; 3.延迟加载的底层原理知道吗&#xff1f; 4.Mybatis的一级、二级缓存用过吗&#xff1f; 5.Mybatis的二级缓存什么时候会清理缓存中的数据&#xff1f; 总结 前言 本文主要介绍了MyBatis面试题相…

CSS 03

1.选择器 1.1 结构伪类选择器 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>结…

算法基础杂项

1算法最优解 1.首先&#xff0c;保证时间复杂度最低 2.其次&#xff0c;保证空间复杂度最低 3.常数项低不低&#xff0c;一般没人管 2.时间复杂度排序 3.对数器

性能测试-数据库

一、数据库事务机制 ACID描述 1、原子性Atomicity&#xff1a;事务通常由多个语句组成。原子性保证将每个事务视为一个“单元”&#xff0c;该事务要么完全成功&#xff0c;要么完全失败 2、一致性Consistency&#xff1a;“一致”是指数据库中的数据是正确的&#xff0c;不存…

云桥通SD-WAN企业组网与IPLC:广域网连接方案对比

1、技术原理&#xff1a; a.云桥通SD-WAN企业组网&#xff1a;基于软件定义网络技术&#xff0c;通过虚拟化、智能路由和网络功能虚拟化等手段实现多种网络连接的集中管理。 b.IPLC&#xff1a;采用传统电路交换技术&#xff0c;通过物理专线在不同地理位置建立点对点的专用通…

【C语言】求字符串长度,三种方法(库函数,指针运算)简单易懂!

目录 一&#xff0c;strlen函数 1&#xff0c;strlen函数 2&#xff0c;strlen函数使用 二&#xff0c;getchar()函数 1&#xff0c;getchar函数 2&#xff0c;代码 三&#xff0c;指针运算 代码&#xff1a; 四&#xff0c;小结 一&#xff0c;strlen函数 1&#xff…

ATA-2168高压放大器用途有哪些方面

高压放大器是一种电子设备&#xff0c;用于将低电压信号放大为较高电压信号。它在各种应用领域中都具有重要作用。下面西安安泰Aigtek将详细探讨高压放大器的多重应用方面&#xff0c;以及它们在科学、医疗、工业和通信等领域中的关键作用。 一、科学研究 1.1物理学实验 高压放…

精品基于Uniapp+ssm英语学习交流平台小程序打卡计划备忘录

《[含文档PPT源码等]精品微信小程序基于Uniappssm英语学习交流平台小程序》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;ssm 安卓框…

「璞华精选」品牌展区成为亮点,引领海外优质生活新潮流!

展会概况 3月07-09日&#xff0c;CCF 2023上海春季百货展在上海新国际博览中心圆满收官。以“聚焦品牌引流行业”为定位目标的CCF上海国际日用百货&#xff08;春季&#xff09;博览会&#xff0c;立足上海&#xff0c;辐射全球商贸&#xff0c;链接行业市场全局&#xff0c;赋…

备战蓝桥杯---牛客寒假基础训练营补题1

1.第二类斯特林数&#xff1a; 2^n-1就是n个1的二进制&#xff0c;因为每一个&为0&#xff0c;所以我们可以把问题等价于n个1&#xff08;不同的球&#xff09;的串分配给m个非空的盒子&#xff0c;求方案数&#xff0c;这就转化成了第二类斯特林数。 我们令s(n,m)表示n个…