Java抽象类+接口

1.抽象类的介绍

1.1抽象类的特点

1)抽象类的关键字就是abstract,加上这个关键字之后就表示这个类就是一个抽象类;

2)抽象类里面可以进行这个成员变量和成员方法的定义,这个方法可以没有具体的实现;

3)抽象类里面不可以通过new这个关键字去进行对象的实例化;

4)如果一个类里面有抽象的方法,这个类一定是一个抽象类;

5)抽象类必须要被继承,而且继承这个抽象类的子类里面需要对于这个父类里面的抽象方法进行重写操作;因为这个父类的这个方法会被继承的子类进行重写,这个也就意味着我们的这个抽象类里面的这个方法需要满足重写的要求,例如这个不可以被static,private,final修饰等等;

6)抽象类里面不一定包含抽象的方法,但是包含抽象方法的类一定是抽象类;

7)抽象类符合这个动态绑定和向上转型的语法,和普通类的差别就是不可以进行对象的实例化,子类需要进行方法的重写;

8)抽象类里面可以有构造方法,供子类创建对象的时候,初始化父类的成员变量,而且这个抽象类里面可以有这个自定义的方法,我们的这个子类里面也是可以调用的;

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.2多态的体现

下面的这个是我们的主函数,这个里面就是shape是一个抽象类,rect和cycle继承了这个抽象类,我们使用这个子类进行对象的实例化操作,我们把这个子类的实例化对象传递给基类的,draw函数使我们在子类里面实现的,这个也是替下了多态的一个用法,我们传递的这个shape1这个属于长方形的对象,他就会调用这个长方形类里面的这个对应的方法,使用这个shape2就是cycle类里面的对象,传递这个参数就会调用这个cylcle里面的这个draw方法;

我们的抽象类自己不可以进行对象的实例化,但是我们的抽象类可以去接受这个子类的实例化对象,这个是符合向上转型的条件的;
在这里插入图片描述

1.3多重继承是方法的重写

在下面的这个情况里面,我们的这个AB类里面的这个方法都是抽象方法,两个类都是抽象类,这个时候我们的C继承B,他需要不仅对于这个B里面的方法进行重写,也需要对于这个A里面的方法进行重写,alt+enter就可以快速的调出来这个重写的方法,直接快速填充;
在这里插入图片描述

2.接口

2.1接口的特性

1)接口是使用的这个interface关键字进行修饰的,这个开始的时候创建这个java文件的时候我们需要进行选择;
在这里插入图片描述

选择之后这个接口的这个上面显示的就是I这个大写的字母,如下图所示:
在这里插入图片描述
2)接口和多态一样,不可以进行这个new对象的实例化,而且这个接口里面的方法默认是public abstract类型的,我们子类的这个里面需要对于接口里面的方法进行实现,继承这个接口的类需要写生这个implements说明,表明我们的这个类是对于某一个接口的实现;
在这里插入图片描述

2.2接口示例

我们有一个IShape接口,这个接口里面的这个函数是我们的test函数,我们不会对于这个接口里面的函数进行实现,而是在继承这个类的方法里面进行重写;

我们的这个接口里面的方法默认属性就是public abstract,但是为了这个代码的简洁性,很多的编程规范里面要求不进行显示的书写在我们的代码里面;
在这里插入图片描述
cycle对于这个接口里面的方法进行重写:
在这里插入图片描述
我们可以新建一个test.java文件,对于这个接口进行测试,这个里面,我们使用cycle创建的实例化对象传递给我们的接口类,这个cycle里面对于接口里面的方法进行了重写,所以调用到这个func方法的时候,这个test函数里面的内容就会被打印输出;
在这里插入图片描述

2.3单个接口

下面的这个是实现的一个类似于这个USB接口的作用,简单的看一下:

我们定义了一个包,这个包里面是有一个IUsb的接口,剩下的全是java文件,下面的这三个都是对于这个接口的方法进行了重写,当然也实现了自己独有的方法,例如这个鼠标里面的这个click就是自己独有的,键盘里面的这个input就是键盘这个类独有的方法;两个类都对于这个IUsb里面的两个方法进行了重写;
在这里插入图片描述

下面的这个computer就是另外一个独立的类,我们的这个Test是对于我们实现的这个功能进行测试,因为这个里面涉及到向下转型,因此这个里面就是使用了这个instance进行判断,其中这个电脑这个类里面写了这个开机和关机的方法useService这个方法是我们的computer里面独有的,因为如果我们不进行判断,这个openDevice是进行了方法的重写的,但是这个click和input没有进行重写,所以这个需要使用各自子类的对象进行调用,这个时候usb这个形参也不知道会接受什么样的对象,因此这个是候鸟需要进行转型操作,就是向下转型毕竟我们的这个usb是接口,转型之后就可以使用我们的这个mouse调用这个里面的click方法了,使用这个computer(这个应该是键盘对象,但是这个形参其实不影响,不要误解就行),调用对应里面的这个input方法,表示从键盘上面读取数据;
在这里插入图片描述

2.4多个接口

