0

0

Java抽象类和接口如何使用

WBOY

WBOY

发布时间:2023-05-16 09:58:12

|

1050人浏览过

|

来源于亿速云

转载

什么是抽象类

什么是抽象类呢?抽象类顾名思义就是很抽象,就是当我们没有足够的信息去描述这个类的时候我们就可以先不用描述,这样的类就是抽象类。

用代码举个例子:

class Shape {
    public void draw() {
        System.out.println("我要画图形!!");
    }
}
class circle extends Shape {
    @Override
    public void draw() {
        System.out.println("我要画圆形!!!");
    }
}
class rect extends Shape {
    @Override
    public void draw() {
        System.out.println("我要画矩形!!!");
    }
}
public class TestDemo3 {
    public static void drawShape(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
        drawShape(new circle());
        drawShape(new rect());
    }
}

正好也通过这个小小的案例来复习一下多态,我们创建一个Shape父类,然后又创建两个子类分别为 rect类和circle类 然后利用这两个类使用同一个方法,产生的形态是不一样的这就是多态,但是

我们可以发现我只用了这两个子类来画图形分别是圆形和矩形,我并没有调用父类来实现这个方法,为啥呢???就是因为这个父类并不能画出图形,那这个父类的draw方法的实现岂不是没有用,我只需要它父类要有这方法,通过子类重写就可以了,不需要父类的方法有具体的实现。

没错,这就引入到我们今天的主题抽象类

立即学习Java免费学习笔记(深入)”;

上面父类的draw方法由于它的具体实现根本没有用处,所以我们就可以不写,这也正符合抽象类的定义,当不能有足够的信息去描述它,那我们就把它叫做抽象类。

抽象类语法

上面父类的draw方法没有具体的实现我们就可以把它叫做抽象方法。利用abstract来修饰

public abstract void draw();

Java抽象类和接口如何使用

但是这样为啥会报错呢??

原因是被abstract修饰的方法叫做抽象方法,如果一个类里面有抽象方法,那这个类一定是抽象类,所以类也要被abstract来修饰。

Java抽象类和接口如何使用

但是相反,抽象类里面一定有抽象方法么???

Java抽象类和接口如何使用

编译器并不会报错,所以答案是不一定,抽象类里面可以有抽象方法也可以没有抽象方法。

抽象类能否被实例化呢???

Java抽象类和接口如何使用

所以,抽象类是不能实例化的。 

抽象类能否像普通类一样定义成员变量和方法,构造方法呢???

Java抽象类和接口如何使用

抽象类与普通类的区别就是在与抽象类不能实例化,其他定义成员变量,成员方法,构造方法等等都是一样的。

 既然抽象类不能实例化,那他存在的意义是什么呢???

老铁思考的有道理,其实抽象类最大的意义就是被继承,因为抽象类不能实例化对象,只能依靠子类来重写父类(就是抽象类)的方法来完成业务需求。

怎么继承抽象类呢???有哪些注意的点呢???

Java抽象类和接口如何使用

 这样继承为啥会出错呢??原因是在子类继承抽象类的时候,子类需要重写父类的所有方法或者子类需要用abstract修饰(抽象类被抽象类继承或者子类重写抽象类(父类)的所有方法)。

Java抽象类和接口如何使用

这样就正确了。

Java抽象类和接口如何使用

这里还要注意当我们没有重写父类的方法时而是用abstract来修饰,这时当你在次继承这个子类的时候也就是这个子类变成了父类,下一个子类还是要继续重写这个父类的方法和这个父类的父类的方法。 

抽象方法能否别static和final修饰呢???

Java抽象类和接口如何使用

 抽象方法不能被static  和final 修饰,因为子类要重写父类的方法,同时可以省略访问修饰限定符,默认是public。

总结抽象类:

  • 我们把不能足够描述清楚一个对象的类叫做抽象类。

  • 被abstract修饰的方法称为抽象方法,被abstract修饰的类称为抽象类

  • 抽象方法必须在抽象类里面,也就是说,只要有抽象方法,类名也必须利用abstract来修饰,相反,抽象类里面可以没有抽象方法,也可以有抽象方法。

  • 抽象类不能实例化,除了不能实例化之外其他与普通类一样可以定义成员变量,成员方法,构造方法等。同时构造方法和类方法(被static修饰的方法)不能被abstract来修饰

  • 抽象方法的访问修饰限定符不能是private,如果省略默认是public,同时抽象方法不能被final修饰。

  • 子类继承抽象类的时候,子类必须重写抽象类的所有方法并且要有方法的具体实现,如果重写那子类还是抽象类,必须用abstract来修饰。

  • 抽象类中的方法没有具体实现,要通过子类重写在子类中实现。

  • 一个类只能继承一个抽象类

