1. 本章学习总结
1.1 尝试使用思维导图总结有关继承的知识点。
1.2 使用常规方法总结其他上课内容。
1.多态是面向对象的三大特性之一。多态的意思:相同的形态,可以实不同的行为。Java中实现多态可以基于继承和接口实现。Java实现多态必须具备三大条件:继承、重写和向上转型。在多态中必须存在is a关系,而且子类必须重写父类的方法(如果要调用父类方法则采用super),多态中可以把子类对象当做父类对象使用,即父类引用指向子类对象,在运行中进行动态绑定,进而实现多态性。
2.instanceof运算符用来指定对象是某以特定类的实例,例如if(p instanceof Student){student stu=(student) p;}
,只能在继承中进行类型转换,如果是将父类强制转换成子类则必须用instanceof。
3.abstract类也是多态的一种体现。
2. 书面作业
Q1.注释的应用。使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)
答:
类注释:
方法注释:
Q2.面向对象设计(大作业1,非常重要)
2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。(不得少于50字)
答:在网上买衣服,进入各种店铺看有没有喜欢的衣服,后面终于在某店挑到一件满意的裤子,在另外一家店铺挑了件上衣。将两个订单加入到购物车,并填写了收货地址,一件寄到家里一件寄到学校。过了几天,快递员把快递送到了。
2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。
2.3 尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)
答:(用AmaterasUML生成的,还不懂怎么增加辅助建模元素)
由上图可知,一共有7个类。其中最为复杂的是Oder类,每个Customer增加多个订单,加入一个购物车里,并且可以在购物车里进行增加或者删除订单。多个Merchandise可以在同一个或者多个订单里,每个订单只能有一个收货单,一个送货单,但多个订单可以有多个送货单,Shop可以有多个送货单。
Q3.ManagerTest.zip代码分析,分析ManagerTest.zip中的代码,回答几个问题:
3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。
答:构造函数的复用
方法的复用
属性的复用
3.2 Employee类及其子类Manager都有getSalary方法,那怎么区分这两个方法呢?
答:在两个类都有getSalary方法的时候,可以通过关键字super来区分,如果是super.getSalary(),则是调用父类的方法,否则调用的就是重写了的子类的getSalary方法。
3.3 文件第26行e.getSalary(),到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。
答:调用的是Manager类的getSalary。这里体现了动态绑定,编译器无法知道是哪个类的对象在调用这个方法,只有在运行时候才能根据e的类型来确定。多态的实现形式是同一接口,继承父类方法重写,同一类中方法重载,所以是根据具体类型来确定具体调用哪个类的方法。
举个例子:
这个就是多态的动态绑定,一个draw(Shape s)就可以处理所有的子类,调用了子类和父类共有的方法,即使二者输出不一样,也只会输出子类方法的行为。
再举例:
这个是多态的静态绑定,子类和父类的方法被static修饰了。它就不能进行后期绑定,所以它无法判断具体应该调用哪个类的具体方法。
3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?
答:使用super调用构造函数可以避免重复写多行一样的代码,产生冗余,节省时间和资源,可以是代码看起来更简洁。若要修改父类构造函数,则只需在父类处修改而不需要在子类里也跟着修改。
Q4.Object类
4.1 编写一个Fruit类及属性String name,如没有extends自任何类。使用System.out.println(new Fruit());是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?
答:如果没有extends自任何类,默认extends Object。所以当直接输出一个对象new Fruit()时,复用了Object类的toString方法。
由上图可知,输出的是类名加上十六进制的哈希串。
4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(new Fruit());调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)
答:当你重写了父类的toString方法,在复用的时候就是用了重写的toString方法,如果想要继续复用父类的toString方法可以通过关键字super.toString
。
4.3 Fruit类还继承了Object类的eqauls方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的)
答:
由上图可知,Object中equals方法比较的是引用。
4.4 在4.3的基础上使用ArrayList fruitList存储多个fruit,要求如果fruitList中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contatins方法是如何实现其功能的?
答:部分代码如下:
输出:
contains方法:
由上图可知:contains方法实际上用的是equals方法(覆盖了的equals方法,数组里面存储的是对象),引用API:当且仅当此列表包含至少一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,则返回 true。
Q5.代码阅读:PersonTest.java(abstract、多态)
5.1 画出类的继承关系
答:
5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因
答:运行结果如下:Manager和Programmer继承Employee,Employee继承Person类,所以有两层toString的输出。
5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?
答:
- 因为子类不能继承父类的构造函数,所以要通过super关键字进行调用父类构造函数。
- 不可以,如果删掉的话,会提示Implicit super constructor Person() is undefined. Must explicitly invoke another constructor,译为隐式的super 构造函数person()是未定义的,必须显示调用另一构造函数。
5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?
参考文件:PersonTest.java
答:
由上图可看出此代码体现了多态性,父类型变量引用了子类对象
- 多态的好处:举例长方形和圆形求周长和以及面积和。
1.当对圆形可以进行操作的时候,也可以对任意与圆有关shape均可操作。即具有可替换性。
2.新增加的类,不会对已存在的类产生影响,即具有可扩充性。
3.增加一个shape类的方法求sumArea和sumPerimeter,长方形和圆形可覆盖其方法,进行具体的求和,即具有接口性。
4.操作灵活多样,增加了使用效率,即具有灵活性。
5.减少了代码量,在进行代码修改时候,无需对不同类的每个对象进行修改,即具有简化性。
- 多态与继承的关系
没有继承就没有多态,多态需要父类向子类提供一个共同接口,通过继承父类进行方法的重写,在同一个类里进行方法的重载。
3. PTA实验总结及码云上代码提交记录
3.1本周Commit历史截图
3.2 实验总结
1.题目5-4是对5-3进行修改,增加了一个abstract Shape类,应注意abstract修饰的,不能通过创建new Shape()创建实例。sumArea和sumPerimeter可以放在main里面,这样就可以处理所有的子类,而不必为每个子类提供自己的方法。
2.题目5-5主要是对如果有重复对象则不存入数组的处理。一开始想着改写equals方法,但是发现运行总会把每个对象输出,后面改用Arraylist.contains则成功输出。
3.题目5-6大部分代码可以直接复制前面做的题目,主要是怎么将Arraylist数组里的不同类对象分开存放,通过比较取得getClass.getName与字符串"Employee"比较来判断分开存放。同样有相同对象不存入利用contains,在写equals的时候少了个!导致出来的答案错误,花了好久才发现。还有就是Comparator接口的写法,本来写了agecomparator和namecomparator,发现跟题目好像不符,只要写一个就行在if(name.compareTo(othername)!=0)return..;else return age.compareTo(ohterager);就行。
4.题目4-1、4-2、4-3只要把编程题的某些方法截取出来就行。4-2需要写一个Object数组存放不同类的对象。4-4还没看懂。