下面的这个do类继承自animal这个类,同时对于IRun和ISwim接口里面的方法进行了重写,其实这个接口就是这个类里面实例化出来的这个对象是不是具有我们的这个接口的这个特性,我们的继承是is a的关系,我们的接口就是这个是不是有这个属性,例如我们的这个狗可以跑,我们就可以让这个狗类实现我们的这个IRun的这个接口;一个类里面可以有多个接口的实现,因为我们的一个类可以有多个属性;
在这里插入图片描述
在我们的这个test文件里面,我们原来是让这个animal进行参数的接受,但是现在我们的这个test02函数参数就是r1,就是只要这个对象具有这个接口的属性,我们就可以调用这个test02方法,原来的这个test01里面首先这个对象必须是animal才可以调用这个eat方法,但是这个test02只要是有这个跑的属性的对象都可以调用这个方法,这个就间接的实现了多继承的功能,实际上这个JAVA里面是没有多继承的,但是通过这个接口的方式,我们就可以让拥有这个属性的对象调用我们的接口函数;

在这里插入图片描述

2.5sort排序的接口comparable

下面的这个代码里面,我们介绍了这个comparable这个接口,尖括号T表示的就是模版,就是这个接口可以处理的类型不是唯一的
在这里插入图片描述
我们想要对于两个学生的年龄进行判断,调用这个comapraTo这个方法,来进行这个年龄的比较,我们是重写了这个方法的,在我们的student这个类里面,因此这个是可以实现我们的这个比较的功能的;
在这里插入图片描述
下面我们定义一个学生数组,使用这个接口对于这个数组里面的这个学生的年龄进行比较:

我们使用的是这个sort函数,其实这个sort函数的底层就是使用的这个comapre这个接口进行比较的,如果我们不进行这个接口的重写,这个时候我们的这个sort是无法发挥作用的,因为他是要进行这个转型的,我们都没有去重写这个comparable里面的接口方法,这个就会报错;

在这里插入图片描述
下面的这个是排序前后的结果的比较:可以看出来这个是按照升序进行排列的;
在这里插入图片描述

2.6使用接口实现冒泡排序

在这里插入图片描述
我们上面实现的这个对于compareTo方法的实现显得很冗余,因此我们优化一下,就是把这个o.age-this.age作为这个重写的方法的返回值,这个时候是按照降序进行排列的,我们可以改变这个o.age和this.age的顺序,这样就可以按照我们的需求,既可以降序排列,也可以升序排列;但是这样做是有风险的,就是我们的这个实际情况的修改,可能会对于这个实际的业务逻辑造成影响,例如这个项目本来就是使用这个o.age-this.age进行降序排列的,但是这个时候我们想要根据这个升序进行排列,这个时候如果我们直接对于这个重写的方法进行修改,原来的这个逻辑就乱套了,这个时候我们需要使用这个comparator这个接口更加灵活的控制我们的这个排列的情况;

在这里插入图片描述

2.7comparator接口更加灵活的管理

下面的这个就是我们的comparator这个接口,为什么要知道这个接口,就是因为我们的上面的这个comparale这个是已经写好的,我们有的时候想要比较这个姓名的排序,有的时候想要对于这个年龄进行排序,有的时候想要升序,有的时候想要降序,这个时候需要我们的根据这个实际情况进行调整,这个compatatable这个接口显得很不灵活,因此我们可以学习了解下这个comparator这个接口,我们可以通过这个接口更加灵活的控制我们的整个程序;

我们的这个接口里面是有一个compare这个方法的,和上面的这个compareTo这个方法的用处基本相同;但是这个时候我们可以根据这个升序降序的具体的需求去对于我们自己创建的这个类进行设计,而不是像上面的这个对于已有的这个进行修改,很容易改变原来的已有的逻辑,我们的这个就很灵活;

在这里插入图片描述
想要实现年龄的比较,这个时候我们就可以使用这个ageCompare(我们自己设计的类)创建对象,使用这个对象.compare方法吗,这个方法的参数就是我们需要进行比较的对象;
在这里插入图片描述
想要实现这个姓名的比较也很简单,就是使用这个compareTo进行比较,这个时候,我们可以创建nameCompare这个类,然后使用compare进行控制,这个compareTo就是针对的无法进行转换的字符串进行比较的,如果是像这个hello world的这样,我们既可以使用这个equals进行比较,但是我们的这个汉字的编码转换问题,因此我们就可以使用这个compareTo进行比较;

在这里插入图片描述
和上面的这个一样,我们创建一个对象compare2调用这个compare方法进行比较他们的姓名;
在这里插入图片描述
对于数组的这个情况,就是我们原来使用这个Arrays.sort的情况或者是冒泡排序,这个时候我们也可以解决问题:原来的这个sort是已经有的,现在的这个调用的是我们自己的这个compare方法,这个里面使用两个参数,第二个就是使用的我们的这个ageCompare创建的对象,这个也是可以进行比较的;在这里插入图片描述
按照相同的方法,我们的这个里面的姓名也是可以进行比较的,然后是按照升序进行排列的,当然,我们可以在我们的这个java文件里面对于这个compare进行控制,因为这个方法被我们重写了,这个升序降序都是可以实现的;

在这里插入图片描述

2.8我的心得

学到这个comparable和comparator的时候,这个接口的难度一下子就上来了,第一次感受到前所未有的难度,但是我知道这个仅仅是一个开始,后面的路一定不是一帆风顺的,这个博客也是自己学了两遍之后在自己的这个IDEA上面实现了之后,稍微明朗了一些之后才写的,第一次学的时候也是感觉特别难,但是一步一步走下去,终究会抵达的,我亦无他,唯手熟尔,既然一天一遍不行,那就每天一遍,我相信总会学明白的,加油吧,少年~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值