201521123082《Java程序设计》第4周总结
标签(空格分隔): java
1. 本周学习总结##
1.1 尝试使用思维导图总结有关继承的知识点。
1.2 使用常规方法总结其他上课内容。
(1)多态性:
1.相同的形态,不同的行为(不同的定义)
2.相同的方法名,不同的实现
3.父类类型变量可以引用子类对象(重要)
(2)通过 instanceof可以判断父类引用所引用的对象实例的实际类型。(对于这个知识点的运用还不太熟悉)如果变量引用的是当前类或它的父类的实例,instanceof 返回 true,否则返回 false。
参考链接:http://www.weixueyuan.net/view/6001.html
2. 书面作业##
Q1.注释的应用
使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)
Ansewr:
以PTA实验5.5为例:
类的注释:
方法的注释:
其他注释常用关键字:
@author 作者名
@date 日期
@version 版本标识
@parameter 参数及其意义
@since 最早使用该方法/类/接口的JDK版本
@return 返回值
@throws 异常类及抛出条件
@deprecated 引起不推荐使用的警告
@see reference 查看引用
@override 重写
Q2.面向对象设计(大作业1,非常重要)
2.1将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。(不得少于50字)
Answer:
最近准备学python,于是决定到各个购物网站去找书,并货比三家。首先想到某猫。于是输入了某猫的域名:
网站提示扫二维码登录:
到达搜索页面:
搜索结果如下,我看到了最心仪的那本python从入门到实践,准备点进去购买:
我发现这本书可以立即购买也可以加入购物车。但发现这本书一个账号的一次买一本,我的两个基友也想买。只好又点进去第二意向的书,再买两本。
最后到购物车去结算:
发现太贵了我还是到以下网站去学习了:
2.2通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。
Answer:
2.3尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)
Answer:
一个完整的面向对象系统,需要有满足要求和实现要求的各种类。然后各种类之间也存在着一定关系,比如类的继承。在我上述的故事中,比如子类商品可以继承父类商品的一些属性。
1.首先我们先定义登录类,在登录时,必须输入username和password或者通过扫描二维码进行登录。
public class UserofLogin {
private String userName;
private String passWord;
/*
* 在以后可以添加验证码
* 或者加入users自己的登入二维码图片数据
*/
}
2.进入网站之后必须有个主菜单网站的类,像上图可以查看购物车、个人信息:
public class Menu {
public void showUser(User user) {
}
public void showShoppingCart(ShoppingCart Cart) {
}
/*
*其他
*/
}
3.在点击个人信息时,会有如会员名、会员号、积分、收藏的各种商品和店铺等的信息,所以建一个个人信息类。
public class User {
String VIPName;
String VIPNum;
String Point;
/*
*其他用户信息
*/
}
4.然后,我们可以建立的一个同类型物品的搜索类,在搜索物品后出现含有关键字的物品,以供用户选择。(这段代码暂时还不会实现,后面补上)
5.先写一个网站商品父类,命名为GOODS,让子类商品Good来继承,并添加自己独特的属性。
public class GOODS {
String name;
String goodnum //商品编号
double price;
}
6.最重要的写好购物车这个类(实现如上图中有的功能):
public class ShoppingCart {
/*
*构建一个内部类作为购物车内的一个项目
*项目中有商品和价格
*/
class Project {
private Good good;
private int num;
}
private double TotalPrice;//用来显示总价
public void add() {
/*
*实现增加商品数量
*/
}
public void delete() {
/*
*实现减少商品数量
*也可以实现清空购物车
*/
}
public void purchase() {
/*
*实现购买商品
*可以自己付费
*可以找人代付或者匿名购买
*/
}
}
Q3.ManagerTest.zip代码分析
分析ManagerTest.zip中的代码,回答几个问题:
3.1在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。
Answer:
1.成员方法中采用了复用,如下:
Employee类:
public double getSalary() {
return salary;
}
Manager类:
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
2.成员变量中也采用了复用:
name、salary、hireDay
3.Employee类和Manager类的构造器:
public Employee(String n, double s, int year, int month, int day) {
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
hireDay = calendar.getTime();
}
public Manager(String n, double s, int year, int month, int day) {
super(n, s, year, month, day);
bonus = 0;
}
3.2 Employee
类及其子类Manager
都有getSalary方法,那怎么区分这两个方法呢?
Answer:
用super区分父类和子类的两个方法,例如使用super.getSalary()就表示父类的getSalary()方法。
3.3 文件第26行e.getSalary()
,到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。
Answer:
需要在运行的时候,e.getSalary根据e的类型确定。在这题的源代码中,可以看出e.getSalary()调用的是父类Employee类的getSalary()。
3.4 Manager
类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?
Answer:
好处:代码复用可以减少输入代码的时间和资源,不会看起来很冗长,减少代码重复现象。
虽然复制粘贴看起来直观,但是这样增加代码量来来提高易读性的做法并不可取。
Q4.Object类
4.1编写一个Fruit类
及属性Stringname
,如没有extends自任何类。使用System.out.println(newFruit())
;是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?
Answer:
代码和实现结果:
我们看看println的源码:
然后深入看valueOf的源码:
简单分析:代码中直接输出时,调用了toString()方法。归根结底使用Object的toString()方法,得到上面截图的结果。
4.2如果为Fruit
类添加了toString()方法
,那么使用System.out.println(new Fruit())
;调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)
Answer:
(1)父类的toString()方法还会有。
(2)用到super,如图:
4.3Fruit类还继承了Object
类的eqauls
方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true
。(使用代码证明你自己覆盖的eqauls方法是正确的)
Answer:
equals 方法是String类从它的超类Object中继承的,被用来检测两个对象是否相等,即两个对象的内容是否相等。
代码实现如下:
编写一个equals方法覆盖父类的相应方法:
4.4 在4.3的基础上使用ArrayList<Fruit> fruitList
存储多个fruit,要求如果fruitList
中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contains方法是如何实现其功能的?
Answer:
实现过程如下:
分析:
由下面截图可以很清楚indexOf方法中还是用到了equals()的方法。
Q5.代码阅读:PersonTest.java(abstract、多态)
5.1 画出类的继承关系
Answer:
5.2读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因
Answer:
真正运行结果:
分析:
Student、Employee、Manager和Programmer这四个类,都会先输出自己特有的成员变量(status、salary、bonus、allowance),然后调用父类的同名方法。又Manager和Programmer这两个类继承了Employee类,所以会出现如上图情况。
5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?
Answer:
作用:调用父类的构造器;
不行,编译出错,会出现“Must explicitly invoke another constructor ”的提示。因为本来父类中就没有无参构造器,去掉的话,就不能对有参构造器进行调用。
5.4PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?
Answer:
体现多态的代码:
for (Person person : peoples) {
System.out.println(person);
}
什么是多态?其实多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态。多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与不同的具体事物进行对话。
多态的好处(摘自网络):
1.可替换性。多态对已存在的代码具有可替换性。
2.可扩充性。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
3.接口性。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
4.灵活性。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性。多态简化了对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。值得注意的是,多态并不能够解决提高执行速度的问题,因为它基于动态装载和地址引用,或称动态绑定。
关于多态的比较好的一篇文章:http://blog.csdn.net/jian_yun_rui/article/details/52937791
多态与继承的关系:
通俗一点讲,继承即子类继承父类中所以的属性和方法,实现代码的复用,方法的重写、覆盖;多态即父类引用可以持有子类对象,包含动态绑定和静态绑定。
参考文章:http://www.cnblogs.com/chalk/p/4717322.html
3. 码云代码提交记录##
4.PTA实验##
1.PTA函数题实验总结:
(1)第一题是面向对象的基础题,涉及覆盖与toString的知识点,要求编写toString,格式父类的toString-company的toString-salary,其实就是用super。
(2)第二题是Object的应用,其实就是创建对象存入数组当中,然后倒序输出。
(3)第三题涉及覆盖的知识点,题目就要求写一个方法public boolean equals(Object obj)。方法中DecimalFormat df = new DecimalFormat("#.##")使salary保留两位小数,然后用下面代码比较salary是否一样。
if(!df.format(this.salary).equals(df.format(other.salary)))
return false;
(4)第四题涉及clone方法、标识接口、深拷贝,还未完成,完成后把实现过程的问题和收获补上。
2.编程题4和5的总结:
T4:
题目4是相对于题目3的改进,让Rectangle和Circle类继承Shape类,来使代码看起来更整洁。题目中最重要的应用是用abstract定义抽象类Shape,具体代码如下:
abstract class Shape{
final static double PI=3.14;//不可变常量double PI,值为3.14
private static double sum1=0.0;
private static double sum2=0.0;
public abstract double getPerimeter();
public abstract double getArea();
public static double getSum1() {
return sum1;
}
public static void setSum1(double sum1) {
Shape.sum1 = sum1;
}
public static double getSum2() {
return sum2;
}
public static void setSum2(double sum2) {
Shape.sum2 = sum2;
}
public static double sumAllArea(Shape shape){
Shape.sum1=Shape.sum1+shape.getArea();
return sum1;
}
public static double sumAllPerimeter(Shape shape){
Shape.sum2=Shape.sum2+shape.getPerimeter();
return sum2;
} //sumAllArea和sumAllPerimeter方法放在Shape类中
}
T5:
(1)题目中要在PersonOverrid类写一个equals方法,比较name、age、gender,这三者都相同,才返回true。代码实现如下:
public boolean equals(PersonOverride Person) {
if (this.name.equals(Person.name) && this.age == Person.age&& this.gender == Person.gender)
return true;
else
return false;
}
(2)题目中要求每创建一个对象都使用equals方法比较该对象是否已经在数组中存在,如果存在,则不将该对象放入数组persons2。在代码实现中,让每个新输入的对象与前面数组的对象循环比较,只有当不用时才存入数组。计算数组实际包含的对象的数量时,一开始把所有输入的对象都算进去,后来只在存入数组的那个循环体用count++来计数保证正确。