201521123044 《Java程序设计》第4周学习总结

1. 本章学习总结

2. 书面作业

1. 注释的应用

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

答:

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

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

答:最近发现没什么鞋穿了,想在网上购买一双。于是开始了我的购物。。。
  • 然后登陆我的账号,可以通过输入账号和密码,或者用手机扫码登陆。
  • 在主界面中,找到分类栏,选择鞋靴->男鞋->板鞋
  • 逛了好久,发现了一双还不错,选中了鞋码、颜色,加入购物车中。
  • 到结算时才发现我大概买了一双假鞋,这么贵,算了,我还是去别家看看吧!

2.2 通过这个故事我们能发现谁在用这个系统,系统中包含的类及其属性方法,类与类之间的关系。尝试找到这些类与属性,并使用思维导图描述类、属性、方法及类与类之间的关系。

答
导图:

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

答:
  • 用户信息类:
public class User{
    string username;
    string password;
}
  • 商品类:
public class Shopping{
    public void color(){
    }
    public void Shoe size(){
    }
    public void Shoe number(){
    }

}
  • 购物车类
public class ShoppingCart(){
    public void add() {
        
    }
    public void delete() {
    
    }
    
    public void purchase() {
        
    }
    
    public void clear() {
        
    }
}

3.ManagerTest.zip代码分析

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

  • 3.1 在本例中哪里体现了使用继承实现代码复用?回答时要具体到哪个方法、哪个属性。
class 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 double getSalary()
   {
      return salary;
   }
   private String name;
   private double salary;
   private Date hireDay;
}
class Manager extends Employee
{
   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;
   }

}

答:从上面代码中可体现了Mannager复用Employee的代码,具体体现在getSalary方法,以及n、s、year、month、和day等属性。
  • 3.2 Employee类及其子类Manager都有getSalary方法,那怎么区分这两个方法呢?
父类
class Employee{
   public double getSalary(){
      return salary;
   }
}
子类
class Manager extends Employee{
   public double getSalary(){
      double baseSalary = super.getSalary();
      return baseSalary + bonus;
   }
}

答:通过super来区分父类Employee及其子类Manager的getSalary方法。
  • 3.3 文件第26行e.getSalary(),到底是调用Manager类的getSalary方法还是Employee类的getSalary方法。

答:如图容易看出e.getSalary(),调用Employee类的getSalary方法;并且在for语句中的(Employee e:staff),也容易看出e.getSalary(),调用Employee类的getSalary方法。
  • 3.4 Manager类的构造函数使用super调用父类的构造函数实现了代码复用,你觉得这样的有什么好处?为什么不把父类构造函数中的相关代码复制粘贴到Manager的构造函数中,这样看起来不是更直观吗?
答:使用super调用父类的构造函数的好处:
①获取父类中的变量或者方法的引用,可以直接访问父类中的变量或者对象,进行修改赋值等操作。
②直接访问父类的方法。
③调用父类的初始化方法。

4.Object类

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

public class Main{
	public static void main(String[] args){
		System.out.println(new Fruit());
	}
}
运行结果:shapes.Fruit@15db9742

再观察println的源码发现:


再看valueof的源码:

得出结论为:直接调用了toString函数用法。

  • 4.2 如果为Fruit类添加了toString()方法,那么使用System.out.println(newFruit());调用了新增的toString方法。那么其父类中的toString方法的代码就没有了吗?如果同时想要复用其父类的toString方法,要怎么操作?(使用代码演示)
class Fruit{
		private String name;
		@Override
		public String toString() {
			return "Fruit [name=" + name + "]\n" + super.toString();
		}
		
}
	public class Main{
		public static void main(String[] args){
			System.out.println(new Fruit());
		}
	}
答:运行结果为:

可得添加toString()方法后父类toString方法依然存在,如果要复用父类的toString方法只需加上super.xxx即可。
  • 4.3 Fruit类还继承了Object类的eqauls方法。尝试分析其功能?自己编写一个equals方法覆盖父类的相应方法,功能为当两个Fruit对象name相同时(忽略大小写),那么返回true。(使用代码证明你自己覆盖的eqauls方法是正确的)
