1. 本章学习总结
尝试使用思维导图总结有关多态与接口的知识点
使用常规方法总结其他上课内容1.接口的出现时为了实现多态,多态的实现不一定依赖于接口。2.接口的常见成员有:全局常量和抽象方法。3.对象的类型转换:自始自终都是子类在做类型的变化。4.instanceof关键字:判断一个对象是否为某个类或者接口的实例或者子类实例。5.内部类:将一个类定义在另一个类里面,对里面这个类就叫做内部类。 可以使用匿名内部类实现接口。6.类和类的关系:继承;(单继承) 类和接口的关系:实现;(多实现) 接口和接口的关系:继承(多继承)
2. 书面作业
Q1.代码阅读:Child压缩包内源代码
1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误。并分析输出结果。
答: com.parent包中Child.java文件不能编译通过。通过eclipse运行可以发现出错的语句是System.out.println(i);提示错误是the field Parent.i is not visible。即Parent类中的i是私有属性( private int i=1;)i只能在parent类中被访问。 修改方法:(1)将System.out.println(i);改成System.out.println(geti());(2) 将private int i=1;改成 protected int i=1; 改正后运行结果如下:1.2 另外一个包中的OutOfParentPackage.java,能否编译通过?提示什么错误?分析原因。
答: 另外一个包中的OutOfParentPackage.java,不能编译通过。提示的错误如图: Parent类默认是包访问权限,而OutOfParentPackage和parent分别属于不同的两个包,无法访问。通过用public修饰parent类 使其在不同的包中可以被访问。(protected关键字:在不同的包中的类可以在继承后的子类随机存取)然后分别将protected int j=2;
改成public int j=2;
将protected int geti()
改成public int geti()
。 1.3 回答:如果为了访问到protected修饰的属性或方法应该怎么办?
答: 在相同的包中,protected修饰的属性或方法可以由相同的包中的类直接存取;在不同的包中,protected修饰的属性或方法可以在继承或间接继承于其所属的类的子类中访问。Q2.abstract进阶:阅读GuessGame抽象类的设计与使用源代码
2.1 Guess改造前代码很简单,而改造后的代码使用了抽象类、抽象方法看起来很复杂,那这样的改造到底有什么好处呢?答: 改造前,未使用抽象类,只能控制台输出 运行界面如: 而改造后使用抽象类,可以在控制台,也可以使用对话框图形界面等输入 运行界面如:2.2 如果想将该游戏改造成图形界面,应该进行一些什么操作?
答: 在图形界面设计上,应该由输入,提示,判断大小和统计时间四部分构成。创建这个界面首先创建了一个类Guess,该类继承Jfame类创建框架,并命名为“猜数字游戏”设置框架可视化frame.setVisible(true);设置大小和宽度frame.setSize;是否居中显示为null;另外创建标签JTextfield field1 field2 field3 field4四个标签分别设置为随机数,数字,提示,用时(所对应的文本框用于输入或显示对应的数据)设置了but1随机数,but2猜数字,but3重置三个按钮来辅助完成游戏。 程序基本框架图:2.3 结合该例子,你觉得什么时候应该使用abstract?
答: 就像在该例子中定义了抽象类(abstract class)GuessGame,而我们想要定义一些方法来描述GuessGame抽象类的的行为特征,发现这些方法的实现方式无法确定,这个时候就需要用到abstract关键字。abstract的用法:1.abstract修饰类,会使这个类成为抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,需要子类继承并覆盖其中的抽象方法。(抽象类可以不包含任何抽象方法)2.abstract修饰方法,会使这个方法变成抽象方法,只有声明(定义)而没有实现。要求其子类覆盖(实现)这个方法。调用时可以以多态方式调用子类覆盖(实现)后的方法,也就是说抽象方法必须在其子类中实现,除非子类本身也是抽象类。
2.4 重要:在这个例子中,变化的是什么,不变的是什么?尝试结合abstract、继承等概念进行说明
答: 在这个例子中,变化的是输入的环境,可以采用不同的方法输入,如从控制台输入、从对话框图形界面输入等等。不变的是抽象方法本身,其通过各种不同的方式实现。 在玩游戏时定义的GuessGame类是abstract抽象的的(包含抽象方法)即没有具体的输入、输出的的方法导致了这个游戏就没有办法进行,所以此时我们要有具体的方法来实现,而具体的实现要通过继承来完成即创建一个子类,在子类中将抽象类中的抽象方法进行实现。(抽象类的子类覆盖了抽象类的所有的抽象方法后,该子类才可以被实例化。)Q3.Comparable与Comparator
3.1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序?答: Comparable接口强行对实现它的每个类的对象进行了整体排序。在类中实现Comparable接口后(Comparable接口有public int compareTo(T o);
方法可以比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。)再来看一下Arrays.sort的原型:public static <T extends Comparable<? super T>> void sort(List list),这部分即是说你要排序的这个集合元素已经实现了接口Comparable。如果你尝试为没有实现Comparable接口的元素排序,编译器会出错:The generic method sort(List) of type Collections is not applicable for the arguments(ArrayList). The inferred type 你刚编写的类is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>。通过直接使用Arrays.sort就能通过Comparable的compareTo方法,进行直接排序。 3.2 有了Comparable接口为什么还需要Comparator接口呢?
答: 因为只能在类中实现compareTo()一次,不可能说经常来修改类的代码实现自己想要的排序,因此如果要以不同于compareTo()方法中指定的顺序排序我们的类对象,此时就可以用到Comparator接口。Q.4.面向接口案例分析
阅读Case-StudentDao.zip案例
4.1 画出类关系图,描述每个类与接口的作用。答: 其中: (1)StudentDao接口:声明public Student readStudent,public boolean writeStudent和public void diplayAllStudent()三个抽象方法。即写入学生数据、读取学生数据和显示所有学生信息。 (2)StudentDaoArrayImpl类:public StudentDaoArrayImpl设置一个长度为size的students数组;public Student readStudent输入一个名字,若students数组中有学生的name与输入的名字相等,则返回该学生,否则返回null;public boolean writeStudent输入一个学生,若数组中有空位(null),则把此学生加入students数组,并返回true,否则返回false;public void diplayAllStudent()输出全部的学生。 (3)Studen类:用来创建对象,属性为学生的名字,创建对象的名字并覆盖toString方法。方法有:getName()、setName()、toString()和构造函数。 (4)StudenDaoListImpl类:设置一个以Student对象的ArrayList,并命名List;public Student readStudent输入一个名字,若List中有学生的name与输入的名字相等,则返回该学生,否则返回null;public boolean writeStudent输入一个学生,加入List,并返回true;public void diplayAllStudent()输出List的全部学生。4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?
答:StudenDaoListImpl与StudentDaoArrayImpl各自的私有属性不同,且StudenDaoListImpl是用ArrayList实现的,而StudentDaoArrayImpl是用数组实现的(学生的数量一开始就要决定,且无法改变)。Q5.什么是面向接口编程?面向接口编程的好处是什么?结合题目3与4中的Test.java的代码讨论分析
答: 面向接口编程:实现一个程序的时候,在保证实现的层次关系,避免代码重复的同时,使用接口(接口中是抽象方法),将定义与实现尽可能分离,让类实现接口,在类中实现接口的抽象方法,而最为理想的系统设计规范应是所有的定义与实现分离(其实这非常难以实现)。 面向接口编程能够大大提高程序的灵活性以及可维护性。当实现方法需要改变时,只要接口及接口功能不变,甚至可以在不改动定义代码时将实现方法整个替换掉。(就像我们将一个60G硬盘换成一个160G的硬盘,计算机其他地方不用做任何改动,而是把原硬盘拔下来、新硬盘插上就行了,因为计算机其他部分不依赖具体硬盘,而只依赖一个IDE接口,只要硬盘实现了这个接口,就可以替换上去。) 就像是题目四Test.java中的代码,我们只要做的就是确定学生数据到底是以何种方式来存放(实现),到底使用数组还是用Arraylist来实现方法,其次才是去关注学生的数据是是哪些需要存放。在需要的时候,可以很轻易地在少改动甚至是不改动学生的数据的情况下,完成存放方式的改变。Q6.结对编程:面向对象设计(大作业2-非常重要) 内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。 写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面 形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。 注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner)与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。
如 购物车类:public class shoppingcart{ private String name; private double price; private int number; void pway();}
订单类:
public class order{ private String name; private String address; private int lnumber; private int dnunber; void dway();}
3.本周码云代码Commit历史截图
在码云的项目中,依次选择“统计-Commits历史-设置时间段”,然后搜索并截图,如下图所示
4. PTA实验总结
实验1:关键在于实现comparable接口。通过调用Arrays.sort();实现排序,同时注意compareTo方法的重写要能先对name升序排序,如果name相同再对age进行升序排序。
实验2:Comparator:以不同于compareTo()方法中指定的顺序排序我们的类对象。在这题中,就需要我们编写NameComparator类以及AgeComparator类来实现Comparator接口