09:简易计算器,组合+内部类回顾复习
案例:
需求:加法
分析:
首先一个 Frame 框,第一个文本框输入1,第二个输入2,点击 = 按钮时,让最后一个框输出计算结果,并且让1和2消失。
思路:
- 首先要写一个测试类 TestCalc,main方法里面要 new 一个具体的类
- 于是有一个计算器类 Calculator 继承 Frame ,因为 Java 万物皆对象。在构造函数里边搞定
- 一般还有个监听器类 MyCalculatorListener 实现 ActionListener 事件监听接口,重写 actionPerformed 事件表现方法。正常项目里面这三个应该分开写,但是为了方便,写一起。
- 计算器类中:
- 3个文本框、1个按钮、1个标签。
- 流式布局
- 将组件添加进去,自动适应窗体大小 pack(),设置可见性 setVisible 为true
5.main方法中:new 一个 Calculator,测试一下框的效果,展示如下
- 然后要给 = 绑定一个事件,把前两个框的1和2显示出来,并且把计算结果显示在第三个框上。
- 首先 button 要添加一个监听事件 button.addActionListener()需要一个实现了 ActionListener接口的实现类,即我们创建的监听器类button.addActionListener( new MyCalculatorListener)
- 接下来上边就不用动了,重点写监听事件会做什么东西即可
7.监听类:
- 首先获取三个变量,把三个变量变成参数传到构造器中。上边 new 实现事件监听接口的监听类 MyCalculatorListener 的时候,传进去即可。这样就不用想办法去外边 get ,通过传参的方式是最快的,传进来构造器默认就有这3个参数,我们就可以对它进行一些操作了
- 重写的 actionPerformed 方法:
- 获得加数和被加数,通过包装类Integer将String解析成int型
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num1.getText());
- 将这两个值 + 法运算后,放到第三个框
num3.setText("" + (n1 + n2));
- 清除前两个框
num1.setText("");
num2.setText("");
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gui.lesson2; 2 3 import java.awt.*; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 7 //简易计算器 8 public class TestCalc { 9 public static void main(String[] args) { 10 11 new Calculator(); 12 } 13 } 14 15 //计算器类 16 class Calculator extends Frame { 17 public Calculator() { 18 //3 个文本框 19 TextField num1 = new TextField(10);//columns 最大能填多少个字符 20 TextField num2 = new TextField(10);//columns 最大能填多少个字符 21 TextField num3 = new TextField(20);//columns 最大能填多少个字符 22 //1 个按钮 = 23 Button button = new Button("="); 24 25 button.addActionListener(new MyCalculatorListener(num1, num2, num3)); 26 //1 个标签 + 27 Label label = new Label("+"); 28 //布局 29 setLayout(new FlowLayout()); 30 31 add(num1); 32 add(label); 33 add(num2); 34 add(button); 35 add(num3); 36 37 pack(); 38 setVisible(true); 39 40 } 41 } 42 43 //监听器类 44 class MyCalculatorListener implements ActionListener { 45 46 //获取三个变量 47 48 private TextField num1, num2, num3;//基础教过不要这么写,但这里这么写很棒! 49 50 public MyCalculatorListener(TextField num1, TextField num2, TextField num3) { 51 this.num1 = num1; 52 this.num2 = num2; 53 this.num3 = num3; 54 } 55 56 @Override 57 public void actionPerformed(ActionEvent e) { 58 59 //1.获得加数和被加数 60 int n1 = Integer.parseInt(num1.getText());//通过包装类Integer将String解析成int型 61 int n2 = Integer.parseInt(num2.getText()); 62 63 //2.将这个值 + 法运算后,放到第三个框 64 num3.setText("" + (n1 + n2)); 65 //3.清除前两个框 66 num1.setText(""); 67 num2.setText(""); 68 } 69 }
OOP原则:组合,大于继承 !
1 class A extends B { 2 3 } 4 class A { 5 public B b; 6 7 }
案例:完全改造为面向对象的写法
分析:对象.属性使用
思路:
1.在一个类里面去调用另外一个类的引用,比如 MyCalculatorListener 没必要去单独去写,写着很累,要是我们能在一个监听器里面把它组合进来,就很好了。比如获取三个变量,就可以写成获取计算器这个对象;
- 不需要 private TextField num1, num2, num3; 这样写很 low
- 我们对 Caclulator 进行操作,无论有多少对象,我们通过 Calculator2 calculator2 = null; 就可以了
- 这就叫组合,正常的话要用这个对象,需要去实现这个接口,重写方法。
- 上边 new MyCalculatorListener(this),把 this 传进去即可,this丢进去后一般我们要提升作用域
- 提字段(属性),需要的东西提成一些变量 TextField num1, num2, num3;
- 写一个方法loadFrame()。不要构造器了,把代码粘进去即可
2.阿里巴巴手册说了,最好不要用多态,继承。多态会让你的代码更加麻烦,容易理解有错误。继承增加了耦合性。通过组合的方 式把一个对象拿过来使用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gui.lesson2; 2 3 import java.awt.*; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 7 //简易计算器 8 public class TestCalc2 { 9 public static void main(String[] args) { 10 new Calculator2().loadFrame(); 11 } 12 } 13 14 //计算器类 15 class Calculator2 extends Frame { 16 //属性 17 TextField num1, num2, num3; 18 19 //方法 20 public void loadFrame() { 21 //3 个文本框 22 num1 = new TextField(10);//columns 最大能填多少个字符 23 num2 = new TextField(10);//columns 最大能填多少个字符 24 num3 = new TextField(20);//columns 最大能填多少个字符 25 //1 个按钮 = 26 Button button = new Button("="); 27 //1 个标签 + 28 Label label = new Label("+"); 29 30 button.addActionListener(new MyCalculatorListener2(this)); 31 32 //布局 33 setLayout(new FlowLayout()); 34 add(num1); 35 add(label); 36 add(num2); 37 add(button); 38 add(num3); 39 //显示 40 pack(); 41 setVisible(true); 42 43 } 44 } 45 46 //监听器类 47 class MyCalculatorListener2 implements ActionListener { 48 49 //获取计算器这个对象,在一个类中组合另外一个类; 50 Calculator2 calculator2 = null; 51 52 public MyCalculatorListener2(Calculator2 calculator2) { 53 this.calculator2 = calculator2; 54 } 55 56 @Override 57 public void actionPerformed(ActionEvent e) { 58 //1.获得加数和被加数,通过包装类Integer将String解析成int型 59 //2.将这个值 + 法运算后,放到第三个框 60 //3.清除前两个框 61 int n1 = Integer.parseInt(calculator2.num1.getText()); 62 int n2 = Integer.parseInt(calculator2.num2.getText()); 63 calculator2.num3.setText("" + (n1 + n2)); 64 calculator2.num1.setText(""); 65 calculator2.num2.setText(""); 66 } 67 }
内部类:
最应该去使用的,更好的包装。
比如具体计算方法(监听器里面的)应该写在计算器类里面,不应该写在外边。假设能把他丢进去就是最好的。所以一般将其提成内部类。
而且监听器类中,要使用计算器类的属性,还得组合其对象,太麻烦。而把监听器类写成内部类,可以天然使用计算器类的属性,更加方便。
内部类最大的好处就是可以畅通无阻的访问外部类的属性和方法!降低了一些代码成本。有时候能用内部类优化,但是有时候会让代码更乱,看情况用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gui.lesson2; 2 3 import java.awt.*; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 7 //简易计算器 8 public class TestCalc3 { 9 public static void main(String[] args) { 10 new Calculator3().loadFrame(); 11 } 12 } 13 14 //计算器类 15 class Calculator3 extends Frame { 16 //属性 17 TextField num1, num2, num3; 18 19 //方法 20 public void loadFrame() { 21 //3 个文本框 22 num1 = new TextField(10);//columns 最大能填多少个字符 23 num2 = new TextField(10);//columns 最大能填多少个字符 24 num3 = new TextField(20);//columns 最大能填多少个字符 25 //1 个按钮 = 26 Button button = new Button("="); 27 //1 个标签 + 28 Label label = new Label("+"); 29 30 button.addActionListener(new MyCalculatorListener3()); 31 32 //布局 33 setLayout(new FlowLayout()); 34 add(num1); 35 add(label); 36 add(num2); 37 add(button); 38 add(num3); 39 //显示 40 pack(); 41 setVisible(true); 42 } 43 44 //监听器类 45 private class MyCalculatorListener3 implements ActionListener { 46 @Override 47 public void actionPerformed(ActionEvent e) { 48 //1.获得加数和被加数,通过包装类Integer将String解析成int型 49 //2.将这个值 + 法运算后,放到第三个框 50 //3.清除前两个框 51 52 int n1 = Integer.parseInt(num1.getText()); 53 int n2 = Integer.parseInt(num2.getText()); 54 num3.setText("" + (n1 + n2)); 55 num1.setText(""); 56 num2.setText(""); 57 } 58 } 59 }