您的位置:首页 > 编程语言 > Java开发

20155313 2016-2017-2 《Java程序设计》第四周学习总结

2017-03-19 23:42 417 查看

20155313 2016-2017-2 《Java程序设计》第四周学习总结

教材学习内容总结

6 继承与多态

面对对象中,子类继承父类,避免重复的行为定义,不过并非为了避免重复定义行为就使用集成,滥用集成而导致程序维护上的问题时有所闻。继承基本上就是避免多个类间重复定义共同行为。书本中举了一个RPG游戏中设定一个角色剑士的例子。

public class SwordsMan {
private String name;
private int level;
private int blood;

public void fight() {
System.out.println("挥剑攻击");
}

public int getBlood() {
return blood;
}

public void setBlood(int Blood) {
this.blood = blood;
}

public int getLevel() {
return level;
}

public void setLevel(int level) {
this.level = level;
}

public String getName() {
return name;
}

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

}

从实际例子出发我们发现,只要在游戏中出现一个角色,我们就要给他设定一个具有角色名称、等级与血量的类,而不同的职业,类似魔法师、术士之类他们也需要设定名称、等级与血量,也就是说在编写程序的时候会出现重复。然而重复在程序涉及上就是不好的信号。如果游戏在运营的过程中需要将name、level、blood改成其他名称,或者给所有角色增加一个怒气值,那就要对所有的类进行修改,这样在维护的过程中需要花更多的时间同时也容易出现纰漏。

因此在这里就需要将相同的代码程序提升为父类:



这个类在定义上没什么特别的信誉发,只不过是将SwordsMan与Magician中重复的程序复制过来。接着SwordsMan可以如下继承Role:



这里出现了新的关键词extends,这表示SwordsMan会扩充Role的行为,也就是继承Role的行为,再扩充Role原本没有的fight()的行为。类似一种公共调用的函数,所有输入extends Role定义的类可以使用Role里面所有的设定,并且在自己的类中定义属于自己的属性。类似地Magician也可以如下定义继承Role类:



Magician继承Role的行为,再扩充了Role原本没有的fight()与cure()行为。例如你还可以设定一个角色小偷:

package cc.openhome;

public class Thief extends Role {
public void steal() {
System.out.println("偷东西");
}

public void run() {
System.out.println("逃跑");
}
}

这个小偷能偷东西和逃跑。

最后使用一个RPG的程序使被继承的属性显示出来:



继承的捞出之一,就是若你要将name、level、blood改成其他名称,那就只要修改Role.java就可以了,只要使继承Role的子类都无须修改。

在Java中,子类只能继承一个父类,继承除了可避免类间重复的行为定义外,还有个重要的关系,那就是子类与父类间会有is-a的关系,中文成为“是一种”的关系。以前面返利来说,SwordsMan继承了Role,所以SwordsMan是一种Role(SwordsMan is a Role),Magician继承了Role,所以Magician是一种Role。

现在需要将游戏中所有角色的血量显示出来,这时候就需要使用单一接口操作多种类型的对象,这种方法也叫多态。下面的范例中,在showBlood()方法中,既可以通过Role类型操作SwordsMan对象,也可以通过Role类型操作Magician对象。

在上面我们显示了角色的血量,现在我们需要播放角色攻击动画。书本中将fight()方法提升至Role类中定义:

pacakge cc.openhome;

public class Role {
···
public void fight() {
// 子类要重新定义fight()的实际行为
}
}

在Role类中定义了fight()方法,由于实际上角色如何攻击,只有子类才知道,所以这里的fight()方法内容是空的,没有任何程序代码执行。SwordsMan继承Role之后,再对fight()的行为进行定义:

package cc.openhome;

public class SwordsMan extends Role {
@Override
public void fight() {
System.out.println("挥剑攻击");
}
}

同样地,Magician继承Role之后,再对fight()的行为进行定义:

package cc.openhome;

public class Magician extends Role {
@Override
public void fight() {
System.out.println("魔法攻击");
}

public void cure() {
System.out.println("魔法治疗");
}
}

如果某方法区块中没有任何程序代码操作,可以使用abstract表示该方法为抽象方法,该方法不用撰写{}区块,直接“;”结束即可。例如:

package cc.openhome;

public abstract class Role {
private String name;
private int level;
private int blood;

public abstract void fight();
}

类中操作接口,使用implements关键字。操作某接口时,对接口中定义的方法有两种处理方式,一是操作接口中定义的方法:

public class name3 extends name1 impelments name1{
...
}

二是再度将该方法标示为abstract:

public abstract class name3 implements name4{
...
}

在Java中,可使用interface来定义抽象的行为与外观,如接口中的方法可声明为public abstract :

public interface Swimmer{
public abstract void swim();
}

在interface中可以定义常数,java中经常见到在接口中定义这类常数,称为枚举常数。

代码托管

代码提交过程截图:

运行 git log --pretty=format:"%h - %an, %cd : %s" 并截图



代码量截图:

运行 find src -name "*.java" | xargs cat | grep -v ^$ | wc -l 并截图





不知道为何在总文件夹中无法显示代码数量,因此进入子文件夹分开显示,要到存在src的文件夹的目录才能查找,有些更小的工程没有进行截图,但总代码量应该在500行左右。

错题总结

填空:Linux Bash中,(grep )命令可以进行全文搜索。

CH04 填空:p86 命令行下编译Guess.java的命令是(javac -d . Guess.java)

CH04 判断: Java中,=与==并没有在基本类型和类类型的不同。(OK)

CH04 填空:两个Integer对象比较大小,可以使用(compareTo())方法

CH04 填空: p109 Average.java 求1,2,3,4,5的平均值的命令是(java cc.openhome.Average 1 2 3 4 5

CH05 判断:Java中类总会有默认构造方法。(X)

CH05 填空:调用p145 sum函数计算1+2+3+4+5的代码是(MathTool.sum(1,2,3,4,5))

CH05 填空:Java中方法参数只用(传值)调用。

CH05 填空:被声明为(static)的成员,不属于某个对象,而是属于类。

CH05 判断:Java中方法内可以定义类。(OK)

学习进度条

代码行数(新增积)博客量(新增积)学习时间(新增积)重要成长
目标5000行30篇400小时
第四周500/5001/220/20

参考资料

Java学习笔记(第8版)

《Java学习笔记(第8版)》学习指导
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: