实验10面向对象的几个基本原则
- 楼房的窗户
- 相关知识点
所谓抽象编程,是指设计一个类别,而不是特定类别,而是抽象类或接口。“开-闭”的原则是使设计系统对外开放,对修改和关闭。其本质是在系统中添加新模块时,不需要修改现有模块。在设计系统时,首先要考虑用户需求的变化,设计应对用户变化的部分进行扩展和开放,设计的核心部分是经过仔细考虑后确定的基本结构。这部分应该修改和关闭,即不应该因为用户需求的变化而再次改变,因为这部分不是用来处理需求的变化的。
在设计某些系统时,应考虑抽象系统的整体设计。程序设计完成后,首先关闭abstract类别的修改。否则,一旦修改abstract类别,它的所有子类别都可能需要修改。它应该对增加abstract类别的子类开放,即在增加新子类别时,不需要修改其他重要类别的抽象设计。
- 实验目的
让学生掌握“开闭”原则的设计理念
- 实验要求
建筑物需要安装窗户。如果建筑物只能安装木制窗户,显然建筑物的设计并不完善。模拟建筑的设计使建筑物能够安装各种材料的窗户。具体要求如下:
- 定义抽象Window(窗户)。Window有四种非抽象方法
public double getWidth()、public double getHeight()、public void setWidth (double w)、public void setHeight(double w)Stringg和抽象方法 getMaterial()。
- 定义Building类型(建筑),其中有Window类型的ArrayList属性windows。定义一个
- public void use(ArrayList<Window> windowlist),该方法将windowlist中的每个元素调用getwidth()和getlength()返回窗口的尺寸是否符合要求。如果符合要求,将相应的元素复制到windows中的元素。窗户的大小是常量(宽度为109.98,高度为156.98)。比较算法如下:
Math.abs(w.getWidth()-width)<=1E-2&&
Math.abs(w.getHeigh()-height)<=1E-1;
- public void showWindow()显示建筑物安装的所有窗户的方法。并输入每个窗户的详细信息。格式如下:
第一扇窗是: 木制窗户 宽是 : 109.98 高是 : 156.89
- 编写几个Window的子类
WoodWindow: String getMaterial()返回“木窗”
AluminumWindow:String getMaterial()返回“铝合金窗”
运行结果如下:
第一扇窗是: 木制窗户 宽是 : 109.98 高是 : 156.89
第二扇窗是: 木制窗户 宽是 : 109.98 高是 : 156.89
第三扇窗是: 木制窗户 宽是 : 109.98 高是 : 156.89
第四扇窗是: 木制窗户 宽是 : 109.98 高是 : 156.89
- 请绘制上述系统的类图,注意用斜体表示抽象类
- 请在(1)-(3)中完成三类代码
- 实验指导
如果实验中的Window、Building、WodWindow和AluminumWindow被视为一个小的开发框架,那么Application就被视为Application.java被认为是一个使用该框架进行应用程序开发的用户程序,因此该框架满足了“开闭”的原则,当用户程序需要其他材料的窗口时,框架更容易维护,系统只需简单地扩展框架,即在框架中添加Window子类,而无需修改框架中的其他类别。
编辑
abstract class Window { private double width; private double height; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public abstract String getMaterial();}///建筑class Building { private final double windowWidth = 109.98; private final double windowHeight = 156.98; private ArrayList<Window> windows = new ArrayList<>(); public void use(ArrayList<Window> windowList) { for (Window w : windowList) { if (Math.abs(w.getWidth() - windowWidth) <= 0.01 && Math.abs(w.getHeight() - windowHeight) <= 0.1) { windows.add(w); } } } public void showWindow() { for (int i = 0; i < windows.size(); i++) { System.out.println("第 " + (i + 1) + “扇窗是” + windows.get(i).getMaterial() + " 宽是:" + windows.get(i).getWidth() + " 高是:" + windows.get(i).getHeight()); } }}class WoodWindow extends Window { @Override public String getMaterial() { return “木窗”; }}class AluminumWindow extends Window { @Override public String getMaterial() { return “铝合金窗”; }}public class Application { public static void main(String[] args) { Building schoolBuilding = new Building(); ArrayList<Window> windows = new ArrayList<Window>(); for (int i = 0; i < 7; i++) { if (i % 2 == 0) { windows.add(new WoodWindow()); windows.get(i).setWidth(109.98); windows.get(i).setHeight(156.89); } else { windows.add(new AluminumWindow()); windows.get(i).setWidth(109.99); windows.get(i).setHeight(156.87); } } schoolBuilding.use(windows); schoolBuilding.showWindow(); }}
- 搭建流水线
- 相关知识点
如果一个对象A组合了对象B,那么对象A可以委托对象B调用其方法,即对象A以组合的方式重用对象B。通过组合对象重用方法的优点是,组合对象重用方法也称为“黑盒”重用,因为当前对象只能委托包含的对象调用其方法,因此当前对象包含的对象方法的细节对当前对象来说是看不见的。此外,对象与所包含的对象之间存在弱耦合关系,因为如果修改当前对象所包含的对象类代码,则无需修改当前对象类代码。
- 实验目的
本实验的目的是让学生掌握一个对象如何组合另一个对象。
- 实验要求
装配线的作用是,用户只需将处理过的数据交给装配线,即一次让装配线上
对象处理数据。例如,在歌手比赛中,只需将评委给出的分数交给设计好的装配线即可获得选手的最终分数。装配线的第一个对象负责输入裁判给选手的分数,第二个对象负责删除最高分和最低分,最后一个对象负责计算平均分。具体要求如下:
- 编写InputScore、DelScore、ComputerAverage和Line类别
- InputScore对象负责输入分数,InputScore组合DelScore对象
- DelScore的对象负责删除最高分和最低分。DelScore结合了CoputerAverage的对象
- CoputerAverage的对象负责计算平均值
- InputScoreline组合、DelScore、ComputerAverage这三类实例
- 在主要类别中,利用Line创建流水线对象,并将裁判的分数交给流水线
- 请绘制上述系统的类图
- 请在(2)-(5)中完成四类代码
编辑
public class SingGame { public static void main(String[] args) { Line line = new Line(); line.givePersonScore(); }}class InputScore{ DelScore del; InputScore(DelScore del){ this.del = del; } public void inputScore(){ System.out.println(“请输入评委数”; Scanner read = new Scanner(System.in); int count = read.nextInt(); System.out.println(“请输入各评委的分数”); double[] a = new double[count]; for(int i =0 ; i<count; i++){ a[i] = read.nextDouble(); } del.doDelect(a); }}class DelScore{ ComputerAverage computerAve; public DelScore(ComputerAverage computerAve) { super(); this.computerAve = computerAve;} public void doDelect(double[] a){ java.util.Arrays.sort(a); System.out.println(”去掉最高分: "+a[a.length-1]+ ","); System.out.println(”去掉最高分: "+a[0]+ "。"); double b[] = new double[a.length-2]; System.arraycopy(a, 1, b, 0, a.length-2); computerAve.giveAver(b); }}class ComputerAverage{ public void giveAver(double[] b){ double sum =0; for(int i =0 ; i<b.length;i++){ sum = sum +b[i]; } double aver = sum/b.length; System.out.println(”选手最终得分 "+aver); }}class Line{ InputScore one; DelScore two; ComputerAverage three; Line(){ three = new ComputerAverage(); two = new DelScore(three); one = new InputScore(two); } public void givePersonScore(){ one.inputScore(); }}