Java接口

目录

抽象类

抽象类的概述

如何使用抽象类

抽象类的使用

抽象特征

 关于抽象需要注意的几个事情

接口(interface)

常量

如何实现接口

接口与接口多继承

接口的注意事项


抽象类

抽象类的概述

父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了(因为子类对象会调用自己重写的方法)。换句话说,父类可能知道子类应该有哪个功能,但是功能具体怎么实现父类是不清楚的(由子类自己决定),父类只需要提供一个没有方法体的定义即可,具体实现交给子类自己去实现。**我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类**。

对于红字这句话我们需要有一个更深的理解,就是有抽象方法的就可以算作抽象类,但是在抽象类里不见的会有抽象的方法,这句话很重要换一句话说,如果他是抽象类,那么就一定有抽象方法,反之则不然。

通过上述这个大段,我们仔细阅读还可以发现的就是,我们的抽象类是需要有父类和子类的继承,才能真正的算是一个抽象类,接下来我们将距离几个方法。

在抽象类和其他的类是一样的,都是有方法,而在抽象类里我们管方法叫做抽象方法。

- **抽象方法** : 没有方法体的方法。
- **抽象类**:包含抽象方法的类。

如何使用抽象类

使用`abstract` 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。 

修饰符 abstract 返回值类型 方法名 (参数列表);
eg:
public abstract void Sing();

如果一个类包含抽象方法,那么该类必须是抽象类。**注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。**

public abstract class Animal {
    public abstract void run();
}

抽象类的使用

**要求**:继承抽象类的子类**必须重写父类所有的抽象方法**。否则,该子类也必须声明为抽象类。

abstract class Employee {
	private String id;
	private String name;
	private double salary;
	
	public Employee() {
	}
	
	public Employee(String id, String name, double salary) {
		this.id = id;
		this.name = name;
		this.salary = salary;
	}
	
	// 抽象方法
	// 抽象方法必须要放在抽象类中
	abstract public void work();
}

// 定义一个子类继承抽象类
class Manager extends Employee {
	public Manager() {
	}
	public Manager(String id, String name, double salary) {
		super(id, name, salary);
	}
	// 2.重写父类的抽象方法
	@Override
	public void work() {
		System.out.println("管理其他人");
	}
}

// 定义一个子类继承抽象类
class Cook extends Employee {
	public Cook() {
	}
	public Cook(String id, String name, double salary) {
		super(id, name, salary);
	}
	@Override
	public void work() {
		System.out.println("厨师炒菜多加点盐...");
	}
}

// 测试类
public class Demo10 {
	public static void main(String[] args) {
		// 创建抽象类,抽象类不能创建对象
		// 假设抽象类让我们创建对象,里面的抽象方法没有方法体,无法执行.所以不让我们创建对象
//		Employee e = new Employee();
//		e.work();
		
		// 3.创建子类
		Manager m = new Manager();
		m.work();
		
		Cook c = new Cook("ap002", "库克", 1);
		c.work();
	}
}

这个例子可能不太明显,作者又写了一个例子让读者便于理解

public class Main {
    public static void main(String[] args) {
        SonText0 text0 = new SonText0();
        text0.sing();
    }
}
public abstract class Text0 {
    public abstract void sing();
}
public class SonText0 extends Text0{
    @Override
    public void sing()
    {
        System.out.println("我说我是儿子");
    }

}

输出结果 

  

抽象特征

抽象类的特征总结起来可以说是 **有得有失**

**有得:抽象类得到了拥有抽象方法的能力。**

**有失:抽象类失去了创建对象的能力。**

其他成员(构造方法,实例方法,静态方法等)抽象类都是具备的。

换一句话就是,在我们进行抽象类的时候,可以给子类更加自由的空间去实现子类想做的事情,也就是子类可以通过重写抽象的方法,做更多子类想做的事情,但是同时父类也失去了如何去构造属于自己的方法

 关于抽象需要注意的几个事情

1. 抽象类**不能创建对象**,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

   > 理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。所以在写抽象方法的时候,我们是将父类定义为抽象方法,将我们的子类重写父类里的消息,

