1. 本周学习总结
1.1 尝试使用思维导图总结有关多态与接口的知识点。
2. 书面作业
作业参考文件下载
代码阅读:Child压缩包内源代码
1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误。并分析输出结果。
答:从以上截图中看到该Child.java文件无法编译通过。 System.out.println(i); 这句出错;出错原因the field parent.i is not visable,因为i在parent这个类中是私有(private)属性,因此外部无法访问。
第一种改法:将private i 改成protected i,这样子类也能访问
第二种改法:将println(i)改为println(super.geti()),这样子类也能访问
输出结果
输出结果分析:getParenti()结果是输出父类的i值;getParentj()结果依次输出父类中j和i的值;由于showParentj()为静态方法,所以在其他类中直接用其类名就能调用,因此Other.showParentj(p)输出的是parent类型p中的j和i值
1.2 另外一个包中的OutOfParentPackage.java,能否编译通过?提示什么错误?分析原因。
答:从以上截图中可以看到,(parent p)这里出错,出错原因是parent cannot be resolved to a type ,意思为无法识别的类型,也就是说Parent这个类在这个包中无法被识别。
分析原因:编写parent这个类时前面无任何修饰词(修饰词指public、private、protected),那么parent这个类就会默认只能在同一个包中才能被调用。
在parent前添加public后仍然出错,原因是parent 中的j和geti()都是protected,protected只允许同一个包中或在继承类中使用,将parent类中的j和geti()前的protected换成public就能编译通过 |
1.3 回答:如果为了访问到protected修饰的属性或方法应该怎么办?
答:protected 在同一个包里和 public 类型一样,其他类也是能够访问到的。如果在不同包里的 protected 类型的成员变量就只能通过子类来访问。
2.1 Guess改造前代码很简单,而改造后的代码使用了抽象类、抽象方法看起来很复杂,那这样的改造到底有什么好处呢?
答:改造后使用抽象类可以不局限于在控制台操作,可以在控制台或对话框图形界面等输入。
2.2 如果想将该游戏改造成图形界面,应该进行一些什么操作?
答:设计一个图形界面的类然后继承抽象类。
2.3 结合该例子,你觉得什么时候应该使用abstract?
答:当子类中都要覆盖父类中的方法时,最好用抽象类,抽象类把对象的共性抽取出来,使得代码编写简洁,例如要编写多种形状的类,而这几种形状中都会用到计算面积或周长的方法,这个时候我们就可以将父类定义为抽象类shape,父类中包含计算周长和面积的函数,不同的子类形状就可以调用父类的方法并根据形状不同编写不同程序。
2.4 重要:在这个例子中,变化的是什么,不变的是什么?尝试结合abstract、继承等概念进行说明。
答:不变的是父类(即抽象类),变化的是继承抽象类的子类(在该例子中为输入方法),不同的子类中编写相应方法覆盖了父类的方法,当中体现了继承中的多态。
Comparable与Comparator
3.1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序?
答:Comparable接口对实现它的每个类的对象进行整体排序;Arrays有一方法 public static void sort(Object[] a)对指定对象数组按升序进行排序, 数组中的所有元素都必须实现 Comparable 接口,若要对对象进行排序需要使用comparable接口并编写Compareto,才能使用Arrays.sort。
3.2 有了Comparable接口为什么还需要Comparator接口呢?
答:Comparable接口将比较代码写在自身类中,而后者在一个独立的类中实现比较。 如果在设计类的时候没有考虑到排序的问题而没有设计Comparable接口,可以通过 Comparator来实现排序。
3.3 可选:使用匿名内部类、Lambda表达式实现PTA编程5-2。
面向接口案例分析
阅读Case-StudentDao.zip案例
4.1 画出类关系图,描述每个类与接口的作用。
答:Student类:名字为属性,getter/setter和toString()方法。
StudentDao接口:写入读取和输出学生数据。
StudentDaoArrayImpl类:用数组来存放学生信息,使用接口实现三个方法,读取输出写入学生信息。
StudenDaoListImpl类:用arraylist存放信息,使用接口实现三个方法,读取输出写入学生信息。
4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?
StudenDaoListImpl |
StudentDaoArrayImpl |
答:从代码中可以看到,StudenDaoListImpl使用的是ArrayList,而StudentDaoArrayImpl使用的是数组,因此在使用接口时,StudenDaoListImpl中的writeStudent方法的编写直接使用add来添加对象,而StudentDaoArrayImpl则要使用for循环来赋值。
5.什么是面向接口编程?面向接口编程的好处是什么?结合题目3与4中的Test.java的代码讨论分析。不要百度原封不动照搬!
答:面向接口编程就是先把需求提取出来,作为接口。需求具体实现通过该接口的实现类来完成。当需求变化时,只需编写新的实现类不需要改写现有代码,减少对系统的影响。
例如题目三中说到的comparator接口,若我们需要改变对某组对象的排序(升序降序),只需要在修改接口的代码而不需要修改整个框架。再如Test.java中,由于用到了面向StudentDao接口,因此往后台写数据,无需考虑后台是什么(到底是数据库、文件、数组、List)。
6.结对编程:面向对象设计(大作业2-非常重要)
内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。
写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面
形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。
注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner)与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。
选做加分: 给出两人在码云上同一项目的提交记录截图,额外加分。注:两个人在码云上新建一个项目。
参考资料:
结对编程参考资料
可以使用Processon画图
第6题提交作业的结构:
6.1
学生A:邱晓娴 | 学生B:陈凯欣 | 项目地址 |
---|---|---|
http://www.cnblogs.com/qxx-Ultraman/ | http://www.cnblogs.com/carol520123/ | http://git.oschina.net/carolfantasy/jieduibiancheng |
任务分工:晓娴负责编写个人信息的类和菜单,凯欣负责编写商品和购物车的类。
6.2 常用功能描述框架图
6.3 关键代码
//商品类
class Goods {
String name;
double price;
String publish;
}
class Books extends Goods{
public Books(String name,double price,String publish){
this.name=name;
this.price=price;
this.publish=publish;
}
@Override
public String toString() {
return "书名:"+name+'\n'+"价格:"+price+'\n'+"出版商:"+publish ;
}
}
class Foods extends Goods{
public Foods(String name,double price){
this.name=name;
this.price=price;
}
@Override
public String toString() {
return "零食名称:"+name+'\n'+"价格"+price+'\n' ;
}
}
//购物车类
public class Shoppingcart {
double totalprice=0;
int totalnumber=0;
Goods g=new Goods();
public Shoppingcart(Goods g,int totalnumber){
this.g=g;
this.totalnumber=totalnumber;
}
public int add(int n,int i){
if(totalnumber==0)totalnumber=n;
if(i==1)
totalnumber=totalnumber+n;
else
totalnumber=totalnumber-n;
return totalnumber;
}
public double caculate(){
totalprice=(g.price)*totalnumber;
return totalprice;
}
@Override
public String toString() {
return "商品名称:"+g.name+'\n'+"购买数量:"+totalnumber+'\n';
}
}
//个人信息类
public class Perinformation {
String username;
String password;
public Perinformation(String username,String password){
this.username=username;
this.password=password;
}
public Perinformation(){
}
public String toString() {
return "Perinformation [username=" + username + ", password=" + password + "]";
}
}
//操作类
class Caozuo {
Scanner in=new Scanner(System.in);
Perinformation person=new Perinformation();
Goods[] book=new Books[2];
Goods[] food=new Foods[2];
Shoppingcart []cart=new Shoppingcart[4];
Shoppingcart []shop=new Shoppingcart[4];
private static void Booklist(Goods[] book){
book[0]=new Books("JAVA",99.9,"人民出版社");
book[1]=new Books("C语言",50,"清华大学出版社");
System.out.println("1"+book[0]);
System.out.println("2"+book[1]);
}
private static void Foodlist(Goods[] food){
food[0]=new Foods("张君雅小妹妹",9.9);
food[1]=new Foods("浪味仙",6);
System.out.println("1"+food[0]);
System.out.println("2"+food[1]);
}
public void Menu1(ArrayList<Perinformation> list){
System.out.println("1.登录");
System.out.println("2.注册");
System.out.println("3.exit");
int n=in.nextInt();
if(n==1) Denglu(list);
else if(n==2)Zhuce(list);
else System.exit(0);
}
public int Denglu(ArrayList<Perinformation> list){
while(true){
System.out.print("用户名:");
String name =in.next();
String word=null;
for (Perinformation e : list) {
if(e.username.equals(name)){
person=e;
word=new String(e.password);
break;
}
}
if(word==null){
System.out.println("该用户不存在,登陆失败");
Menu1(list);
}
else{
System.out.print("密码:");
String password=in.next();
if(password.equals(word)){
System.out.println("登陆成功");
Menu(list);
}
else {
System.out.println("密码错误,登陆失败");
Menu1(list);
}
}
}
}
public void Zhuce(ArrayList<Perinformation> list){
System.out.print("用户名:");
String username =in.next();
System.out.print("密码:");
String password=in.next();
Perinformation e=new Perinformation(username, password);
person=e;
list.add(e);
System.out.println("注册成功");
Menu(list);
}
public void Menu(ArrayList<Perinformation> list){
System.out.println("1.商品信息");
System.out.println("2.个人信息");
System.out.println("3.查看购物车");
System.out.println("4.返回登录界面");
switch(in.nextInt()){
case 1: Booklist(book);
Foodlist(food);
System.out.println("购买:1");
System.out.println("返回主菜单:0");
int j=in.nextInt();
if(j==0) Menu(list);
else if(j==1){
System.out.println("输入想要购买的商品");
System.out.println("购买书按1,食品按2");
int n=in.nextInt();
if(n==1)
{
System.out.println("1"+book[0]);
System.out.println("2"+book[1]);
System.out.println("输入1或2选择要购买哪本书");
int i=in.nextInt();
System.out.println("输入想要购买数量");
int x=in.nextInt();
Shoppingcart p=new Shoppingcart(book[i-1],x);
cart[i-1]=p;
}
else if(n==2)
{System.out.println("1"+food[0]);
System.out.println("2"+food[1]);}
else {System.out.println("输入错误");}
Menu(list);
}
break;
case 2:System.out.println(person.toString());
Menu(list);
break;
case 3:
double sum=0;
for(int i=0;i<4;i++){
if(cart[i]!=null){
System.out.println(cart[i]);
}
}
for(int i=0;i<4;i++){
if(cart[i]!=null)
sum=sum+cart[i].caculate();
}
System.out.println("总价钱:"+sum);
System.out.println("是否添加商品,是按1否按2");
int o=in.nextInt();
if(o==1)
{
System.out.println("请您输入要添加的数量");
int y=in.nextInt();
cart[0].add(y, o);
}
Menu(list);
break;
case 4: Menu1(list);
}
}
}
6.4 运行界面
码云项目截图
3. 码云上代码提交记录及PTA实验总结
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
实验总结:
5-1 这题是在课堂上完成的,主要掌握了comparable的接口的使用,以及与其紧密联系的arrays.sort的使用。
5-2 这题是考察对comparator接口的使用,与comparable不同的是它要在外部编写,这题写的很顺没有卡住的点。