首页 技术 正文
技术 2022年11月11日
0 收藏 857 点赞 2,933 浏览 8220 个字

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

标签(空格分隔): java


1. 本周学习总结

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

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

选取上课的PPT中的重点:

1.接口的语法特性:

(1)接口不是类,不能使用new进行实例化;

(2)使用instanceof运算符

  if (anObject instanceofComparable){
...}

可以查看该对象是否实现了Comparable接口

(3)接口可以扩展,将共同的行为抽象到父类接口(例子):

public interface Moveable{
void move(double x,double y);
}
public interface Powered extends Moveable{
double milesPerGallon();
double SPEED_LIMIT = 95; //public static final
}

(4)接口中可以包含常量,一个类可以实现多个接口。

2.Comparable与Comparator区别与联系

参考下面的题目3

3.接口与抽象类的区别与联系

(1)相同之处:都代表系统的抽象层,都不能被实例化,都能包含抽象方法。

(2)不同之处:可以实现多个接口,但只能继承一个类。

4.面向接口编程

参考下面的题目5


2. 书面作业

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

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

源代码如下:

package com.parent;public class Child extends Parent{
public static void main(String[] args){
Parent p = new Parent();
Child c = new Child();
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());
}
}class Other{
public static void showParentj(Parent p){
System.out.println(p.j);
System.out.println(p.geti());
}}class Parent{
private int i=1;
protected int j=2;
protected int geti(){
return i;
}
public void getj(){
System.out.println(j);
}
}

Answer:

不能通过编译,MyEclipse中出现错误提示:

改正思路和正确输出结果以及分析:

父类Parent的i是private类型的,父类的i域对于子类来说是不可见。所以我们将Parent的i定义为protected类型。得到以下输出结果:

c.getParenti():

因为子类没有重新定义i,所以输出的值还是父类的i,而父类的i在实例化的时候就初始化为1( protected int i=1;);

c.getParentj():

输出的值为父类的j,父类的j,父类的i和父类的i。因为都是在继承父类的方法,j在父类中初始化为2。

Other.showParentj(p):

输出的值父类的j和父类的i,方法用static修饰的,所以直接用类名调用。


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();
}
}
Answer:

如图:

我们可以看见OutOfParentPackage在parent包外面。

我们现在MyEclipse中编译出现错误The type Parent is not visible。

说明Parent类是不可见的。Parent类加上public。

尝试修改的代码如下:

public class Parent{
piblic int i=1;
protected int j=2;
public int geti(){
return i;
}
public void getj(){
System.out.println(j);
}
}

使用public使包外的类能够访问。


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

Answer:

protected都是不可被继承的,访问protected修饰的属性或方法可以在同一个类中调用protected修饰的属性或方法,也可以同一个包中或是子类中调用protected修饰的属性或方法。


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

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");
}
}
//改造后//Guess2.java
package cc.openhome;public class Guess2 {public static void main(String[] args) {GuessGame game = new ConsoleGame();game.go();
}
}//GuessGame.java
package cc.openhome;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();
}//ConsoleGame.java
package cc.openhome;import java.util.Scanner;public class ConsoleGame extends GuessGame {private Scanner scanner = new Scanner(System.in);@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 scanner.nextInt();
}}

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

Answer:

好处:

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

由java笔记上抽象方法和抽象类的知识点可知:因为我们不知道代码运行的环境,使用抽象方法和抽象类可以先写出代码,后来根据需求和环境续上代码。


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

Answer:

设计一个游戏图形界面类,重写上面的抽象类中的抽象方法满足图形界面的输入输出要求,然后由游戏界面类继承这个抽象类。


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

Answer:

首先我们先了解什么是抽象类和抽象方法:

一个抽象类使用关键字abstract来定义,抽象类可以包含抽象方法,当然也可以不包含抽象的方法。抽象类不能被实例化成对象,但是它可以被继承。一个抽象类可能包含有静态属性,也包含有静态方法。当一个抽象类被继承以后,子类通常要实现其父类中的所有的抽象的方法。然而,如果子类没有实现所有的父类中的抽象的方法,那么这个子类也必须被定义成抽象类。

抽象方法就是不用没有方法体的——也就是没有实现的方法(没有花括号并且后面跟着分号),就像下面这样:

abstract void sum(int a, int b);

其次,我觉得以下情况时考虑用抽象类:

  1. 你想要在几个关联紧密的类之间共享代码。
  2. 你想要继承抽象类的那些类有一些公共方法或属性抑或是有修改protected或private属性的权限。这时你也可以考虑使用抽象类。
  3. 你想要声明非静态或者是非最终执行的属性。你可以获得并且修改这些属性所属的对象的状态。

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

Answer:

我觉得变化的是代码运行环境,比如常见的文本框、控制台、图形界面等;

不变的是这个抽象类,这个类是通用的,只是根据不同的环境决定不同的输出方式方法。

说明:

抽象类(abstract)可能就像是算法,然后我们要运用它的时候,只有通过各种语言,才能在不同的平台上实现其内容。(虽然这么说可能不是那么准确)。其次,我们编写一个抽象类和抽象方法,我们必须有类继承它,这样才有意义,在具体的类中具体实现方法。


Q3.Comparable与Comparator

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

Answer:

用途:

