201521123006 《Java程序设计》第5周学习总结

1. 本周学习总结

1.1 尝试使用思维导图总结有关多态与接口的知识点。

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

  • 接口与抽象类拥有相同之处:(1)都代表系统的抽象层。
    (2)都不能被实例化(不能new)
    (3)都能包含抽象方法。这些抽象方法只用于描述,但不必提供具体的实现。
  • 接口与抽象类的不同之处: (1)在抽象类中可为部分方法提供默认的实现,从而避免在子类中重复实现,提高代码的可重用性。而接口则不能。
    (2)在某个类中可以实现多个接口,但只能继承一个类。
  • Java中常用的接口:(1)ActionListener() //监听接口
    (2)Comparable //比较接口
    (3)Serializable //序列化接口
    (4)Runnable //多线程接口

2. 书面作业

**1. 代码阅读:Child压缩包内源代码 **

1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误。并分析输出结果。

package com.parent;;

class Parent{
    private int i=1;
    protected int j=2;
    protected int geti(){
        return i;
    }
    public void getj(){
        System.out.println(j);
    }
}
class Other{
    public static void showParentj(Parent p){
        System.out.println(p.j);
        System.out.println(p.geti());
    }
    
}

public class Test01 extends Parent{
    public static void main(String[] args){
        Parent p = new Parent();
        Test01 c = new Test01();
        c.getParenti();
        c.getParentj();
        Other.showParentj(p);
        
    }
    public void getParenti(){
        System.out.println(i);
    }
    public void getParentj(){
        System.out.println(super.j);
        System.out.println(j);
        System.out.println(geti());
        System.out.println(super.geti());
    }
}

(1)不能编译通过。
(2)System.out.println(i);这句会出错。
(3)这句会出错的原因在于父类中的i为private修饰,父类中的i对于子类来说是不可见的。
(4)所以改正错误可以将private 改为 protected。
(5)运行输出结果:

1
2
2
1
1
2
1

首先,第一个“1”,则是c.getParenti();输出父类的i,而在父类初始化时i=1。
其次,之后的“2,2,1,1”,则是c.getParentj();输出父类的j,父类的j,父类的i,父类的i,而父类的j在初始化时j=2,而且子类中未重新定义i和j,所以i,j都是父类的。
最后,最后的“2,1”,则是Other.showParentj(p);输出父类的j和父类的i。

1.2 另外一个包中的OutOfParentPackage.java,能否编译通过?提示什么错误?分析原因。如何更改才能使之正常编译?(写不出来正确答案不要紧,但请一定写出思考过程)

import com.parent.*;
public class OutOfParentPackage{
	public static void showParentj(Parent p){
		System.out.println(p.j);
		System.out.println(p.geti());
		p.getj();
	}
}

(1)不能编译通过。
(2)提示的错误:The type keke.Parent is not visible


(3)因为OutOfParentPackage.java在com.Parent包之外,所以访问不到。
(4)根据提示把Parent改为public修饰的之后,发现依然错误。然后再根据提示将Parent中的j和geti()从protected修饰改为public修饰的。改造后的Parent类为:

此时,程序编译成功了,运行结果为:

1.3 回答:如果为了访问到protected修饰的属性或方法应该怎么办?

因为protected修饰的属性和方法是可以在本包和子类访问,所以一种方法是只要有继承关系,子类就可以用super去访问父类中定义的protected修饰的方法或属性,这是我们就可以不用管子类和父类是不是在同一个包中;而另一种方法则是使需要访问protected修饰的属性或方法的类,他们在同一个包就行。

**2. abstract进阶:阅读GuessGame抽象类的设计与使用源代码 **

**2.1 Guess改造前代码很简单,而改造后的代码使用了抽象类、抽象方法看起来很复杂,那这样的改造到底有什么好处呢? **

改造前:

package cc.openhome;
import java.util.Scanner;

public class Guess {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number = (int) (Math.random() * 10);
        int guess;
        
        do {
            System.out.print("猜数字(0 ~ 9):");
            guess = scanner.nextInt();
        } while(guess != number);
        
        System.out.println("猜中了...XD");
    }
}

改造后:

//Guess.java
package cc.openhome;
public class Guess {
    public static void main(String[] args) {
        GuessGame game = new ConsoleGame();//抽象类
        game.go();
    }
}
//classGuess.java
package cc.openhome;
public abstract classGuess {
    public void go() {
        int number = (int) (Math.random() * 10); 
        int guess;
        do {
            print("输入数字:");
            guess = nextInt();
        } while(guess != number);
        println("猜中了");
    }
    
    public abstract void print(String text);
    public abstract void println(String text);
    public abstract int nextInt();
}

好处(PS:由文件名可以知道):

  • 改造前,未使用抽象类,只能控制台输出
  • 改造后,使用抽象类,可以在控制台,也可以使用对话框图形界面等输入

**2.2 如果想将该游戏改造成图形界面,应该进行一些什么操作? **