2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。

   > 理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类

   > 理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

4. 抽象类的子类,必须重写抽象父类中**所有的**抽象方法,否则子类也必须定义成抽象类,编译无法通过而报错。 

   > 理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

5. 抽象类存在的意义是为了被子类继承。

   > 理解:抽象类中已经实现的是模板中确定的成员,抽象类不确定如何实现的定义成抽象方法,交给具体的子类去实现。

接口(interface)

在JDK7,包括JDK7之前,接口中的**只有**包含:抽象方法和常量 

常量

在接口中定义的成员变量默认会加上: public static final修饰。也就是说在接口中定义的成员变量实际上是一个常量。这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接。 

public interface InterF {
    // 抽象方法!
    //    public abstract void run();
    void run();

    //    public abstract String getName();
    String getName();

    //    public abstract int add(int a , int b);
    int add(int a , int b);


    // 它的最终写法是:
    // public static final int AGE = 12 ;
    int AGE  = 12; //常量
    String SCHOOL_NAME = "东北师范大学";

}

如何实现接口

类与接口的关系为实现关系,即**类实现接口**,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 ` implements`关键字。

但是在这里需要补充一点

在我们这里的接口里的方法全部都是抽象方法,在使用接口的时候一定是需要进行重写的,不能进行空着不写,我们可以看一个例子,首先我定义了一个接口 

在这里我在方法名的前面添加了一下public abstract并没有显示报错,说明在接口里我们所有写的方法都是默认存在的,所以在使用时我们要进行重写所有的方法

public interface SportMan {
    void run(); // 抽象方法,跑步。
    void law(); // 抽象方法,遵守法律。
    String compittion(String project);  // 抽象方法,比赛。
}
public class PingPongMan  implements SportMan {
    @Override
    public void run() {
        System.out.println("乒乓球运动员稍微跑一下!!");
    }

    @Override
    public void law() {
        System.out.println("乒乓球运动员守法!");
    }

    @Override
    public String compittion(String project) {
        return "参加"+project+"得金牌!";
    }
}
public class TestMain {
    public static void main(String[] args) {
        // 创建实现类对象。
        PingPongMan zjk = new PingPongMan();
        zjk.run();
        zjk.law();
        System.out.println(zjk.compittion("全球乒乓球比赛"));

    }
}

接下来我们再看一个例子

public class Main {
    public static void main(String[] args) {
        Capper capper = new Capper();
        capper.sing();
    }
}
public interface Sing {
    public abstract void sing();
}
public class Capper implements Sing {
    @Override
    public void sing()
    {
        System.out.println("520Hz");
    }
}

 我们的打印结果就是520Hz

**类与接口之间的关系是多实现的,一个类可以同时实现多个接口。**

首先我们先定义两个接口,代码如下:
 

/** 法律规范:接口*/
public interface Law {
    void rule();
}

/** 这一个运动员的规范:接口*/
public interface SportMan {
    void run();
}
public class JumpMan implements Law ,SportMan {
    @Override
    public void rule() {
        System.out.println("尊长守法");
    }

    @Override
    public void run() {
        System.out.println("训练跑步!");
    }
}

我们的打印结果就是:尊长守法

                                       训练跑步! 

接口与接口多继承

Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。大家一定要注意:

**类与接口是实现关系**

**接口与接口是继承关系**

接口继承接口就是把其他接口的抽象方法与本接口进行了合并。

接口的注意事项

1. 当两个接口中存在相同抽象方法的时候,该怎么办?

> 只要重写一次即可。此时重写的方法,既表示重写1接口的,也表示重写2接口的。

2. 实现类能不能继承A类的时候,同时实现其他接口呢?

> 继承的父类,就好比是亲爸爸一样
> 实现的接口,就好比是干爹一样
> 可以继承一个类的同时,再实现多个接口,只不过,要把接口里面所有的抽象方法,全部实现。

3. 实现类能不能继承一个抽象类的时候,同时实现其他接口呢?

> 实现类可以继承一个抽象类的同时,再实现其他多个接口,只不过要把里面所有的抽象方法全部重写。

