第5周-继承、多态、抽象类与接口
1. 本周学习总结
1 尝试使用思维导图总结有关多态与接口的知识点。
2 可选:使用常规方法总结其他上课内容。
2. 书面作业
作业参考文件下载
##1.代码阅读:Child压缩包内源代码
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());
}
}
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);
}
}
package com.parent;
class Other{
public static void showParentj(Parent p){
System.out.println(p.j);
System.out.println(p.geti());
}
}
1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误。并分析输出结果。
不能编译通过;System.out.println(i)会出错,因为i变量在parent变量中是用private定义的,在Child.java中无法引用,把private改成protected。修改后运行结果如下
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();
}
}
不能通过编译,会提示如下错误;因为在这个包中不能调用刀Parent,需要把Parent定义加上public。
3 回答:如果为了访问到protected修饰的属性或方法应该怎么办?
把protected改成public就可以在其他包里访问它的属性或方法。
2.abstract进阶:阅读GuessGame抽象类的设计与使用源代码
###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");
}
}
//改造后
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();
}
比如如果你想要在知道输入之前就编写出相关代码,改造前的函数就不可以实现了,因为它的输入只能在控制台;用改造后的函数,它可以很早就写出来然后若想要调用就不需要从再从控制台输入,可以从执行处直接输入引用。
###2 如果想将该游戏改造成图形界面,应该进行一些什么操作?
先找到一个图形界面,定义好相关的类和属性,然后调用game的抽象函数。
###3 结合该例子,你觉得什么时候应该使用abstract?
当我们需要引用该函数时,就是该函数专门用来被继承;
如果我们需要多次使用该函数,这时候用抽象函数可以减少很多麻烦;
比如像这个例子一样,我们不知道要输入的变量的确切值,但是我们要写出函数就需要用到抽象函数。
###4 重要:在这个例子中,变化的是什么,不变的是什么?尝试结合abstract、继承等概念进行说明。
变化的是输入环境,我们可以用很多不同的的输入环境进行输入,既可以从控制台还可以从web和其他一些环境输入;
不变的是这个游戏类,他的方法,属性都是不变的。
3.Comparable与Comparator
1 描述Comparable接口的用途。为什么某个类实现了Comparable接口就可以直接使用Arrays.sort对其进行排序?
Comparable接口的用途是对实现它的每个类的对象进行整体排序(使用Arrays.sort功能);
进了老师的ppt看了一会才知道,所有实现Comparable的对象都有一个共同的特性-可以被比较,具体体现在均拥有compareTo方法, 即拥有共同的行为!
Arrays.sort就是面向Comparable接口进行编程,这就是所谓的面向接口编程
2 有了Comparable接口为什么还需要Comparator接口呢?
Comparable接口是一个类比较器,在类内部定义了一种比较方式;
Comparator接口在一个独立的类中实现比较。
3 可选:使用匿名内部类、Lambda表达式实现PTA编程5-2。
4.面向接口案例分析
阅读Case-StudentDao.zip案例
1 画出类关系图,描述每个类与接口的作用。
2 StudenDaoListImpl与StudentDaoArrayImpl有何区别?
StudentDaoArrayImpl使用的是固定的数组来存储students对象;而StudenDaoListImpl是用动态存储器ArrayList来实现的。
5.什么是面向接口编程?面向接口编程的好处是什么?
题目3中使用Comparable和Comparator接口,调用Arrays.sort方法实现排序;Comparable定义在类的内部,Comparator定义在类的外部;题目4中,对学生信息的排序,属性等都是通过接口来实现,在调用接口之后就可以接着进行一些具体的行为,这应该就相当于面向接口的编程。
采用面向接口的编程可以省去大量代码。当然在开发大型的java项目中,分层是不可避免的,分层可以使框架的结构清晰,容易理解,并且提高开发的效率。所以本例也从一个 侧面看到了面向接口编程的优点。
6.结对编程:面向对象设计(大作业2-非常重要)
内容:使用Java代码完成上周做的面向对象设计大作业,需要有初步界面。实现的功能尽量简单,少而精,只包含必要的功能,不要追求高大全。
写出:类图(尽量精简,不用太多子类,两个即可)、系统常用功能描述、关键代码与界面
形式: 两人依托码云合作完成。请在这里贴出你们的学号、姓名与任务分工。
注意: 再过几次课要讲Java图形界面编程,到时候要将该系统升级为图形界面。系统的业务逻辑部分应该变化不大,变化大的是输入与输出部分。所以编码的时候,输入(Scanner)与输出(System.out)的代码,请不要将其与某个业务处理函数绑死。
选做加分: 给出两人在码云上同一项目的提交记录截图,额外加分。注:两个人在码云上新建一个项目。
package taobao;
class Product {
public String name;
public double price;
public int num;
public Product(String name, double price, int num) {
super();
this.name = name;
this.price = price;
this.num = num;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Product [price=" + price + ", num=" + num + ", name=" + name + "]";
}
}
package taobao;
class Clothes extends Product{
private String code;
private String color;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Clothes(String name, double price, int num, String code, String color) {
super(name, price, num);
this.code = code;
this.color =color;
}
@Override
public String toString() {
return "裤子名称:" + name +"码数" + code + "颜色" + color+ "价格:" + price
+ "数量" + num ;
}
}
找不到人一起做就自己试着写了上淘宝买裤子的相关代码。
3. 码云上代码提交记录及PTA实验总结
题目集:jmu-Java-04-面向对象2-进阶-多态接口内部类
1. 码云代码提交记录
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
2. PTA实验
继续完成前面未完成的实验面向对象1-基础-封装继承
函数(选做:4-1)、编程(5-1, 5-2)
一定要有实验总结
写不出来完整正确的函数,感觉很多知识点都是离散的,还需要进一步深入学习。