答:
代码展示:
class Fruit{
		private String name;
		public void setName(String name) {
			this.name = name;
		}
		@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 C{
		public static void main(String[] args){
			Fruit fruit1 = new Fruit();
			fruit1.setName("orange");
			Fruit fruit2 = new Fruit();
			fruit2.setName("orange");			
			System.out.println(fruit1.equals(fruit2));
		}
	}
运行结果:

不得不说eclipse是个很好的偷懒工具,原本还在想怎么写equals函数,想到eclipse有自动生成功能,所以就试了一下,没想到还真有。
  • 4.4 在4.3的基础上使用ArrayList fruitList存储多个fruit,要求如果fruitList中已有的fruit就不再添加,没有的就添加进去。请编写相关测试代码。并分析ArrayList的contatins方法是如何实现其功能的?
import java.util.*;
public class ArrayListfruit {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<String>();
		String fruit[] ={"apple","pear","apple","orange"} ;		
		for (int i = 0;i<4;i++) {
			String o = fruit[i];
			if (list.contains(o)) {
				System.out.println("contain");
			} else {
				list.add(o);
			}  			
		}		
		System.out.println(list);
	}
}
运行结果:

通过观察源码:

得出结论:在contains方法会调用o.equals(elementData[i])方法来比较两个对象的引用是否相同。

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

  • 5.1 画出类的继承关系
  • 5.2 读懂main函数,将自己推测的出代码运行结果与真正运行结果进行比较。尝试分析原因
答:代码运行结果显示为:

 分析:Person类是一个抽象类,是一个不存在实例化的对象。Employee、Student、Manager和Programmer这四个类会输出自己特有的成员变量,然后再调用父类的同名方法,对于Manager和Programmer这两个类,因为他们的父类Employee类也是继承Person类,所以他们会有两层嵌套。
  • 5.3 子类中里面使用了super构造函数,作用是什么?如果将子类中的super构造函数去掉,行不行
答:
    1.调用父类的函数方法;
    2.会出现错误,如下图:

     因为隐式的超级构造函数person()是未定义的。必须显式调用另一构造函数。
  • 5.4 PersonTest.java中的代码哪里体现了多态?你觉得多态有什么好处?多态和继承有什么关系吗
答:
体现多态:

多态的定义是:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。即相同的方法名,不同的实现,父类类型变量可以引用子类对象。
多态的作用:
(1)多态的好处:
    1. 可替换性。多态对已存在的代码具有可替换性。
    2. 可扩充性。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际 上新加子类更容易获得多态功能。  
    3. 接口性。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。  
    4. 灵活性。它在应用中体现了灵活多样的操作,提高了使用效率。  
    5. 简化性。多态简化了对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。值得注意的是,多态并不能够解决提高执行速度的问题,因为它基于动态装载和地址引用,或称动态绑定。
(2)多态与继承的关系:
    1. 继承:子类继承父类中所以的属性和方法,但是对于private的属相和方法,由于这个是父类的隐私,所以子类虽然是继承了,但是没有可以访问这些属性和方法的引用,所以相当于没有继承到。很多时候,可以理解为,没有继承。
    2. 多态:就是父类引用可以持有子类对象。这时候只能调用父类中的方法,而子类中特有方法是无法访问的,因为这个时候(编译时)你把他看作父类对象的原因,但是到了运行的时候,编译器就会发现这个父类引用中原来是一个子类的对像,所以如果父类和子类中有相同的方法时,调用的会是子类中的方法,而不是父类的。
    有几个链接都是不错的解释了多态以及多态跟继承的关系。
 参考链接:http://blog.csdn.net/jian_yun_rui/article/details/52937791
          http://www.cnblogs.com/chalk/p/4717322.html

3.码云上代码提交记录

4.PTA实验总结

  • 实验5-4:在第三题基础上,本题用到了抽象类和继承的内容,Rectangle和Circle类继承Shape类,需要注意的地方就是一定要在父类中定义好抽象的方法之后,才能在子类当中注意定义。当然即使没有被定义,将还是被视作是抽象类,需要加上abstract关键字。至于sumAllArea()和sumAllPerimeter()方法跟shape放在一起即可。
  • 实验5-5:本道题大部分借助eclipse自动生成,需要注意的地方就是加入对象时要判断之前是否已经存在同一个对象,可以用contains方法或者equals()方法的来写,其实两者是一样的,看下源码就知道了,这个问题在之前的答题有写到。
posted @ 2017-03-18 17:14  Min21  阅读(369)  评论(2编辑  收藏  举报