zoukankan      html  css  js  c++  java
  • 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方法针对姓名和年龄分别进行比较,排序。
  • 相关阅读:
    maven 阿里镜像
    红黑树数据结构剖析
    一个简单的通用Makefile实现
    如何取消开机硬盘自检
    用友u8采购发票如何取消审核
    应付帐款—制单处理,出现“供应商被锁定”的解决方法
    用友系统管理员密码清除
    用友软件系统管理员账号admin密码忘记了,如何解决?
    用友 提示“尚有已全部暂估报销的单据未进行处理,不能进行12月的期末处理!”
    MySQL Windows版安装详解
  • 原文地址:https://www.cnblogs.com/KimHeechul/p/6614099.html
Copyright © 2011-2022 走看看