接口

说到接口我们会想到什么呢???我一开始想到的就是充电接口插排等等,比如充电接口,只要符合那个插口的标准,我们都可以使用那个接口来进行充电。这就是把标准进行统一起来,然后大家就可以根据不同的标准来使用不同的接口,比如苹果手机与安卓手机的手机接口就是不一样的,他们就是两种不同的标准,安卓手机用安卓的接口,苹果用苹果的接口这就将标准统一起来。

而在Java中也是一样的,我们把这个标准或者可以说是一种公共的规范叫做接口,只要符合这一接口的标准我们就可以使用它。

听着这抽象的概念你可能现在还是不太明白这到底是什么,我在来拿代码举个例子:

class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(this.name+"吃饭***!");
    }
}

这里我定义了一个动物类,这个动物有名字,年龄,还有吃饭的行为。

class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(this.name+"吃饭***!");
    }
    public void swim() {
        System.out.println("我要游泳~~~~");
    }
}
class Fish extends Animal {
}

接着我又定义了一个鱼类(子类)继承这个动物类(父类),我想让这个鱼有这个游泳的行为,但是这就会有一个问题,在父类定义了一个swim方法,接着我还要定义很多类,难道所有的类都要有这个游泳的行为么???答案是不可以的。所以我们就不能把这个swim方法定义在父类里面,那我们就可以把这个方法定义在子类(鱼类)里面,这样就符合了,但是如果我还要定义1000个动物都会游泳难道都要在自己类中写这个游泳的方法么??这样做显然是不可行的。那我们该怎么做呢??

我们可以就提供一个公共的接口,这也是一种标准,只要符合这一标准都可以使用这个接口或者可以说可以实现这一功能。

看了上面的引例我们应该接口是干什么的了,接下来我们来学一下接口的语法。

怎么定义接口

定义接口要使用interface关键字:

//创建一个接口
//创建接口要是用interface关键字  接口的命名最好是形容词其他的也可以
interface IFlying{
    //这就是一个flying接口
}

接口中的成员变量:

Java抽象类和接口如何使用

这样会报错,接口中的成员变量都是常量,所以必须初始化,接口中的成员变量会被隐式指定为public static final 修饰的。

interface IFlying{
    //接口中的成员变量默认都是被public static final修饰的常量
    //这里的成员变量不可改变
   public static final int a =10;
}

接口中的成员方法:

Java抽象类和接口如何使用

interface IFlying{
    //接口中的成员方法都是抽象方法,默认是public abstract 
    //其中public abstract 可以被省略
    //接口中的成员方法不能有具体的实现
    public abstract void eat();
    //一般就写成:
    //void eat();
    default void sleep(){
        //接口中的方法想要具体实现,要加上default修饰
    }
    //接口中可以有静态方法的具体实现
    public static void method() {
        System.out.println("我是静态的方法!!");
    }
}

接口能否实例化???

Java抽象类和接口如何使用

接口是不能被实例化的。

怎么使用接口???

实现的接口如下:

Android架构基本知识 中文WORD版
Android架构基本知识 中文WORD版

本文档主要讲述的是Android架构基本知识;Android依赖Linux内核2.6来提供核心服务,比如进程管理、网络协议栈、硬件驱动。在这里,Linux内核作为硬件层和系统软件栈层之间的一个抽象层。这个操作系统并非类GNU/Linux的,因为其系统库,系统初始化和编程接口都和标准的Linux系统是有所不同的。 Android 包含一些C/C++库、媒体库、数据库引擎库等等,这些库能被Android系统中不同的组件使用,通过 Android 应用程序框架为开发者提供服务。希望本文档会给有需要的朋友带来帮助