此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareTo 方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort ( Arrays.sort进行自动排序。

分析:

先贴上JDK查询结果:

使用Comparable接口,可以让待排序对象所在的类实现Comparable接口,并重写Comparable接口中的compareTo()方法,就可以使用Arrays.sort进行排序。


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

Answer:

comparable和Comparator 都是用来实现集合中的排序的,只是Comparable是在集合内部定义的方法实现的排序,Comparator是在集合外部实现的排序。

所以,如想实现排序,就需要在集合外定义Comparator接口的方法compare()或在集合内实现Comparable接口的方法compareTo() 。

Comparable是一个对象本身就已经支持自比较所需要实现的接口(如String、Integer自己就可以完成比较大小操作)而Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较


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

Answer:

匿名内部类方法:

直接贴上代码:

//按name排序
Comparator<PersonSortable> nameComparator =
new Comparator<PersonSortable>(){
@Override
public int compare(PersonSortable o1, PersonSortable o2) {
return o1.getName().compareTo(o2.getName());
}};//按age排序
Comparator<PersonSortable> ageComparator =
new Comparator<PersonSortable>(){
@Override
public int compare(PersonSortable o1, PersonSortable o2) {
if (o1.getAge() > o2.getAge()) {
return 1;
} else if (o1.getAge() < o2.getAge()) {
return -1;
} else {
return 0;
}
}};

Lambda表达式:

1.Labmda表达式语法:

  • 参数 -> 表达式或程序块{ }
  • 如果是表达式,则return该表达式的值(无需写return语句)
  • 如果是程序块{ },可以包含多条语句

2.实现:

Comparator<PersonSortable> nameComparator =
(PersonSortable o1, PersonSortable o2) -> (o1.getName().compareTo(o2.getName())); Arrays.sort(personSortables, nameComparator);Comparator<PersonSortable> ageComparator =
(PersonSortable2 o1, PersonSortable2 o2)
-> {
if (o1.getAge() > o2.getAge()) {
return 1;
} else if (o1.getAge() < o2.getAge()) {
return -1;
} else {
return 0;
}};Arrays.sort(personSortables, ageComparator);

4.面向接口案例分析

阅读Case-StudentDao.zip案例

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

Answer:

Student类:包含名字属性,有参构造器,还有getter/setter和toString()方法。

StudentDao接口:编写了三个抽象方法,writeStudent、readStudent、diplayAllStudent。

StudenDaoListImpl类:是对StudentDao接口的操作,存放学生信息采用列表的方式,实现了接口的三个抽象方法,用ArrayList完成操作。

StudentDaoArrayImpl类:对StudentDao接口的操作,实现接口的三个抽象方法。


4.2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?

Answer:

StudenDaoListImpl是用ArrayList实现的,而StudentDaoArrayImpl是用数组实现的。


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

结合题目3与4中的Test.java的代码讨论分析。

Answer:

在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。我们在一般实现一个系统的时候,通常是将定义与实现合为一体,不加分离的,而将所有的定义与实现分离就是面向接口编程吧。

我是这么理解上面那段话的,就以题目4为例子,体现了接口来实现多态,我们只要Test类里面,我们只要做的就是面向StudentDao接口,确定数据是以何种数据结构来存放,之后往后台写数据,无需考虑后台是什么(到底是数据库、文件、数组、List)。面向接口编程可以将接口与实现相分离,从而大大提高程序的灵活性。

题目3中,分别调用Comparable和Comparator两个接口,我们可以对我们自己定义的类进行比较,Comparable接口定义一个对象支持自比较,而Comparator接口可以实现比较两个属于某一特定类的专用比较。

关于面向接口编程可以参考:面向接口编程详解

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

内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。

写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面

形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。

注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner)与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。

选做加分: 给出两人在码云上同一项目的提交记录截图,额外加分。注:两个人在码云上新建一个项目。

6.1
学生A[倪兢飞201521123061] 学生B[黄华林201521123082] 项目地址
http://www.cnblogs.com/JMUNJF/ https://home.cnblogs.com/u/moyi-h/ http://git.oschina.net/smoyi/test
6.2 常用功能描述框架图

商讨后功能流程图如下:


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

3.1. 码云代码提交记录

3.2. PTA实验

实验5.1:根据题目要求,Arrays.sort不能对自定义对象进行排序,要对自定义的PersonSortable类的对象,使用Arrays.sort进行排序。实现Comparable接口:实现先对name升序排序,如果name相同则对age进行升序排序,由于难度不大,直接关键代码:

 public int compareTo(PersonSortable per) {
int x = this.name.compareTo(per.name);
if(x!=0){
return x;
}
else{
if (this.age>per.age)
return 1;
else if(this.age<per.age)
return -1;
else
return 0;
}
}
}

实验5.2:题目要求编写不同的Comparator来满足多样的排序需求。难度其实也不大,直接贴上NameComparator类和AgeComparator类的代码:

class NameComparator implements Comparator {@Override
public int compare(Object per1, Object per2) {
PersonSortable2 p1 = (PersonSortable2) per1;
PersonSortable2 p2 = (PersonSortable2) per2;
if (p1.getName().compareTo(p2.getName()) > 0)
return 1;
else if (p1.getName().compareTo(p2.getName()) < 0)
return -1;
else
return 0;
}
}class AgeComparator implements Comparator {@Override
public int compare(Object per1, Object per2) {PersonSortable2 p1 = (PersonSortable2) per1;
PersonSortable2 p2 = (PersonSortable2) per2;
if (p1.getAge() > p2.getAge())
return 1;
else if (p1.getAge() < p2.getAge())
return -1;
else
return 0;
}
}

其实这周的PTA主要是Comparable和Comparator的应用,在上面题目3已经有了较完整的理解表达

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,026
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,517
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,364
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,145
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,779
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,856