在改造后的基础上重新再设计一个关于图形界面的类,并且这个类需要继承ConsoleGame()即需要继承我们原来写的抽象类,并且要使得我们的输入输出在图形界面中的话,则需要我们在图形界面中重新定义输入输出语句, 覆盖父类中的语句。

**2.3 结合该例子,你觉得什么时候应该使用abstract? **

  • 使用abstract修饰的类,是抽象类
  • 比如有些东西在许多类中有用得到,但是又不能够作为一种工具进行使用或者出现,这是就可以考虑使用抽象类,然后再需要用到的类中进行继承,有需要统一改动的地方只需要更改抽象类就行了,不需要将每个类都逐一更改,并且需要增添其他功能时,也只需设计好类后继承抽象类就行。
    就像本题中,我们没有后决定好使用哪种环境平台,界面显示时,就要使用抽象类,抽象类可以让这个游戏能够方便地根据需要进行改变或者增添功能。

**2.4 重要:在这个例子中,变化的是什么,不变的是什么?尝试结合abstract、继承等概念进行说明。 **

  • 变化的是:使用的环境,例如:在改造前只能使用控制台输出,但是在改造后,使用了抽象类,就可以在控制台,也可以使用对话框图形界面等不同的环境输入输出。
  • 不变的是:抽象类。我们决定使用哪种环境平台,都不会改变抽象类,抽象类本身就包含着多种的输入输出方式。我们只需根据所需的功能进行设计类,之后只需要使我们设计的类继承抽象类就行了,如果有需要实现具体细节或者具体的输入输出等功能时,只需在子类中重写语句进行。

**3. Comparable与Comparator **

**3.1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序? **

(1)Comparable接口一般用于需要排序的对象不是简单的数字型,这时就可以使用Comparable接口就行简单排序,或者自定义排序。
(2)因为查看sort的原型,我们不难发现sort为:

这说明此时需要排序的集合已经实现了Comparable接口,而Comparable接口只有一个 compareTo 方法,并且只要重写compareTo这个方法就可实现自动排序,这样就不用自己写一个排序的方法,更加方便。

**3.2 有了Comparable接口为什么还需要Comparator接口呢? **

因为Comparable接口是定义在类内部,是强行对是实现它的每个类的对象进行整体排序,且只有一种排序方式,而Comparator接口则是定义在类的外部,比较是在一个独立的类中实现,对于Comparator接口来说,它的比较是能够为进行不同的排序做准备,比如:升序、降序。所以Comparator接口可以算是对于Comparable接口的一种完善或者是功能的补充,可以实现多种排序。

**4. 面向接口案例分析 **

**阅读Case-StudentDao.zip案例 **

**4.1 画出类关系图,描述每个类与接口的作用。 **

  • Student类:属性只有String name。方法为:getName(),setName(),toString(),Student的构造函数。是StudenDaoListImpl和StudentDaoArrayImpl的父类。
  • StudentDao接口:提供三个抽象方法,writeStudent(),readStudent(),diplayAllStudent()。
  • StudentDaoArrayImpl类:使用数组来存放学生信息。具体实现接口的三个抽象方法,读取学生信息,输入学生信息,遍历学生信息输出。以及自己的构造函数。
  • StudenDaoListImpl类:使用列表来存放学生信息。与StudentDaoArrayImpl类同样是具体实现接口的三个抽象方法。

**4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别? **

主要区别就是:StudenDaoListImpl使用的是列表来存放学生信息,从而使得部分方法的使用有别与StudentDaoArrayImpl的方法使用。而StudentDaoArrayImpl使用的是数组来存放学生信息,读取和写入学生信息都是使用数组的方法。

**5. 什么是面向接口编程?面向接口编程的好处是什么? **

**结合题目3与4中的Test.java的代码讨论分析。不要百度原封不动照搬! **

  • 面向接口编程就是相当于我们把需要的方法提取出来,作为接口。方法具体实现通过该接口的实现类来完成。而我们针对需求,编写的实现类,编写的具体方法,就可以认为是面对接口编程。在题目3中便有使用 Comparable与Comparator接口,对其 CompareTo方法与Compare方法进行覆盖,从而可以直接使用Array中的sort()方法。而在题目4中使用了StudentDao接口,在接口中编写了所需要的三个抽象类方法,而后在StudentDaoArrayImpl类和StudenDaoListImpl类编写,具体实现这三种抽象方法。
  • 面向接口编程的好处:从题目3和题目4中,我们可以明显感觉到面对接口编程,当需求有变化时,只需根据新的需求来编写新的类就行,不需要对现有的代码进行修改,减少了对于系统的影响,减少了我们的工作量,也避免了出现不必要的错误,增加了程序的灵活性,方便我们在原有的代码上进行修改功能,进行扩展。

**6. 结对编程:面向对象设计(大作业2-非常重要) **

内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。
**写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面 **
**形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。 **
注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner) 与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。
选做加分: 给出两人在码云上同一项目的提交记录截图,额外加分。注:两个人在码云上新建一个项目。

第6题提交作业的结构:

6.1