4. 实现类Zi,实现了一个接口,还继承了一个Fu类。假设在接口中有一个方法,父类中也有一个相同的方法。子类如何操作呢?

> 处理办法一:如果父类中的方法体,能满足当前业务的需求,在子类中可以不用重写。
> 处理办法二:如果父类中的方法体,不能满足当前业务的需求,需要在子类中重写。

5. 如果一个接口中,有10个抽象方法,但是我在实现类中,只需要用其中一个,该怎么办?

> 可以在接口跟实现类中间,新建一个中间类(适配器类)
> 让这个适配器类去实现接口,对接口里面的所有的方法做空重写。
> 让子类继承这个适配器类,想要用到哪个方法,就重写哪个方法。
> 因为中间类没有什么实际的意义,所以一般会把中间类定义为抽象的,不让外界创建对象 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《花雕学AI》02:人工智能挺麻利,十分钟就为我写了一篇长长的故事

ChatGPT最近火爆全网,上线短短两个多月,活跃用户就过亿了,刷新了历史最火应用记录,网上几乎每天也都是ChatGPT各种消息。国内用户由于无法直接访问ChatGPT,所以大部分用户都无缘体验。不过呢,前段时间微软正…

Vulnhub:DC-3靶机

kali:192.168.111.111 靶机:192.168.111.250 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --scripthttp-enum 192.168.111.250 通过nmap得知目标CMS为Joomla 3.7.0 漏洞利用 搜索发现该版本存在sql注入 利用sqlmap获取目标后台用户密码 sqlmap -u &…

测试行业3年经验,面试想拿 17K,HR说你只值 8K,该如何回答或者反驳?

面试最尴尬的不是被拒绝,而是直接说你不值那个价格... 最近朋友在面试的时候,HR 突然来了句:你只值 7K。朋友后面和我说了这个事。我想如果是我处在这种情况下,自己并不能很好地回答或者反驳。不知道大家会怎么回答或者反驳&…

基于vivado(语言Verilog)的FPGA学习(4)——FPGA选择题总结(针对华为逻辑岗实习笔试)

基于vivado(语言Verilog)的FPGA学习(4)——FPGA选择题总结 文章目录基于vivado(语言Verilog)的FPGA学习(4)——FPGA选择题总结1. 消除险象2. 建立时间和保持时间3.ISE4.DMA5.仿真器6…

【Linux】-- 权限和Shell运行原理

目录 Shell的运行原理 用户切换 su - / su sudo 权限 chmod chown chgrp 八进制方法修改文件属性 目录权限 粘滞位 umask 自定义默认权限 Shell的运行原理 广义上,Linux发行版 Linux内核 外壳程序 Linux 从广义上来理解它是一个操作系统 而从狭义上…

关于Map类的使用小结

目录 1. 常用Map类和区别 2. HashMap工作原理 2.1 Put()执行过程 2.2 扩容机制 3. ConcurrentHashMap 3.1 工作原理 3.2 JDK7分段锁的优缺点 1. 常用Map类和区别 Map类包含:HashMap、HashTable、LinkedHashMap、TreeMap。 1) 从功能上区分。 HashMap&…

多线程进阶学习11------CountDownLatch、CyclicBarrier、Semaphore详解

CountDownLatch ①. CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞 ②. 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞) ③. 计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行 public static void m…

SpringBoot学习笔记上

文章目录1 SpringBoot1.1 SpringBoot介绍1.2 SpringBoot创建的三种方式1.3SpringBootApplication注解1.4 SpringBoot的配置文件1.5多环境配置1.6 使用jsp1.7 ComnandLineRunner 接口 , ApplcationRunner接口2 Web组件2.1 拦截器2.2 Servlet2.3 过滤器Filter2.4 字符…

gpt3官网中文版-人工智能软件chat gpt安装

GPT-3(Generative Pre-trained Transformer 3)是一种自然语言处理模型,由OpenAI研发而成。它是GPT系列模型的第三代,也是目前最大、最强大的自然语言处理模型之一,集成了1750亿个参数,具有广泛的使用场景&a…

