25.2.6小记
控制反转
今天听课的时候对于这个概念听的有点云里雾里的,在这里重点解释一下。
反转控制(Inversion of Control,IoC)可以用一个生活中的比喻来理解:
传统模式:你主动控制一切
想象你是一个顾客去餐馆吃饭。在传统模式下,你需要:
自己走到厨房门口喊:“我要点菜!”
盯着厨师做菜,催促他快点。
菜做好了,自己跑去端回来。
整个过程你完全掌控流程,但非常繁琐,且需要全程参与。
反转控制模式:交给“系统”来通知你
而在反转控制模式下:
你坐下来,告诉服务员:“菜做好了叫我一声”。
你不再关心厨师什么时候做菜、怎么通知你。
当菜做好时,服务员主动通知你,你只需处理“端菜”这个动作。
这时,流程的控制权从你(调用者)转移到了服务员(框架/系统)。
对应到代码中的例子
你的按钮监听器代码就是一个典型反转控制的例子:
btnStep.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) { // 系统在按钮点击时自动调用这个方法
System.out.println("按下啦!");
step();
frame.repaint();
}
});
传统模式:你需要写一个死循环不断检查按钮是否被点击(比如 while(true) 轮询)。
反转控制:你告诉按钮:“被点击时叫我一声”,然后系统负责在事件发生时触发你的代码。
即其字面意思理解(反转控制):本来正常情况下是由写代码的人来写出相应的控制代码,但现在则是系统帮助你调用控制检测,在恰当的时间告诉你就完了。
内部类
1.在别的类里面的类叫做内部类(是一个内部的成员 )
2.在函数内部的类
有成员的权力:访问其他成员或者成员函数
在这里相当于定义了一个新的类,这个类实现了ActionListener接口
//匿名类
btnStep.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
System.out.println("按下啦!");
step();
frame.repaint();
}
});
JTable
其中JTable只是数据的表现
具体代码和示例如下:
package kcb;
import javax.swing.*;
public class KCB {
public static void main(String[] args) {
//建立一个图形化窗口
JFrame frame = new JFrame();
//表格
//传入了一个KCBData对象,KCBData类实现了TableModel接口,用于提供表格的数据。
JTable table = new JTable(new KCBData());
//JScrollPane是Java Swing中的一个容器组件,它的作用是为其他组件提供滚动功能,通常用于表格(JTable)、文本区域(JTextArea)等超出容器可视区域的组件。
JScrollPane pane = new JScrollPane(table);
frame.add(pane);
//pack()方法会自动调整JFrame的大小,以适应其中的组件。
frame.pack();
//JFrame.EXIT_ON_CLOSE表示当窗口被关闭时,程序将终止并退出。
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//这行代码设置窗口为可见。
frame.setVisible(true);
}
}
KCBData类实现了TableModel接口,用于提供表格的数据。
package kcb;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class KCBData implements TableModel{
private String[] title = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
private String[][] data = new String[8][7];
public KCBData(){
for(int i=0;i<data.length;i++){
for(int j=0;j<data[i].length;j++){
data[i][j] = "";
}
}
}
//几行
@Override
public int getRowCount() {
return 8;
}
//几列
@Override
public int getColumnCount() {
return 7;
}
@Override
public String getColumnName(int columnIndex) {
return title[columnIndex];
}
//Column都是什么类型
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
data[rowIndex][columnIndex] = (String)aValue;
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
@Override
public void addTableModelListener(TableModelListener l) {
}
}
运行呈现的窗口:
MVC设计模式
其中我们看见的是一个Jtable类的对象(Table Object),在构造Jtable对象的时候我们给它一个TableModel的一个对象 (TableModel是一个接口,且Jtable知道TableModel具体的样子),所以你实现一个TableModel给Jtable(在TableModel中需要实现override将原本的函数覆盖)
Jtable在运行过程中反过来调用你写的函数,你的数据由你自己写的TableModel来维护,Jtable只管表现
MVC(其中Model和View没有关系,即没有连接,用户的输入不是直接调整图形上展示的数据):
(Jtable)view:当它被通知数据修改了,则其从model获得数据将整个画面重新画一遍
(TableModel)Model:因为某些愿意数据修改了,则它会通知view数据已经修改,告知它需要更新
(Jtable)Control:(用户在界面上做了什么动作,相当于输入),其知道之后就可以调用model接口,使model中的数据得到调整
好处:view很单纯
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix