第4周作业-面向对象设计与继承

1. 本周学习总结

1.1 尝试使用思维导图总结有关继承的知识点。

1.2 使用常规方法总结其他上课内容。

总结: 多态性
(1)概念:相同的形态,不同的行为——父类类型变量可以引用子类对象,但不能将父类的引用赋给子类类型变量。
(2)instanceof运算符: ① 通过 instanceof判断父类引用所引用的对象实例的实际类型。② 只能在继承层次内进行类型转换(不随意强制转换)。③ 将父类强制转换成子类之前,应使用instanceof进行检查或说判断。
(3)动态绑定(dynamic binding):运行时能够自动地选择调用哪个方法。
注释: 便于之后看到理解,不用再梳理一遍代码才明白此程序的意义。
注释格式基本为

    /**
    *
    *@...
    */

2. 书面作业

1. 注释的应用——使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看。(截图)

    我的注释:


    查看效果:






2. 面向对象设计(大作业1,非常重要)

2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事。(不得少于50字)

Answer:

    2017年3月1日小王在网上浏览淘宝,搜索自己想要的物品,看到中意的便将它加入购物车中;突然想起需要为妹妹买一套衣服,她就继续搜索浏览,看到一件合适的衣服但是用户评价不是很好,就在找到这件衣服的界面中寻找相似的物品,然后在搜索结果中进行选择,查看后把中意的加入购物车并进行结算。
2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。

Answer:

    通过这段话我们可以得知系统中包含的类有:物品(包括衣服),购物车,搜索,用户菜单。
尝试画思维导图之UML类图:

2.3 尝试使用Java代码实现故事中描述的这一过程(不必很完善),将来要在这个基础上逐渐完善、扩展成一个完整的面向对象的系统。(可选:加分)

Answer:

import java.util.ArrayList;

public class Online_shopping {

	public static void main(String[] args) {
		// 调用函数
	}

}

class User_Menu {
	public void Search() {
		Search search = new Search();
	}

	public void Shoppingcart(Shoppingcart shoppingcart) {

	}

	public void Pingjia(Pingjia pingjia) {

	}
}

class Allgoods {
	private String name;
	private double price;
	private int number;

	public void Lookupsimilarity() {

	}

	public void Lookupthesame() {

	}

	public void Lookdetails() {

	}
}

class Search {
	private String key;
	ArrayList<Allgoods> arrayList = new ArrayList<Allgoods>();
}

class Shoppingcart {
	private double Sumprice;

	public void add() {

	}

	public void delete() {

	}
}

class Pingjia {
	private String Messege;
}

class cloths extends Allgoods {
	private String size;

}

3. ManagerTest.zip代码分析

——分析ManagerTest.zip中的代码,回答几个问题:

3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。

Answer:

    子类Manager中用到了父类Employee中的n,s,year,month,day 五大属性以及getSalary方法。(在getSalary中还进行了覆盖操作)
    
    子类中使用继承实现代码复用的代码:
public Manager(String n, double s, int year, int month, int day)
   {
      super(n, s, year, month, day);
      bonus = 0;
   }

   public double getSalary()
   {
      double baseSalary = super.getSalary();
      return baseSalary + bonus;
   }
3.2 Employee类及其子类Manager都有 getSalary方法,那怎么区分这两个方法呢?

Answer:

    如3.1代码所示,在调用父类的属性与方法时皆用到了super关键字,这就让编译器区分了用到的方法是属于父类还是子类。
3.3 文件第26行e.getSalary(),到底是调用Manager类的 getSalary方法还是Employee类的 getSalary方法。

Answer:

    e.getSalary()根据程序运行的情况进行调用相应的方法,即动态绑定。此代码中如果是boss 则调用 Manager类的 getSalary方法。
3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?

Answer:

    使用 super调用父类的构造函数便于日后修改,也便于编译器区分方法来源。把父类构造函数中的相关代码复制粘贴到`Manager`的构造函数中看起来是更直观没错,但是这会造成代码的冗长。再加上,引入继承本就是要是代码复用简便程序,减少空间多余的使用,提高效率;如果简单的复制粘贴不就使得继承没有意义了吗?

4. Object

4.1 编写一个Fruit类及属性String name,如没有extends自任何类。使用System.out.println(new Fruit());是调用Fruit的什么方法呢?该方法的代码是从哪来的?尝试分析这些代码实现了什么功能?

Answer:

    使用System.out.println(new Fruit()); 是调用 Fruit的 println方法,准确的说是 toString方法。该方法的代码源自Object类,它是所有类的父类,当然包括Fruit类。
    代码:
public class Fruit {
	private String name;
	public static void main(String[] args) {
		System.out.println(new Fruit());
	}

}
    运行结果:

分析:

    首先,看一下println的源代码:
public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }
    它的功能就是输出并换行,还用了valueOf方法来"Returns the string representation of the Object argument.",那再看一下valueOf的源代码:
public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
    其实就是用了 Object类中的 toString()。
4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(new Fruit());调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)

Answer:

    如果为 Fruit类添加了 toString()方法并进行调用,其父类的 toString方法依然存在,只是在子类中直接使用或重新定义了 toString方法(这里重新定义的概念是:并非完全不满意父类中的方法,只是希望在执行父类中方法的前后做点加工。——书本P172)。
    如果同时想要复用其父类的 toString方法,就使用 super关键字。代码如下:
public class Fruit {
	private String name;
	
	@Override
	public String toString() {
		return "引用父类:\n" + super.toString();
	}

	public static void main(String[] args) {
		System.out.println(new Fruit());
	}

}
    运行结果:

4.3 Fruit类还继承了Object类的eqauls方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的)

Answer:

    Object类的 eqauls方法的功能:Indicates whether some other object is "equal to" this one. (显示其它对象是否“等于”这一个) equal的源代码:
public boolean equals(Object obj) {
        return (this == obj);
    }
    使用Eclipse自动生成:
	@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.equalsIgnoreCase(other.name))//原代码:else if (!name.equals(other.name)),但题目要求忽略大小写。
			return false;
		return true;
	}
    加上自己的输出代码:
public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		Fruit f1 = new Fruit();
		Fruit f2 = new Fruit();
		f1.name = "APPLE";
		f2.name = "apple";
		System.out.println(f1.equals(f2));
	}
    运行结果:

5. 代码阅读:PersonTest.java(abstract、多态)

5.1 画出类的继承关系

Answer:

5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因

Answer:

    推测运行结果:Employee,Student,Programmer,Manager按年龄从小到大的顺序分别用toString方法中的格式输出结果。
    真正运行结果:
Manager [bonus=12000.3, toString()=Employee [salary=90000.1, toString()=Person [name=Clark, adress=GE, phonenumber=111, email=111@mail.com, age=10, gender=mail]]]
Student [status=1, toString()=Person [name=wang, adress=110, phonenumber=15959, email=15959@163.com, age=18, gender=male]]
Employee [salary=1000.0, toString()=Person [name=zhang, adress=136, phonenumber=1360, email=1360@mail.com, age=21, gender=female]]
Programmer [allowance=50000.0, toString()=Employee [salary=100000.0, toString()=Person [name=Gates, adress=usa, phonenumber=911, email=911@com, age=59, gender=male]]]
    分析原因:Manager类是Person类的子类Employee类的子类,三重嵌套按 toString中的格式输出;Student类是Person类的子类,双重嵌套输出;Employee类是Person类的子类,双重嵌套输出;Programmer类是Person类的子类Employee类的子类,三重嵌套按 toString中的格式输出。
5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行?

Answer:

    子类中里面使用了super构造函数的作用是:调用父类的构造函数。
    不能将子类中的super构造函数去掉,原因:创建子类时父类构造函数无论如何都会被调用,如果子类构造函数没有显式地调用父类的构造函数,则自动调用父类默认无参构造函数,如果父类无相应无参构造函数,则会出错。拿这个程序来说,恰好其属于父类无相应无参构造函数(都需要参数),所以会编译错误。

示例:

5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗?

Answer:

    体现多态的地方:
    for (Person person : peoples) {
        System.out.println(person);
    }//父类类型变量引用所有子类对象,这行代码根据不同的子类实现相应的toString方法。
    多态的好处("一个接口,多种实现"):(1)减少相似的代码,节省空间,提高效率。(2)有利于增添新类或修改子类。(3)提高了代码的扩展性。
    多态与继承的关系:多态与继承中的方法重写密切相关,在方法中接收父类类型作为参数,在方法实现中调用父类类型的各种方法。当把子类作为参数传递给这个方法时,JVM会根据实际创建的对象类型,调用子类中相应的方法。

3. 码云代码提交记录 (在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图)

4. PTA实验——实验总结

(1)函数4-1:一开始没有看懂题目,纠结了很久,结果原来是只要写 public String toString()里的内容,了解了就很简单了。
(2)函数4-2:注意到题目要求倒序输出并且注意使用倒序的方式;再注意一些细节。
(3)函数4-3:重写equals方法,注意保留小数的方法,不要忽略null的情况。
(4)编程5-4:没有掌握继承的用法,陷入瓶颈,输出的时候遇到了问题 --> 通过看书和ppt逐渐熟悉;而后周四的课上懂得了继承的用法;再询问同学。
(5)编程5-5:根据步骤,用到了ArrayList的contains方法,注意判断对象是否已经在数组中存在。
(6)编程5-6:
posted @ 2017-03-18 17:40  wuht  阅读(224)  评论(2编辑  收藏  举报