目录
基本知识
Java 提供了一个关键字 interface ,用这个关键字我们可以定义出一个特殊的结构:接口。
public interface 接口名{
//成员变量(常量)
//成员方法(抽象方法)
}
注意:接口不能创建对象;接口是用来被类实现( implements )的,实现接口的类称为实现类。
修饰符 class 实现类 implements 接口1,接口2,接口3,…{
}
.一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。
1、使用接口有啥好处,第一个好处是什么?
●可以解决类单继承的问题,通过接口,我们可以让一个类有一个亲爹的同时,还可以找多个干爹去扩展自己的功能。
2、为什么我们要通过接口,也就是去找干爹,来扩展自己的功能呢?
.因为通过接口去找干爹,别人通过你 implements 的接口,就可以显性的知道你是谁,从而也就可以放心的把你当作谁来用了。
3、使用接口的第二个好处是什么?
·一个类我们说可以实现多个接口,同样,一个接口也可以被多个类实现的。这样做的好处是我们的程序就可以面向接口编程了,这样我们程序员就可以很方便的灵活切换各种业务实现了。
package com.xinbao.d5_interface;
public interface B {
void testb1();//抽象方法
void testb2();
}
package com.xinbao.d5_interface;
public interface C {
void testc1();
void testc2();
}
package com.xinbao.d5_interface;
public class D implements B,C{
//实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类
@Override
public void testc1() {
}
@Override
public void testc2() {
}
@Override
public void testb1() {
}
@Override
public void testb2() {
}
}
package com.xinbao.d5_interface;
public class Test {
public static void main(String[] args) {
D d = new D();
d.testb1();
}
}
接口的应用案例:班级学生信息管理模块的开发
需求
请设计一个班级学生的信息管理模块:学生的数据有:姓名、性别、成绩
功能1:要求打印出全班学生的信息;功能2:要求打印出全班学生的平均成绩。
注意!以上功能的业务实现是有多套方案的,比如:
第1套方案:能打印出班级全部学生的信息;能打印班级全部学生的平均分。
第2套方案:能打印出班级全部学生的信息(包含男女人数);能打印班级全部学生的平均分(要求是去掉最高分、最低分)。
要求:系统可以支持灵活的切换这些实现方案。
package com.xinbao.d7_interface_demo;
public class Student {
private String name;
private char sex;
private double score;
public Student() {
}
public Student(String name, char sex, double score) {
this.name = name;
this.sex = sex;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
package com.xinbao.d7_interface_demo;
import java.util.ArrayList;
public interface StudentOperater {
void printAllInfo(ArrayList<Student> students);
void printAverageScore(ArrayList<Student> students);
}
package com.xinbao.d7_interface_demo;
import java.util.ArrayList;
public class StudentOperatorImpl1 implements StudentOperater{
@Override
public void printAllInfo(ArrayList<Student> students) {
System.out.println("-------全部学生信息--------");
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
System.out.println("姓名:" + s.getName() + " 性别:" + s.getSex() + " 成绩:" + s.getScore());
}
System.out.println("-------------------------");
}
@Override
public void printAverageScore(ArrayList<Student> students) {
double allScore = 0.0;
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
allScore += s.getScore();
}
System.out.println("平均成绩是:"+ allScore/students.size());
}
}
package com.xinbao.d7_interface_demo;
import java.util.ArrayList;
public class StudentOperatorImpl2 implements StudentOperater{
@Override
public void printAllInfo(ArrayList<Student> students) {
System.out.println("-------全部学生信息--------");
int countGirl = 0;
int countBoy = 0;
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
System.out.println("姓名:" + s.getName() + " 性别:" + s.getSex() + " 成绩:" + s.getScore());
if (s.getSex() == '女'){
countGirl++;
}else{
countBoy++;
}
}
System.out.println("女生人数是:" + countGirl + " 男生人数是:" + countBoy);
System.out.println("-------------------------");
}
@Override
public void printAverageScore(ArrayList<Student> students) {
double allScore = 0.0;
double max = students.get(0).getScore();
double min = students.get(0).getScore();
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
allScore += s.getScore();
if (max < s.getScore()){
max = s.getScore();
}
if (min > s.getScore()){
min = s.getScore();
}
}
System.out.println("平均成绩是:"+ (allScore - max - min)/(students.size() - 2));
}
}
package com.xinbao.d7_interface_demo;
import java.util.ArrayList;
public class ClassManager {
private ArrayList<Student> students= new ArrayList<>();
//面向接口编程 多态
private StudentOperater studentOperator = new StudentOperatorImpl2();
public ClassManager(){
students.add( new Student("迪丽热巴",'女',100));
students.add( new Student("古力娜扎",'女',99));
students.add( new Student("哈尼克孜",'女',98));
students.add( new Student("佟丽娅",'女',97));
}
//打印全班学生的信息
public void printInfo(){
studentOperator.printAllInfo(students);
}
//打印全班同学的平均分
public void printScore(){
studentOperator.printAverageScore(students);
}
}
package com.xinbao.d7_interface_demo;
public class Test {
public static void main(String[] args) {
ClassManager cl = new ClassManager();
cl.printInfo();
cl.printScore();
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=44639:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\oop-app4 com.xinbao.d7_interface_demo.Test
-------全部学生信息--------
姓名:迪丽热巴 性别:女 成绩:100.0
姓名:古力娜扎 性别:女 成绩:99.0
姓名:哈尼克孜 性别:女 成绩:98.0
姓名:佟丽娅 性别:女 成绩:97.0
女生人数是:4 男生人数是:0
-------------------------
平均成绩是:98.5
Process finished with exit code 0
三个新增方法
1、JDK8开始,接口中新增了哪些方法?
·默认方法:使用 default 修饰,使用实现类的对象调用。
·静态方法: static 修饰,必须用当前接口名调用
私有方法: private 修饰,jdk9开始才有的,只能在接口内部被调用。
·他们都会默认被 public 修饰。
2、JDK8开始,接口中为啥要新增这些方法?
·增强了接口的能力,更便于项目的扩展和维护。
package com.xinbao.d8_interface_jdk8;
public interface A {
/**
* 1、默认方法:必须使用dafault修饰,默认会被public修饰
* 实例方法:对象的方法,必须使用实现类的对象来访问
*/
default void test1(){
System.out.println("==默认方法==");
test2();
}
/**
* 2、私有方法:必须使用private修饰(jdk9才开始支持)
* 实例方法:对象的方法
*/
private void test2(){
System.out.println("==私有方法==");
}
/**
* 3、静态方法:必须使用static修饰,默认会被public修饰
*/
static void test3(){
System.out.println("==静态方法==");
}
}
package com.xinbao.d8_interface_jdk8;
public class B implements A{
}
package com.xinbao.d8_interface_jdk8;
public class Test {
public static void main(String[] args) {
B b = new B();
b.test1();//类的对象调用
A.test3();//接口名调用
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=44778:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\oop-app4 com.xinbao.d8_interface_jdk8.Test
==默认方法==
==私有方法==
==静态方法==
Process finished with exit code 0
接口的多继承
一个接口可以同时继承多个接口,便于实现类去实现
package com.xinbao.d9_interface_attention;
public class Test {
public static void main(String[] args) {
//目标:理解接口的多继承
}
}
interface A{
void test1();
}
interface B{
void test2();
}
interface C{}
//一个接口可以同时继承多个接口
interface D extends A, B, C{
}
//便于实现类去实现
//class E implements A, B, C{}
class E implements D{
@Override
public void test1() {
}
@Override
public void test2() {
}
}
接口其他注意事项(了解)
1、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
2、一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现。
3、一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的。
4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
package com.xinbao.d9_interface_attention;
public class Test2 {
public static void main(String[] args) {
//目标:了解使用接口的几点注意事项
Zi z = new Zi();
z.run();//父类run()方法执行了
Q q = new Q();
q.talk();//Q重写talk()
}
}
//1、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
interface I{
void test1();
}
interface J{
String test1();
default void run(){
System.out.println("接口J的run()方法执行了");
}
default void talk(){
System.out.println("J的talk执行了");
}
}
//interface K extends I, J{
//报错
//}
//2、一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现。
//class E implements I, J{
//报错
//}
//3、一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的。
class Fu{
public void run(){
System.out.println("父类run()方法执行了");
}
}
//class Zi implements J extends Fu 错误,先有亲爸再有干爹
class Zi extends Fu implements J{
@Override
public String test1() {
return null;
}
}
//4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
interface M{
default void talk(){
System.out.println("M的talk执行了");
}
}
interface N{
default void talk(){
System.out.println("N的talk执行了");
}
}
class Q implements M, N{
@Override
public void talk() {
System.out.println("Q重写talk()");
}
}