下载
interface IFlying{
    void eat();
}
interface IRunning{
    void run();
}
interface ISwimming{
    void swim();
}
interface IClimbing{
    void climb();
}
//创建一个Ant类 
//利用implements关键字来实现接口
//一个类可以实现多个接口,接口之间利用逗号连接
//实现了接口必须要在接口中重写接口中的方法
//重写方法快捷键:鼠标移动到implements关键字上然后 alt+enter
class Ant implements IClimbing,IRunning{
    public String name;
    @Override
    public void run() {
        System.out.println(this.name+"要跑步");
    }
    @Override
    public void climb() {
        System.out.println(this.name+"爬山");
    }
}
  • 接口的使用时利用implements关键字与类连接,类与接口之间使用implements连接的。

  • 一个类可以实现多个接口,多个接口之间利用逗号连接。

  • class Ant implements IClimbing,IRunning.的意思是类Ant可以实现两个功能,既可以爬又可以跑。

  • 类实现接口时,必须要重写接口中的方法。如果不重写该类还是抽象类,要用abstract来修饰。

接口能否有静态方法和代码块呢???

Java抽象类和接口如何使用

接口中是不能有静态代码块和构造方法的。 

接口间的继承

我们这里总结一下类与接口之间的联系

  • 类与类之间是继承关系利用extends来连接   代表子类继承了父类

  • 类与接口之间是利用implements来连接, 代表类能实现某个功能

  • 接口与接口之间也可以进行联系,利用extends 接口A和接口B  interface A enxtends B 代表接口A拓展了接口B的功能。

这里来讲一下接口与接口之间的继承

我们利用extends关键字将两个接口连接起来,这样就实现了接口之间的继承。

例如:

interface IRunning extends IFlying{
    //类IRunning拓展了IFlying的功能
    void run();
    //接口与接口之间继承后IRunning拓展了IFlying功能
    //有了IRunning的功能的类也要重写IFlying这个方法
}
  • 类IRunning拓展了IFlying的功能

  • 接口与接口之间继承后IRunning拓展了IFlying功能

  • 有了IRunning的功能的类也要重写IFlying这个方法

几个重要的接口

接口comparable

我们这里举一个例子:

比如我们要进行给一个学生进行排序,我们之前学过Arrays的sort方法,好我们来尝试一下这个方法对学生进排序。

class Student{
    public String name;
    public int age;
    public double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student[] student = new Student[4];
        student[0] = new Student("张三",18,88);
        student[1] = new Student("李四",98,98);
        student[2] = new Student("王二麻子",8,18);
        student[3] = new Student("赵老八",58,38);
        System.out.println(Arrays.toString(student));
        Arrays.sort(student);
        System.out.println(Arrays.toString(student));
    }
}

Java抽象类和接口如何使用

从这里发现Arrays.sort方法是比较具体的数字大小的,而我们这里比较学生这个对象并没有指定,我们究竟依靠什么来比较这个学生对象,目前这个学生有名字,分数,年龄,我们到底依靠什么比较是根据我们的需求来定,那我们要具体的比较学生对象的某一个学生怎么比较呢·???看报错信息也就是这个异常,我们需要提供这个comparable这个接口然后重写这个comparable方法。

怎样提供接口????

Java抽象类和接口如何使用

 我们根据类要实现一个接口是利用关键字implements来连接的。

Java抽象类和接口如何使用

 然后使用comparable这个接口,尖括号里面写上你要排序的类。

好这样我们就实现了这个接口,当然看前面那个红线就知道会有报错,这也就是当我们实现一个接口我们必须重写这个接口中的方法,然后Alt+enter重写这个接口中的方法。

Java抽象类和接口如何使用

好,我们就重写了这样的一个方法,比如我们要比较年龄按照升序排列:

Java抽象类和接口如何使用 

然后调用Arrays.sort方法就可以进行排序了。

Java抽象类和接口如何使用

 同样我们还可以根据名字排序:

Java抽象类和接口如何使用

由于,名字是String类型也就是引用类型所以我们要调用compareTo方法来进行比较。

同样的我们还可以根据分数来排序这个学生对象。

Java抽象类和接口如何使用

 comparator接口-比较器

我们刚才使用comparable这个接口会有一个缺陷,就比如当我们已经实现按照年龄排序好了,但是有个人突然把他改成了名字比较,如果是未来做项目开发的时候,那就会给程序猿造成很大的困扰,就怕有一天别人修改了那段代码,所以我们就有了这个comparator这个比较器,我们还是把他封装起来,不用在去学生这个类中去修改。

