zoukankan      html  css  js  c++  java
  • 201521123063 《JAVA程序设计》 第5周学习总结

    1. 本周学习总结

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

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

    • 上周学习了继承和多态,满足is-a条件,但是发现会导致继承的滥用,如果只是但以的想拥有某种行为或变量,不需要一定要继承才能实现,可以使用接口

    • Comparable和Comparator区别:
      Comparable接口只提供了int compareTo(T o)方法,而Comparator接口只提供了int compare(T o1,T o2)方法
      Comparator位于包java.util下,需要导入java.util.Comparator类,而Comparable位于包java.lang下,不需要导包
      排序方法:
      Collections.sort((List list, Comparator<? super T> c)
      Arrays.sort((List list, Comparable<? super T> c)

    • 接口与抽象类
      抽象类表示这个类是什么,接口类表示这个类能做什么
      抽象类和接口都不能直接实例化
      抽象类可以有具体的方法 和属性,接口只能有抽象方法和不可变常量
      一个类只能继承一个抽象类,而一个类却可以实现多个接口
      接口和抽象类区别

    2. 书面作业

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

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

    在Child类中
     public void getParenti(){
            System.out.println(i);//此处报错:i不可见
        }
    分析:在Child的类中没有i这个属性,则morning会调用父类的i,但是i被private修饰,只允许本类访问,可改为protected,这样就可以允许子类访问了
    
    输出结果:
    1
    2
    2
    1
    1
    2
    1
    分析结果:
    由于子类Child类中没有i,j属性,那么就会使用父类的属性,所以那些输出结果都是用父类的i和j
    
    

    1.2 另外一个包中的OutOfParentPackage.java,能否编译通过?提示什么错误?分析原因。如何更改才能使之正常编译?

    public class OutOfParentPackage{
    	public static void showParentj(Parent p){
    		System.out.println(p.j);     //报错
    		System.out.println(p.geti());//报错
    		p.getj();                    //报错
    	}
    }
    

    答:不能通过编译,根据eclipse提示可以在Parent类中用getter和setter方法,或者将j的属性改为public修饰的,但是不大安全就是了,同理,也将geti和getj方法改为public的

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

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

    改造前:
    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");
        }
    }
    
    改造之后:
    public abstract class GuessGame {
        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();
    }
    
    

    分析:改造前的代码比较中规中矩,但只能在控制台输入输出,该造后,用abstract修饰输出输入的方法,使其抽象化,可以在控制台,图形界面或者以其他方式进行

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

    答:首先肯定是要导入工具包,因为输入输出,还有获取输入都是用抽象方法,具体实现的内容是由继承这些类的子类来重写这些方法来实现
    

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

    答: 当一个类中没有充足的信息来描述一个具体的对象时,可以用abstract,以不变应万变
    

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

    答:可以变化的是继承GuessGame的子类中复写父类的方法,即输入输出的方式;不变的是父类抽象类方法的定义,这些类不需要有具体的内容,毕竟不知道要干啥,可以随机应变,因为任何继承这个抽象类的子类都必须复写父类的抽象方法,这样想做什么就让子类来做就好了
    
    

    3. Comparable与Comparator

    3.1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序?
    在API中查找的结果:

    public static void sort(Object[] a)根据元素的自然顺序对指定对象数组按升序进行排序。数组中的所有元素都必须实现 Comparable 接口。此外,数组中的所有元素都必须是可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,e1.compareTo(e2) 不得抛出 ClassCastException)。
    保证此排序是稳定的:不会因调用 sort 方法而对相等的元素进行重新排序。
    
    该排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)。此算法提供可保证的 n*log(n) 性能。 
    
    
    参数:
    a - 要排序的数组 
    抛出: 
    ClassCastException - 如果数组包含不可相互比较的 的元素(例如,字符串和整数)。
    
    

    简要分析:comparable接口当中含有compareTo比较具体方法,但是只能按一种方式比较

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

    Arrays.sort(T[] a, Comparator<? super T> c) 
              根据指定比较器产生的顺序对指定对象数组进行排序。
    API文档中查找的结果:
    sort
    public static <T> void sort(T[] a,
                                Comparator<? super T> c)根据指定比较器产生的顺序对指定对象数组进行排序。数组中的所有元素都必须是通过指定比较器可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,c.compare(e1, e2) 不得抛出 ClassCastException)。
    保证此排序是稳定的:不会因调用 sort 方法而对相等的元素进行重新排序。
    
    该排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)。此算法提供可保证的 n*log(n) 性能。 
    
    参数:
    a - 要排序的数组
    c - 确定数组顺序的比较器。null 值指示应该使用元素的自然顺序。 
    抛出: 
    ClassCastException - 如果数组包含使用指定的比较器不可相互比较的 的元素。
    

    简要分析:有了Comparable接口,Arrays.sort实现比较算法进行排序,但是形式比较单一,有了Comparator接口,在集合外定义compare()的方法,可以重写compare方法。传入了两个参数,就可以根据不同的排序要求作出排序,比较灵活,在书上284页也有相应的例子

    3.3 可选:使用匿名内部类、Lambda表达式实现PTA编程5-2。

    匿名内部类:(主要代码)
    
    Comparator<PersonSortable2> n1 = new Comparator<PersonSortable2>() {      //按年龄升序,定义了匿名内部类
    			public int compare(PersonSortable2 o1, PersonSortable2 o2) {
    
    				return o1.getAge() - o2.getAge();
    			}
    		};                                                            //注意此处的分号
    		Arrays.sort(p, n1);
    		System.out.println("NameComparator:sort");
    		for (int i = 0; i < n; i++) {
    			System.out.println(p[i]);
    		}
    		Comparator<PersonSortable2> n2 = new Comparator<PersonSortable2>() {   //按姓名升序排序
    			public int compare(PersonSortable2 o1, PersonSortable2 o2) {
    
    				return o1.getName().compareTo(o2.getName());
    			}
    		};
    		Arrays.sort(p, n2);
    		System.out.println("AgeComparator:sort");
    		for (int i = 0; i < n; i++) {
    			System.out.println(p[i]);
    		}
    		System.out.println(Arrays.toString(n1.getClass().getInterfaces()));
    		System.out.println(Arrays.toString(n2.getClass().getInterfaces()));
    
    
    Lambda表达式:
    	Comparator<PersonSortable2> n1 = (PersonSortable2 o1, PersonSortable2 o2) -> (o1.getName().compareTo(o2.getName()));  
    
            Comparator<PersonSortable2> n2 = (PersonSortable2 o1, PersonSortable2 o2) -> (o1.getAge() - o2.getAge());  
    
    补充格式:
         参数 -> 表达式或程序块{  }
         如果是表达式,则return该表达式的值(无需写return语句)
         如果是程序块{ },可以包含多条语句
    

    截图:

    4. 面向接口案例分析

    阅读Case-StudentDao.zip案例
    4.1 画出类关系图,描述每个类与接口的作用。

    此图由eclipse的UML自动生成


    Student类当中只有name这个属性,有有参的构造函数,还有其对应的setter和getter方法

    StudentDao接口定义了读写学生信息和显示全部学生信息的抽象方法,

    StudenDaoListImpl类实现了StudentDao接口,用列表来存储Student类的对象,readStudent方法是通过遍历列表找到目标,writeStudent是直接通过add添加新的对象

    StudentDaoArrayImpl类也实现了StudentDao接口,不过是默认存储Student对象数组大小为80,与StudenDaoListImpl类有点不同的是读入信息是判断数组元素是否为空,才存入数组,其他大同小异

    Test类就是含有入口函数,测试用的

    4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?

    答:顾名思义,前者是用List列表来存储对象,后者是用数组来存储对象,只是实现方式不一样,结果是一样的
    
    

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

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

    答;面向接口编程就是在面向对象的前提下,由于各个对象之间有可能存在协作关系,所以可以采用接口来实现交互,题目3中的Comparable和Comparator接口同样都是用来比较的,但是后者是可以比较一个类生成的两个对象之间属性的比较,同为比较,但是实现的方式不同,题目4的StudenDaoListImpl与StudentDaoArrayImpl同样实现的结果是一样的,面向接口编程,就是在实现的方式不清楚的情况下,定义的一个接口,让其他类实现这个接口,再根据情况来写具体的内容,有了接口可变性比较强,能够解决需求变化。在书上202页第一段就有提到:写程序要有弹性,要有可维护性。
    
    

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

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

    参考书面作业第3、4题的做法,使输入输出抽象化
    类图:

    学生L 学生null 项目地址
    https://q.cnblogs.com/u/lyq063/ https://git.oschina.net/jmulyq/ShoppingCart.git

    6.2 常用功能描述框架图

    6.3 关键代码

    输入输出接口:
    public interface shop {
    	//输入输出方式抽象化
    	public void print(String text);
        public abstract void println(String text);
        public abstract int nextInt();
        public abstract Double nextDouble();
        public abstract String next();
    }
    
    菜单类:
    public class Menu implements shop{
    	
    
    	private Scanner scan = new Scanner(System.in);
    	int k=0;
    	
    	public void showmenu(Cart cart){
    		println("**********欢迎光临**********");
    		println("        1.浏览商品");
    		println("        2.查找商品");
    		println("        3.加入购物车");
    		println("        4.我的购物车");
    		println("        0.退出");
    		println("请选择:");
    		int choice=nextInt();
            Iterm[] booklist=Iterm.allproduct();
    		switch(choice){
    		    case 1:{
    		    	for(Iterm i:booklist){
    		    		println(i.toString2());
    		    	}
    		    	break;
    		    }
    			case 2:{
    				boolean flag=false;
    				String prudoct=next();
    				for(k=0;k<booklist.length;k++){
    					if(booklist[k].getName().equals(prudoct)){
    						println(booklist[k].toString2());
    						flag=true;
    						break;
    					}	
    				}
    				if(!flag){
    					println("您所查找的商品未找到,请重新输入");
    				    k=-1;
    				}else 
    					break;
    				
    			}
    			case 3:{
    				
    				if(k>=0){
    					println("请输入数量:");
    					int num=nextInt();
    					booklist[k].setNumber(num);
    					cart.addproduct(booklist[k]);
    					cart.cartmenu(booklist[k]);
    				}
    				else{
    					println("错误操作,还未选择商品!");
    				}
    				break;
    			}
    			case 4:{
    				cart.cartmenu(booklist[k]);
                                    break;
    			}
    			case 0:return;
    		}
    		showmenu(cart);
    	}
    
    	@Override
    	public void print(String text) {
    		
    		System.out.print(text);
    		
    	}
    	
    	@Override
    	public void println(String text) {
    		System.out.println(text);
    		
    	}
    
    	@Override
    	public int nextInt() {
    		return scan.nextInt();
    	}
    
    	@Override
    	public Double nextDouble() {
    		return scan.nextDouble();
    	}
    
    	@Override
    	public String next() {
    		return scan.next();
    	}
    }
    
    商品类:
    public class Iterm{
    	private String name;
    	private double price;
    	public int number;
            ...一堆setter、getter、toString方法(含有两种格式,一种是不需要输出数量的)
    
    }
    
    购物车类:
    public class Cart implements shop {
        ArrayList<Iterm> iterm = new ArrayList<Iterm>();
    	private Scanner scan = new Scanner(System.in);
    	public  void cartmenu(Iterm i) {
    		println("1.删除商品");
    		println("2.结算全部商品");
    		println("3.清空购物车");
    		println("4.显示购物车中所有商品");
    		println("0.返回菜单");
    		println("请选择:");
    		int c = nextInt();
    		switch (c) {
    		case 1: {
    			deleteproduct(i);
    			break;
    		}
    		case 2: {
    			System.out.println(allmoney());
    			break;
    		}
    		case 3: {
    			iterm.clear();
    			break;
    		}
    		case 4:{
    			for(Iterm i1:iterm){
    	    		System.out.println(i1.toString());
                            break;
    	    	}
    		}
    		case 0: {
    			return;
    		}
    		}
    	}
    
    	public void addproduct(Iterm i) {
    		if(iterm.contains(i)){
    			iterm.get(iterm.indexOf(i)).number+=i.number;
    		}
    		else iterm.add(i);
    	}
    
    	public void deleteproduct(Iterm i) {
    		iterm.remove(i);
    	}
    
    	public double allmoney() {
    		double sum = 0;
    		for (Iterm i : iterm) {
    			sum += i.getPrice() * i.getNumber();
    		}
    		return sum;
    	}
    
    	public  void showcartproduct() {
    		for (Iterm i : iterm) {
    			println(i.toString());
    		}
    	}
    
    	...还有复写接口输入输出的方法
    }
    
    测试类:
    public class PersonTest {
    
    	public static void main(String[] args) {
    		Menu menu=new Menu();
                    Cart cart=new Cart();
    		menu.showmenu();
    
    	}
    
    }
    
    

    6.4 运行界面
    主菜单及所有商品:

    在书列表中找不到的情况:

    加入购物车并结算:

    删除当前商品:

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

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

    3.1. 码云代码提交记录

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

    3.2. PTA实验

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

    实验总结:

    • 4-1
      待续

    • 5-1
      这题编写了PersonSortable类,实现了Comparable接口,根据题意来重写compareTo和toString方法
      比较简单,注意Comparable,“< >”内要写比较的对象

    • 5-2
      这题用的是比较器,需要import java.util.Comparator;,应为这题要求是分别对姓名和年龄排序,所以可以重写compare方法,传入两个对象进行属性之间的比较
      注意最后排序时候要Arrays.sort(p,new一个对象)才行,根据要求来创建对象,实现不同的排序方法

  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/lyq063/p/6603408.html
Copyright © 2011-2022 走看看