(PS:本来是两个人一起写的,但是后面合不起来,就各写各的了)

徐婉萍 项目地址
http://www.cnblogs.com/KimHeechul/p/6614099.html https://git.oschina.net/KimHeechul/Java201521123006/commit/d7ceaa5eb223a233c8ac1d2bec108099913a18ca

**6.2 常用功能描述框架图 **

**6.3 关键代码 **

class product{
	public String name;
	public double price;
	
	public product(String name, double price) {
		this.name=name;
		this.price=price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "product [name=" + name + ", price=" + price + "]";
	}
}
class ShoppingCart extends product{
	public int num;
	public double sum;
	public ShoppingCart(String name,double price,int num) {
		super(name,price);
		this.num = num;
	}


	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public double getSum() {
		return sum;
	}

	public void setSum(double sum) {
		this.sum = sum;
	}

	@Override
	public String toString() {
		return "ShoppingCart [name=" + name + ", price=" + price + ", num=" + num+"]";
	}
	ArrayList <product> Goods = new ArrayList<product>();
	public void add(product goods){
		this.Goods.add(goods);
	}
	public double sumShoppingCart(){
		double sum = 0;
		for(product goods:Goods){
			sum+=goods.getPrice()*((ShoppingCart) goods).getNum();
		}
		return sum;
	}
	public boolean deleteShoppingCart(int index){
		if(index>=0&&index<Goods.size()){
			product goods;
			goods=Goods.get(index); 
			sum-=goods.getPrice()*((ShoppingCart) goods).getNum();
			Goods.remove(index);
			return true;
		}
		else
			return false;
	}
	
}
class Login {
	private String name="xwp";
	private String secret="123456";
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSecret() {
		return secret;
	}
	public void setSecret(String secret) {
		this.secret = secret;
	}
	public Login(String name, String secret) {
		super();
		this.name = name;
		this.secret = secret;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Login other = (Login) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (secret == null) {
			if (other.secret != null)
				return false;
		} else if (!secret.equals(other.secret))
			return false;
		return true;
	}
	
}
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		ArrayList<ShoppingCart> shoppingcarts = new ArrayList<ShoppingCart>();
		product[] goods = new product[5];
		goods[0] = new product("Java", 65.3);
		goods[1] = new product("Math", 37.2);
		goods[2] = new product("skirt", 80.0);
		goods[3] = new product("jacket", 46.8);
		goods[4] = new product("Ajax", 65.3);

		System.out.println("请输入帐号和密码:");
		Login account = new Login(in.next(), in.next());
		Login obj = new Login("xwp", "123456");
		if (!account.equals(obj)) {
			System.out.println("帐号或密码错误!");
			return;
		}

		System.out.println("登入成功!");
		while (true) {
		System.out.println("请输入要搜索的商品名:");
		String name = in.next();
		int i;
		for (i = 0; i < goods.length; i++) {
			if (name.equals(goods[i].getName())){
				System.out.println(goods[i]);
				break;
			}
		}
		if (i == goods.length){
			System.out.println("找不到该商品!");
			return;
		}
		else {
			System.out.println("1.添加至购物车并查看     2.结算此商品     3.结算购物车及此商品");
			int choice=in.nextInt();
			if ( choice== 1)
			{
				System.out.println("输入需要的数量");
				ShoppingCart shoppingcart = new ShoppingCart(goods[i].getName(), goods[i].getPrice(),in.nextInt());
				shoppingcarts.add(shoppingcart);
				System.out.print("显示购物车");
				System.out.println(shoppingcarts);
				
				
			}
			else if (choice == 2){
				System.out.println("输入此商品需要的数量");
				double sum = 0.0;
				ShoppingCart shoppingcart = new ShoppingCart(goods[i].getName(), goods[i].getPrice(),in.nextInt());
				sum += shoppingcart.getPrice()*shoppingcart.getNum();
				System.out.println("总价:");
				System.out.println(sum);
			}
			else if(choice == 3){
				System.out.println("输入此商品需要的数量");
				double sum = 0.0;
				for (ShoppingCart shoppingcart : shoppingcarts) {
					sum += shoppingcart.getPrice()*shoppingcart.getNum();
				}
				sum+=goods[i].getPrice()*in.nextInt();
				System.out.println("总价:");
				System.out.println(sum);
			}
		}
		}
	}
}

**6.4 运行界面 **

3. 码云上代码提交记录及PTA实验总结

**题目集:jmu-Java-04-面向对象2-进阶-多态接口内部类 **

**3.1. 码云代码提交记录 **

**在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图 **

**3.2. PTA实验 **

继续完成前面未完成的实验面向对象1-基础-封装继承
函数(选做:4-1)、编程(5-1, 5-2)
一定要有实验总结

  • 5-1:主要是使用Comparable接口,利用compareTo方法进行比较,排序。
  • 5-2:主要是使用Comparator接口,利用compare方法针对姓名和年龄分别进行比较,排序。
posted @ 2017-03-25 00:47  HeeCHUL  阅读(288)  评论(0编辑  收藏  举报