对学生年龄排序:

class AgeComparator implements Comparator{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}

对学生分数排序:

class ScoreComparator implements Comparator{
    @Override
    public int compare(Student o1, Student o2) {
        return (int)(o1.score - o2.score);
    }
}
对学生名字排序:
class NameComparator implements Comparator{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}

我们还是利用Arrays.sort方法里面再加一个比较器的这个参数就可以比较了。

 public static void main(String[] args) {
        Student[] student = new Student[4];
        student[0] = new Student("张三",18,88);
        student[1] = new Student("李四",98,98);
        student[2] = new Student("王二麻子",8,18);
        student[3] = new Student("赵老八",58,38);
        System.out.println(Arrays.toString(student));
        AgeComparator ageComparator = new AgeComparator();
        Arrays.sort(student,ageComparator);
        System.out.println(Arrays.toString(student));
    }

这样我们将根据什么排序,实例化对应的对象,通过对象调用重写comparator的方法就可以进行比较,不需要担心类中被修改。

cloneable接口深入理解深拷贝与浅拷贝

我们之前学过数组中的克隆方法,就是把一个数组中的内容全部拷贝到另外一个数组中去。

今天我们学的cloneable接口可以将一个对象的属性拷贝到另外一个对象里面去。

怎么使用cloneable接口

我们创建一个人这个类,人这个类中有两个属性,一个是分数,一个是smartphone这个对象(引用类型)。

class SmartPhone{
    public int money = 9999;
}
class Person{
    public int score = 96;
    SmartPhone smartPhone = new SmartPhone();
}
public class TestDemo {
    public static void main(String[] args){
        Person person1 = new Person();
    }
}

我们现在要将这个person这个类实现cloneable接口,利用implements连接,同样的我们要重写这个cloneable这个接口中的方法。

Java抽象类和接口如何使用

这里我们要注意·重写cloneable这个方法,它的返回类型是object,object是Java中所有类的父类。

好,完成了接口的操作,我们接下来完成克隆的工作,我们怎么使用clone这个方法来进行克隆呢???

浅拷贝:
//浅拷贝
class SmartPhone{
    public int money = 9999;
}
class Person implements  Cloneable{
    public int score = 96;
    SmartPhone smartPhone = new SmartPhone();
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Person{" +
                "score=" + score +
                ", smartPhone=" + smartPhone +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person)person1.clone();
        System.out.println(person1.smartPhone.money);
        System.out.println(person2.smartPhone.money);
        person1.smartPhone.money=9;
        System.out.println("===============拷贝之后=================");
        System.out.println(person1.smartPhone.money);
        System.out.println(person2.smartPhone.money);
    }
}

Java抽象类和接口如何使用

 原因是什么呢??画一下图理解一下

Java抽象类和接口如何使用

 这就是浅拷贝,对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此

为浅拷贝。只要将money值进行修改两个对象的money的值都改变,没有彻底的拷贝。

深拷贝
//深拷贝
class SmartPhone implements  Cloneable{
    public int money = 9999;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "SmartPhone{" +
                "money=" + money +
                '}';
    }
}
class Person implements  Cloneable{
    public int score = 96;
    SmartPhone smartPhone = new SmartPhone();
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person)super.clone();
        tmp.smartPhone= (SmartPhone) this.smartPhone.clone();
        return tmp;
    }
    @Override
    public String toString() {
        return "Person{" +
                "score=" + score +
                ", smartPhone=" + smartPhone +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person)person1.clone();
        System.out.println(person1.smartPhone.money);
        System.out.println(person2.smartPhone.money);
        person1.smartPhone.money=9;
        System.out.println("===============拷贝之后=================");
        System.out.println(person1.smartPhone.money);
        System.out.println(person2.smartPhone.money);
    }
}

Java抽象类和接口如何使用

 此时为深拷贝,进行了彻底的拷贝。对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

Java抽象类和接口如何使用

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

309

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1500

2023.10.24

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

391

2023.09.04

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1079

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

169

2025.10.17

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

C# 教程
C# 教程

共94课时 | 7.7万人学习

Java 教程
Java 教程

共578课时 | 51.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号