1. 本周学习总结
1.1 尝试使用思维导图总结有关继承的知识点。
1.2 使用常规方法总结其他上课内容。
多态性的应用:
instanceof运算符: 通过 instanceof判断父类引用所引用的对象实例的实际类型;将父类强制转换成子类之前,应使用instanceof进行检查或说判断。
动态绑定:运行时能够自动地选择调用哪个方法。
2. 书面作业
-
Q1.注释的应用
使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)
类注释方法:
/**
.......注释的内容
/
方法注释:
-
Q2.面向对象设计(大作业1,非常重要)
2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。
在京东购买耳机。打开京东购物网站,在搜索栏中输入关键字“耳机”。进一步进行精确筛选例如品牌、佩戴方式、功能用途等。确定搜索范围之后可选择按照综合、销量、评论、新品和价格这几种方式排序查看商品。找到满意的商品,点击查看详细信息,想要购买就点击“加入购物车”,最后在我的购物车中进行商品结算。
2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。
2.3 尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)
参考资料:
UML类图
面向对象案例-借款者姓名地址.zip -
Q3.ManagerTest.zip代码分析
分析ManagerTest.zip中的代码,回答几个问题:
3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。
public Employee(String n, double s, int year, int month, int day)//父类Employee的函数 { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); hireDay = calendar.getTime(); } public double getSalary()//父类Employee的函数 { return salary; } public Manager(String n, double s, int year, int month, int day)//子类Manager中的函数 { super(n, s, year, month, day); bonus = 0; } public double getSalary()//子类Manager中的函数 { double baseSalary = super.getSalary(); return baseSalary + bonus; }
可见Manager类中,
super(n, s, year, month, day)
是利用关键字super来调用父类的构造函数对自身进行初始化,复用了name、salary、year、month、day这五个属性;double baseSalary = super.getSalary()
也是调用父类方法。3.2 Employee类及其子类Manager都有getSalary方法,那怎么区分这两个方法呢?
答:如果有重写父类的方法,调用方法是子类的,如果调用父类的需要使用关键字super.方法。
3.3 文件第26行e.getSalary(),到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。
答:Employee类的方法
3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?
答:子类调用父类的构造方法,可减少代码量,也更简洁。
Q4.Object类
4.1 编写一个Fruit类及属性String name,如没有extends自任何类。使用System.out.println(new Fruit());是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?
import java.util.*; class Fruit{ private String name; } public class Main { public static void main(String[] args) { System.out.println(new Fruit()); } }
结果:Fruit@15db9742。
java中,每个类都是Object的子类,而Object有个toString方法。
在你的代码中,你直接打印了一个类,他会调用这个类的toString方法,如果你不覆盖这个方法,它就调用Object的toString方法,结果默认是这个类的类型加上内存的地址。4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(new Fruit());调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)
父类toString方法仍然存在,如果想要复用其父类的toString方法,用super.调用方法即可。代码如下:
import java.util.*; class Fruit{ private String name; public String toString() { return "name "+super.toString(); } } public class Main { public static void main(String[] args) { System.out.println(new Fruit()); } }
输出结果为:name Fruit@15db9742
4.3 Fruit类还继承了Object类的equals方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的)
Object的equal类比较两个变量在内存中的指针指向是否相同,即比较两者是否为“同一个”。
class Fruit{ private String name; Fruit(String name){ this.name=name; } @Override public String toString() { return "name "+super.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Fruit other = (Fruit) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } public class Main { public static void main(String[] args) { Fruit fruit1=new Fruit("apple"); Fruit fruit2=new Fruit("apple"); Fruit fruit3=new Fruit("watermelon"); System.out.println(fruit1.equals(fruit2)); System.out.println(fruit1.equals(fruit3)); } }
运行结果为:
true
false
4.4 在4.3的基础上使用ArrayList
fruitList存储多个fruit,要求如果fruitList中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contatins方法是如何实现其功能的? Q5.代码阅读:PersonTest.java(abstract、多态)
参考文件:PersonTest.java
5.1 画出类的继承关系
5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因
运行结果如图:
Person类被abstract修饰,是一个抽象类,抽象类不能被直接实例化,只能作为其它类的父类。剩下的四个类中,Employee和Student类继承Person类的输出格式是输出自己特有的属性,然后调用父类的toString()方法;Manager和Programmer继承Employee类,所以它们的输出格式有两次嵌套
5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?
(1)子类中里面使用了super构造函数,作用是调用父类的构造方法.
(2)如果将子类中的super构造函数去掉,则编译时会调用父类无参构函数。编译出错。
5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?
(1)首先每个类中都用了toString()方法,但输出结果都不相同;其次子类类型的引用变量即可以引用本类对象,也可引用父类对象。 (2) 把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。 赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
(3)多态与继承、重载并不是孤立的,他们之间存在着紧密的联系,多态是建立继承、重载这两者的基础之上。多态应用的三个条件:继承、子类对象指向父类引用、重写。
3. 码云代码提交记录
4. PTA实验
题目集:jmu-Java-03-面向对象1-基础-封装继承 中的
函数(4-1, 4-2, 4-3,4-4较难选做)
编程(5-4, 5-5, 5-6)
一定要有实验总结
本次的收获:
4-1:用super关键字调用父类方法。
4-3:运用DecimalFormat方法保留小数、重写equal方法。
5-4:用abstract修饰类,通过继承的关系来实现代码的复用。
5-5:重写equals判断对象是否在数组中存在。