JavaSE——面向对象高级二(3/4)-接口(认识接口、接口的好处)以及接口的综合案例(设计班级学生的信息管理模块)

简介: JavaSE——面向对象高级二(3/4)-接口(认识接口、接口的好处)以及接口的综合案例(设计班级学生的信息管理模块)

接口

认识接口

  • Java提供了一个关键字 interface,用这个关键字我们可以定义出一个特殊的结构:接口。
public interface 接口名{
    //成员变量(常量)
    //成员方法(抽象方法)
}

在接口中,不需要将变量用final修饰成常量,它会自动转为常量,例如:

public interface A{
    double R = 3.14;
    //相当于 public static final double r = 3.14;
}

注意:常量建议使用大写来命名。

方法也同样,接口会自动将方法转为抽象方法,例如:

public interface A{
    void run();
    //相当于public abstract void run();
}

故而接口中的方法只能有签名,不能有方法体。

注意:接口不能创建对象;接口是用来被类实现(implements),实现接口的类称为实现类

修饰符 class 实现类 implements 接口1,接口2,接口3,...{

}

  • 一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。

接口的好处

  • 弥补了类单继承的不足,一个类同时可以实现多个接口。
  • 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。

例如下面这种情况,一个类继承了几个类之后就不能再继承其他类了,这时需要其他功能就可以用接口来实现了。

public class Test{
    public static void main(String[] args){
        Student s = new A();
    }
}
 
class Student{
 
}
 
class A extends Student{
 
}

接口为其拓展更多功能:

public class Test{
    public static void main(String[] args){
        Singer s = new A(); //或是 Driver s = new A();
    }
}
 
class A extends Student implements Driver,Singer{
 
    @override
    public void drive{
    }
 
    @override
    public void sing{
    }
 
}
 
class Student{
 
}
 
 
interface Driver{
    void drive();
}
 
interface Singer{
    void sing();
}

1.使用接口有啥好处,第一个好处是什么?


  • 可以解决类单继承的问题,通过接口,我们可以让一个类有一个亲爹的同时,还可以找多个干爹去扩展自己的功能。

2.为什么我们要通过接口,也就是去找干爹,来扩展自己的功能呢?


  • 因为通过接口去找干爹,别人通过implements的接口,就可以显性地知道你是谁,从而也就可以放心地把你当作谁来用了。

3.使用接口的第二个好处是什么?

  • 一个类我们说可以实现多个接口,同样,一个接口也可以被多个类实现。这样做的好处是我们的程序就可以面相接口编程了,这样我们程序员就可以很方便的灵活切换各种业务实现了。

接口的综合案例

需求

请设计一个班级学生的信息管理模块:学生的数据有:姓名、性别、成绩


功能1:要求打印出全班学生的信息;


功能2:要求打印出全班学生的平均成绩。


注意!以上功能的业务实现是有多套方案的,比如:


  • 第1套方案:能打印出班级全部学生的信息;能打印班级全部学生的平均分。
  • 第2套方案:能打印出班级全部学生的信息(包含男女人数);能打印班级全部学生的平均分(要求是去掉最高分、最低分)

要求:系统可以支持灵活的切换这些实现方案。

先定义出基本的学生类:

学生类

package user.interfaceDemo;
 
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 user.interfaceDemo;
 
import java.util.ArrayList;
 
public class ClassManager {
    private ArrayList<Student> students = new ArrayList<>();
 
    //构造器初始化出班级内部的信息
    public ClassManager(){
        students.add(new Student("余周周",'女',99));
        students.add(new Student("林杨",'男',100));
        students.add(new Student("蒋川",'男',80));
        students.add(new Student("凌翔茜",'女',90));
    }
 
    //打印出全班学生的信息
    public void printInfo(){
 
    }
 
    //打印出全班学生的平均成绩
    public void printScore(){
 
    }
}

实现的方法这部分因为要能够灵活切换,所以需要用接口实现,先空着,去定义接口。

学生操作接口

package user.interfaceDemo;
 
import java.util.ArrayList;
 
public interface StudentOperator {
    void printAllInfo(ArrayList<Student> students);
    void printAverageScore(ArrayList<Student> students);
}

下面就定义两个学生操作类,在学生操作类中去实现学生操作接口,分别重写接口的两个方法。

学生操作类

第一套方案:

package user.interfaceDemo;
 
import java.util.ArrayList;
 
public class StudentOperatorImp1 implements  StudentOperator{
 
    @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());
            System.out.println("性别:" + s.getSex());
            System.out.println("分数:" + s.getScore());
            if(i != students.size() - 1){
                System.out.println("--------------------");
            }
        }
        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 user.interfaceDemo;
 
import java.util.ArrayList;
 
