1. 本周学习总结
1.1 尝试使用思维导图总结有关继承的知识点。
1.2 使用常规方法总结其他上课内容。
本周除了继承,我们还重点学习了多态。
(1)多态性在于有相同的形态,却是不同的行为或者说是不同的定义。即相同的方法名,不同的实现。对于多态性来说,重要的是父类类型变量可以引用子类对象。
(2)多态的 instanceof 运算符:instanceof在程序中的作用,一般是通过 instanceof 就可以判断父类引用所引用的对象实例的实际类型。
(3)因为只能在继承层次内使用 cast 进行类型转换,如果随意强制类型转换,有可能会出现运行时错误,产生一个 ClassCastException 异常。所以在进行强制类型转换时,我们应该先使用 instanceof 进行判断,是否可以进行强制转换。
2. 书面作业
1. 注释的应用
使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)
2. 面向对象设计(大作业1,非常重要)
2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。(不得少于50字,参考QQ群中PPT的范例)
首先:使用https://www.taobao.com/打开淘宝
然后:使用登入名和密码,登入自己的淘宝账号
之后:登入账号后,想到自己的早餐已经吃得差不多了,就想要购买早餐。于是在搜索框中输入“早餐”。
再之后:找到了自己想要的早餐,点击进入商品页面,选择好商品的数量,口味,进入购物车。
然后:打开购物车页面,发现想要买两箱,就在页面中的数量一栏增加数量。
然后:在购物车页面的最下方点击结算按钮,进入结算页面。
最后:提交订单,使用银行卡或者支付宝进行结算,这次购物就完成了。
2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。
2.3 尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)
PS:2.2和2.3结合起来更简便,不用打两遍的文字,所以一起写了。
在这个故事中可能包含了这些类:
(1)用于存放用户的登入名,密码的User类;
class User{
private String name;
private String code;
}
(2)用于存放所有商品信息的Goods类;
class Goods{
private String name;
private int id;
private double price;
private String type;
}
(3)用于存放搜索信息的Search类;
class Search{
private String Keyname;
private int Keyid;
private String Keytype;
public Search(){}
if(Goods.name.equals(Keyname))
System.out.println(Goods);
else if(Goods.id.equals(Keyid))
System.out.println(Goods);
else if(Goods.type.equals(Keytype))
System.out.println(Goods);
else
System.out.println("Sorry");
}
(4)用于存放自己选中的商品信息的ShoppingCart类;
class ShoppingCart{
private String name;
private int id;
private int num;
private double price;
public ShoppingCart{}
public add(){
/*
*代码省略
*/
}
public delete(){
/*
*代码省略
*/
}
public pay{
double sum;
sum+=Goods.price;
}
}
(5)调用所有类和方法的主函数的Main类;
package keke;
public class Main {
public static void main(String[] args) {
/*
*代码省略
*/
}
}
(6)用于输出或者说是显示的自己购物车信息,自己的个人信息的Menu类。
class Menu{
public ShoppingCartout(){
System.out.println(ShoppingCart.name,ShoppingCart.id,ShoppingCart.num,ShoppingCart.price);
}
public Userout(){
System.out.println(User.name);
}
}
思维导图:
3. ManagerTest.zip代码分析
分析ManagerTest.zip中的代码,回答几个问题:
3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。
class Employee //Employee为父类
{
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 String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
private String name;
private double salary;
private Date hireDay;
}
class Manager extends Employee //Manager类中出现了关键字extends,即继承父类Employee,为子类。
{
/**
* @param n the employee's name
* @param s the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String n, double s, int year, int month, int day)
{
super(n, s, year, month, day);//出现了super()语句,即调用父类中的构造函数进行初始化。
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();//同样出现了super()语句,即调用父类中的getSalary()。
return baseSalary + bonus;
}
public void setBonus(double b)
{
bonus = b;
}
private double bonus;
}
3.2 Employee类及其子类Manager都有getSalary方法,那怎么区分这两个方法呢?
因为如果Employee类及其子类Manager都有getSalary方法,即子类会覆盖或者隐藏了父类中的同名方法,这时候我们就要使用super()语句才能在子类中调用父类的同名方法,近似可以认为带有super()语句的方法就是父类的方法。所以我们可以用super()语句来区分两个同名方法。
3.3 文件第26行e.getSalary()
,到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。
根据具体的代码来看,在代码的开始分别将staff[0]定义为为Manager类的boss;而将staff[1] 和 staff[2] 定义为Employee类。所以在执行后面的代码时需要根据staff类的不同而调用不同的方法,或者说是调用父类还是子类的方法。在本段代码中,因为staff[0]是Manager类的,所以调用Manager类的getSalary方法。又因为staff[1] 和 staff[2] 定义为Employee类,所以调用Employee类的getSalary方法。
3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?
(1)我认为这样可以减少代码的编写,节省时间,毕竟同样的代码不需要再写一遍了。
(2)因为虽然这样更直观,但是也更浪费时间,浪费内存,明明可以简便的事情就不需要额外增加其他事了。毕竟,这样不仅浪费打代码的人的时间,同样也增加了阅读代码的时间。
4. Object类
4.1 编写一个Fruit类及属性String name,如没有extends自任何类。使用System.out.println(new Fruit());
是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?
System.out.println(new Fruit());
因为如果在Java中直接输出一个类的对象的时候,则是会调用这个类的toString()方法,但是因为在这个代码中没有自己写的toString()方法,所以System.out.println(new Fruit());
就是继承Object类的toString()方法,Object中toString()方法的实现是这样的:getClass().getName() + "@" + Integer.toHexString(hashCode())。
就会输出本题的运行结果:类名+@+这个类的哈希码值。
4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(new Fruit());
调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)
(1)为Fruit类添加了toString()方法后:
(2)其父类中的toString方法的代码并不会没有,在子类中新增toString方法不会影响父类中的toString方法。
(3)因为就我们所知的调用父类的方法一般是使用super()语句。所以可以使用super()语句复用其父类的toString方法。
4.3 Fruit类还继承了Object类的eqauls方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的)
(1)Object类的eqauls方法:主要认为是两个对象进行比较是否相同,根据是否相同输出true or false。
(2)
4.4 在4.3的基础上使用ArrayList<Fruit> fruitList
存储多个fruit,要求如果fruitList中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contatins方法是如何实现其功能的?
(1)
(2)
通过查看ArrayList的contatins方法的源代码,不难发现在contains方法会调用 o.equals(elementData[i])方法,其中elementData[i]是个object类的实例,即contains的方法其实就是调用equals()方法。
5. 代码阅读:PersonTest.java(abstract、多态)
5.1 画出类的继承关系
5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因
因为对Person类来说,它是抽象类型,不能实例化,所以只需要考虑代码中的Student类,Employee类,Manager类和Programmer类的toString()方法,然后用super关键字来调用父类Person类的toString()方法,最后得出运行结果。
5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?
(1)作用是为了能够调用或者是继承父类的方法和属性。
(2)不能,因为如果去掉的话就不能继承父类中的方法和属性了,这样的话,一旦在子类只能继承的是默认值,即需要重新初始化。
5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?
(1)因为多态是相同的方法名,不同的实现。所以可以明显看出是代码中的toString()方法。
(2)多态的好处在于可以增强程序的可扩展性及可维护性,使代码更加简洁。同时不但能减少编码的工作量,也能大大提高程序的可维护性及可扩展性。
(3)继承:子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。
多态:子类重写父类的方法,使子类具有不同的方法实现。
3. 码云代码提交记录
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
4. PTA实验
题目集:jmu-Java-03-面向对象1-基础-封装继承 中的
函数(4-1, 4-2, 4-3,4-4较难选做)
编程(5-4, 5-5, 5-6)
- 对于4-1:使用toString()语句就行了。
- 对于4-2:使用equals()语句来比较,并使用if语句来实现不同的输入形式,并创建对象。输出时使用for语句进行倒序输出。
- 对于4-3:使用DecimalFormat df=new DecimalFormat("#.##");保留位数。同样使用equals()语句。
- 对于5-4:主要和前面的函数差不多,只是需要使用extends关键字进行继承父类。同样也使用了equals()语句。
- 对于5-5:使用了for循环来使不相等的输入才能输进对对象中,同样也使用了equals()语句。使用了toString()语句进行输出。
- 对于5-6:使用了extends关键字进行继承父类,同样在子类中使用super()语句继承父类中的方法和属性。还是用了for(Person itor:personList)进行遍历,以及contains()语句。