Flutter Row 实例 —— 新手礼包

大家好,我是 17。 本文在 3.31 日全站综合热榜第一。 新手礼包一共 3 篇文章,每篇都是描述尽量详细,实例讲解,包会! Flutter Row 实例 —— 新手礼包Flutter TextField UI 实例 —— 新手礼包Flutter TextField 交…

靠近用户侧和数据,算网融合实现极致协同

游弋自如的生产力,在边缘。IMMENSE、36氪|作者 1846年1月,纽约。 一行长短不一的电码顺着通讯线路飞往130公里开外的费城,这是华尔街的巨头们首次使用电报传输讯息,更具有金钱意味的是,电力通讯的成功&am…

【蓝桥杯集训·周赛】AcWing 第96场周赛

文章目录第一题 AcWing 4876. 完美数一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第二题 AcWing 4877. 最大价值一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第三题 AcWing 4878. 维护数组一、题目1、原…

路由策略实验

运行OSPF协议 [R1]ospf 1 router-id 1.1.1.1 [R1-ospf-1]area 0 [R1-ospf-1-area-0.0.0.0]network 192.168.12.1 0.0.0.0 [R1-ospf-1-area-0.0.0.0]network 192.168.13.1 0.0.0.0 [R2]ospf 1 router-id 2.2.2.2 [R2-ospf-1]area 0 [R2-ospf-1-area-0.0.0.0]network 192.168.…

抖音seo矩阵系统源码搭建技术+二开开源代码定制部署

抖音已经成为了当今最为流行的短视频平台之一,拥有着庞大的用户群体和海量的视频资源。对于一些商家或者运营者来说,如何从这些视频资源中挖掘出有效的信息,进而提升自己的品牌、产品或者内容的曝光度,就成为了一个非常重要的问题…

一次通过.frm和.ibd恢复mysql数据表的过程

1、导出.frm和.ibd文件 2、安装Mysql的Utilities 3、执行命令(实际恢复的表) mysqlfrm --diagnostic ./stat_vehicle_mileage.frm4、复制Sql,添加ROW_FORMATCOMPACT(需要检测生成的Sql语句是否可用) CREATE TABLE …

Android开发-Android常用组件-ProgressBar进度条

4.8 ProgressBar进度条 常用属性 android:max 进度条的最大值 android:progress 进度条已完成进度值 android:progressDrawable 设置轨道对应的Drawable对象 android:indeterminate 如果设置成true,则进度条不精确显示进度 android:indeterminateDrawable …

YOLO算法改进指南【算法解读篇】:2.如何训练自己的数据集

我们接着上一篇文章配置完YOLOv5需要的环境后,今天我们试着用YOLOv5训练自己的数据。(在开始本教程前,记得先跑一遍入门篇,确保环境是正常的) 有图有真相,先看看我的运行结果 【YOLOv5 源码地址】 🚀 我的环境: 语言环境:Python3.8编译器:PyCharm深度学习环境: to…

2021蓝桥杯真题格点(填空题) C语言/C++

问题描述 如果一个点(x,y) 的两维坐标都是整数, 即 x∈Z 且 y∈Z, 则称这个点为 一个格点。 如果一个点 (x,y) 的两维坐标都是正数, 即 x>0 且 y>0, 则称这个点在 第一象限。 请问在第一象限的格点中, 有多少个点(x,y) 的两维坐标乘积不超过 2021 , 即x⋅y≤2021 。 掟…

c#之反射详解

总目录 文章目录总目录一、反射是什么?1、C#编译运行过程2、反射与元数据3、反射的优缺点二、反射的使用1、反射相关的类和命名空间1、System.Type类的应用2、System.Activator类的应用3、System.Reflection.Assembly类的应用4、System.Reflection.Module类的应用5、…

SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理

SpringBoot 整合RabbitMq 自定义消息监听容器来实现消息批量处理前言添加依赖配置文件编写监听器创建SimpleRabbitListenerContainerFactory发送消息前言 RabbitMQ是一种常用的消息队列,Spring Boot对其进行了深度的整合,可以快速地实现消息的发送和接收…