public class StudentOperatorImp2 implements StudentOperator{
    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("=======全班所有学生信息如下=======");
        int count1 = 0;  //用于记录男生的数量
        int count2 = 0;  //用于记录女生的数量
        for (int i = 0; i < students.size(); i++) {
            Student s = students.get(i);
            System.out.println("姓名:" + s.getName());
            System.out.println("性别:" + s.getSex());
            System.out.println("分数:" + s.getScore());
            if(i != students.size() - 1){
                System.out.println("--------------------");
            }
            if(s.getSex() == '男'){
                count1++;
            }else{
                count2++;
            }
        }
        System.out.println("男生人数为:" + count1 + "人");
        System.out.println("女生人数为:" + count2 + "人");
        System.out.println("班级总人数为:" + students.size() + "人");
        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);
            if(s.getScore() > max) max = s.getScore();
            if(s.getScore() < min) min = s.getScore();
            allScore += s.getScore();
        }
        System.out.println("该班级的最高分是:" + max + "分");
        System.out.println("该班级的最低分是:" + min + "分");
        System.out.println("该班级的平均分为:" + ( (allScore - max - min) / (students.size() - 2) ));
    }
}

接下来回到班级管理类,完善功能:

完善班级管理类

package user.interfaceDemo;
 
import java.util.ArrayList;
 
public class ClassManager {
    private ArrayList<Student> students = new ArrayList<>();
    //创建出学生操作对象,给下面的方法进行调用,其中StudentOperatorImp1可以替换为StudentOperatorImp2,功能就进行了变化.
    private StudentOperator studentOperator = new StudentOperatorImp1();
 
    //构造器初始化出班级内部的信息
    public ClassManager(){
        students.add(new Student("余周周",'女',99));
        students.add(new Student("林杨",'男',100));
        students.add(new Student("蒋川",'男',80));
        students.add(new Student("凌翔茜",'女',90));
    }
 
    //打印出全班学生的信息
    public void printInfo(){
        studentOperator.printAllInfo(students);
    }
 
    //打印出全班学生的平均成绩
    public void printScore(){
        studentOperator.printAverageScore(students);
    }
}

测试

package user.interfaceDemo;
 
public class Test {
    public static void main(String[] args) {
        ClassManager cc = new ClassManager();
        cc.printInfo();
        cc.printScore();
    }
}


第一套方案的运行结果:


改为第二套方案:



第二套方案的运行结果为:


END



目录
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
5月前
|
Java
设计接口的几种方法
设计接口的几种方法
|
5月前
|
SQL 前端开发 Java
若依修改03----利用若依代码生成器,生成课程管理的前后端代码,课程的条件搜索接口,一旦数据表创建好了,直接交给若依代码的生成器就好了,配置代码生成信息,包含基本信息,字段信息,生成信息。字段信息决
若依修改03----利用若依代码生成器,生成课程管理的前后端代码,课程的条件搜索接口,一旦数据表创建好了,直接交给若依代码的生成器就好了,配置代码生成信息,包含基本信息,字段信息,生成信息。字段信息决
|
6月前
|
SQL 前端开发 API
SSMP整合案例第一步 制作分析模块创建与开发业务实体类
SSMP整合案例第一步 制作分析模块创建与开发业务实体类
34 0
|
7月前
|
安全 前端开发 NoSQL
如果让你设计一个接口,你会考虑哪些问题?
接口设计需关注参数校验、扩展性、幂等性、日志、线程池隔离、异常重试、异步处理、查询优化、限流、安全性、锁粒度和避免长事务。入参与返回值校验确保数据正确性;考虑接口扩展性以适应不同业务需求;幂等设计防止重复操作;关键接口打印日志辅助问题排查;核心接口使用线程池隔离确保稳定性;异常处理中可采用重试机制,注意超时控制;适合异步的场景如用户注册后的通知;并行查询提升性能;限流保护接口,防止过载;配置黑白名单保障安全;适当控制锁粒度提高并发性能;避免长事务影响系统响应。
101 2
|
7月前
|
存储 Java 数据库
平台设计-数据相关类
平台上和数据有关的类有实体类BO、视图类VO、传输类DTO;传输类又细分为信息类和请求类。
|
7月前
|
XML API 数据库
七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置
七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置
133 0
|
Java
图书管理借阅系统【Java简易版】Java三大特征封装,继承,多态的综合运用
图书管理借阅系统【Java简易版】Java三大特征封装,继承,多态的综合运用
112 0
|
jenkins 测试技术 持续交付
python接口自动化(三十六)-封装与调用--流程类接口关联续集(详解)
上一篇已经给大家都介绍过了流程类接口关联,但是由于博客的登录机制改变,所以没有办法给小伙伴们实战演练一下,那么这篇就按照上一篇计划的用jenkins来给小伙伴们演示一下流程类接口的封装和调用,其实很简单,就是用上一篇和前边这篇传送门的代码稍稍修改即可。不知道你自己练习了么,如果练习了,可以看看和我有什么不同,没练习的看看自己思路和我有啥不一样。好了废话少说进入主题
205 0
python接口自动化(三十六)-封装与调用--流程类接口关联续集(详解)
|
jenkins 测试技术 持续交付
python接口自动化(三十五)-封装与调用--流程类接口关联(详解)
流程相关的接口,主要用 session 关联,如果写成函数(如上篇),s 参数每个函数都要带,每个函数多个参数,这时候封装成类会更方便。在这里我们还是以博客园为例,带着小伙伴们实践一下。
394 0
python接口自动化(三十五)-封装与调用--流程类接口关联(详解)
下一篇
DataWorks