201521123027 《JAVA程序设计》第五周学习总结
1.本周学习总结
1.1 尝试使用思维导图总结有关多态与接口的知识点。
1.2 可选:使用常规方法总结其他上课内容
- Comparable接口与Comparator接口的区别;
- Markdown的其他用法,如分割线、文字引用等。
2.书面作业
Q1.代码阅读:Child压缩包内源代码
1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误。并分析输出结果。
答:
上图是parent包中Child.java文件的源代码,通过eclipse可以看出出错的语句是 System.out.println(i);系统提示的错误是the field Parent.i is not visible,即Parent.i不可见。原因是在Parent类中定义i为私有类型,在类之外无法调用的。而在Parent类中有geti()方法,故可以将 System.out.println(i);改为System.out.println(geti());。
修改后运行结果为:
分析:c.getParenti();输出父类的i,因为子类Child类中没有定义属性i,所以要输出父类Parent类中的i,即输出1;同理c.getParentj();依次输出父类Parent类中的j、j、i、i,即依次输出2、2、1、1,这里加不加super对结果没有影响; Other.showParentj(p);输出父类Parent类中的j、i,因为有static关键字修饰,可以直接通过类名调用。
1.2 另外一个包中的OutOfParentPackage.java,能否编译通过?提示什么错误?分析原因。
答:OutOfParentPackage.java的源代码为:
提示错误为The type Parent is not visible,即为Parent类不可见。因为Parent类没有设定访问权限,系统默认为在com.parent包内可以访问,而OutOfParentPackage.java在com.parent包外,无法访问Parent类。
修改方法:在Parent类前加上关键字public,但是此时还是会出现错误提示,因为j和geti()方法都是有protected修饰,包外仍然无法访问,所以要将protected改为public。
修改后代码为:
运行结果为:
Q2.abstract进阶:阅读GuessGame抽象类的设计与使用源代码
2.1 Guess改造前代码很简单,而改造后的代码使用了抽象类、抽象方法看起来很复杂,那这样的改造到底有什么好处呢?
答:
改造前代码
package cc.openhome;
import java.util.Scanner;
public class Guess {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int number = (int) (Math.random() * 10);
int guess;
do {
System.out.print("猜数字(0 ~ 9):");
guess = scanner.nextInt();
} while(guess != number);
System.out.println("猜中了...XD");
}
}
改造后代码
package cc.openhome;
public class Guess {
public static void main(String[] args) {
GuessGame game = new ConsoleGame();
game.go();
}
}
GuessGame代码:
package cc.openhome;
public abstract class GuessGame {
public void go() {
int number = (int) (Math.random() * 10);
int guess;
do {
print("输入数字:");
guess = nextInt();
} while(guess != number);
println("猜中了");
}
public abstract void print(String text);
public abstract void println(String text);
public abstract int nextInt();
}
ConsoleGame.java代码:
package cc.openhome;
import java.util.Scanner;
public class ConsoleGame extends GuessGame {
private Scanner scanner = new Scanner(System.in);
@Override
public void print(String text) {
System.out.print(text);
}
@Override
public void println(String text) {
System.out.println(text);
}
@Override
public int nextInt() {
return scanner.nextInt();
}
}
改造前的代码未使用抽象类,只可以用控制台输入;
改造后的代码使用了抽象类,不仅可以在控制台进行输入,也可以使用对话框图形界面等输入。
2.2 如果想将该游戏改造成图形界面,应该进行一些什么操作?
答:首先要写一个图形界面的类来继承Guess中的抽象类,然后重新写抽象类中的抽象方法。
2.3 结合该例子,你觉得什么时候应该使用abstract?
答:abstract关键字修饰抽象类,其中也包含抽象方法。如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类叫抽象类。所以当问题中仅有一个大致的框架,没有具体的方法时,就可以使用abstract关键字。
结合上题中例子,当我们要设计一个猜字游戏是,父类GuessGame类需要实现输入数字、输出是否正确等方法,而子类ConsoleGame类中有具体的实现方法,此时就要在父类GuessGame类中使用abstract关键字。
2.4 重要:在这个例子中,变化的是什么,不变的是什么?尝试结合abstract、继承等概念进行说明。
答:在这个例子中,变化的是输入环境,可以使用控制台输入,也可以从对话框图形界面输入;不变的是抽象类中的抽象方法,无论你使用什么方法输入数字,它都是使用这个抽象方法去完成这个数字游戏。一个抽象类中没有具体的方法去实现我们想要的结果,所以需要建立一个子类去继承这个抽象类,并且这个子类中包含我们所需的实现方法。
Q3.Comparable与Comparator
3.1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序?
答:
用途:Comparable接口强行实现它的每一个类的对象进行整体排序。这种排序被称为类的自然排序。
原因:一个类实现了comparable接口,说明这个类可以进行类的自然排序,另外Arrays.sort的算法用到了comparable接口,所以某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序。
3.2 有了Comparable接口为什么还需要Comparator接口呢?
答:两个接口都是可以用来实现集合中元素中的比较、排序。但是comparable接口是一个内比较器,在类内部定义了一个比较方式,局限于只能按照一种固定的方式进行排序;而Comparator接口有两个参数对象,可以按照自己所想要的排序方式对类中的对象进行排序。
Q4.面向接口案例分析
阅读Case-StudentDao.zip案例
4.1 画出类关系图,描述每个类与接口的作用。
答:
作用:
Student类:属性为String name,创建对象,toString()方法。
StudentDaoArrayImpl类:创建一个Students数组存放学生的信息,有三个抽象方法:①public Student readStudent(String name)输入一个学生的姓名,若students数组中存在name与输入的姓名相同,则返回该学生,否则返回null;②public boolean writeStudent(Student student)输入一个学生的姓名,若students数组中有空位,则将这个学生的姓名存入数组中并返回true,否则返回false;③public void diplayAllStudent()输出全部学生的信息。
StudenDaoListImpl类:设置一个以Student对象的ArrayList;有三个抽象方法:①public Student readStudent输入一个名字,若List中有学生的name与输入的名字相等,则返回该学生,否则返回null;②public boolean writeStudent输入一个学生,加入List,并返回true;③public void diplayAllStudent()输出List的全部学生。
StudentDao接口:提供三个抽象方法,写入学生信息、读取学生信息、显示学生信息。
4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?
答:StudentDaoArrayImpl定义了一个长度为size的数组用来存放学生信息,局限性在于只能存放一定数目的学生信息;而StudenDaoListImpl定义了ArrayList来存放学生信息,空间上不会受到约束。
Q5.什么是面向接口编程?面向接口编程的好处是什么?
结合题目3与4中的Test.java的代码讨论分析。不要百度原封不动照搬!
答:
面向接口编程:所谓的面向接口编程就是将方法的声明与实现分开,创建接口时只需声明抽象方法,具体的实现过程放在某个类中,类要实现接口;
题目三用到了Comparable接口与Comparator接口,通过这两个接口我们可以很方便的对我们定义的类中的对象进行比较,再用Arrays.sort进行排序;题目四中Test.java文件,定义一个StudentDao接口,想对学生信息进行写入,读取,显示等操作,只需在接口定义抽象方法,具体的实现过程放在某个类中,例如StudentDaoArrayImpl类是将学生信息存入数组中,但是会有局限性,此时我们并不需要修改StudentDaoArrayImpl类中的代码,只需要重新写一个StudenDaoListImpl类,用这个类实现接口。所以从上述两个例子中可以看出面向接口编程的好处有方便、易于程序扩展等。
Q6.结对编程:面向对象设计(大作业2-非常重要)
内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。
写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面
形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。
注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner)与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。
选做加分: 给出两人在码云上同一项目的提交记录截图,额外加分。注:两个人在码云上新建一个项目。
6.1
学生A | 学生B | 项目地址 |
---|---|---|
http://www.cnblogs.com/DevilRay/p/6613906.html | null | https://git.oschina.net/clcl1004/cccc/blob/shopping/README.md |
6.2常用功能描述框架图
6.3关键代码
class Goods{
private String name;
private String id;
private double price;
private int numble;
public Goods(String name,String id,double price,int numble){
this.name=name;
this.id=id;
this.numble=numble;
this.price=price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNumble() {
return numble;
}
public void setNumble(int numble) {
this.numble = numble;
}
@Override
public String toString() {
return "Goods [name=" + name + ", id=" + id + ", price=" + price + ", numble=" + numble + "]";
}
}
class Total implements Shop{
public double totalprice(List<Goods> com){
double t=0;
for(Goods a:com){
t=t+a.getPrice()*a.getNumble();
}
return t;
}
@Override
public void shopcar(List<Goods> com) {
// TODO Auto-generated method stub
for(Goods a:com){
System.out.println("名称:"+a.getName()+" 编号:"+a.getId()+" 价格:"+a.getPrice()+" 购买数量:"+a.getNumble());
}
}
6.4运行界面
开始界面:
选择界面:
3.码云上代码提交记录及PTA实验总结
3.1码云代码提交记录
3.2PTA实验总结
(1)Comparable接口的实现,要运用到implements关键字(语法:[修饰符] class 类名 implements<类名>{})和CompareTo方法;写返回值时,可以直接`return p1.getAge()-p2.getAge();最后直接调用Array.sort()方法进行排序。
(2)Comparator接口,此题要对Comparator接口实现对name和age分别进行升序排序,而使用Comparable接口无法实现,所以要注意这两个接口的区别。