20145238 《Java程序设计》第4周学习总结

教材学习内容总结第六章 继承与多态

6.1.1

·继承基本上就是避免多个类间重复定义共同行为。

在游戏中会有很多程序代码重复的片段,这样在修改和维护的过程中多有不便,可将代码提升为父类,如下代码就是课本中出现两个代码中重复的片段

public class Role {
private String name;
private int level;
private int blood; 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;
}
}

SwordsMan继承Role

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

同样的Magician继承Role

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

从而可以实现以下程序,虽然没有定义getName()、getLevel()、getBlood()但从Role中继承就可以直接使用。

public class RPG {
public static void main(String[] args) {
demoSwordsMan();
demoMagician(); } static void demoSwordsMan() {
SwordsMan swordsMan = new SwordsMan();
swordsMan.setName("Justin");
swordsMan.setLevel(1);
swordsMan.setBlood(200);
System.out.printf("剑士:(%s,%d,%d)%n",swordsMan.getName(),
swordsMan.getLevel(),swordsMan.getBlood());
} static void demoMagician() {
Magician magician = new Magician();
magician.setName("Monica");
magician.setLevel(1);
magician.setBlood(100);
System.out.printf("剑士:(%s,%d,%d)%n", magician.getName(),
magician.getLevel(), magician.getBlood());
} }

代码运行截图如下:

6.1.2

如果角色的数量较多,只要他们继承的都是同一个类(Role)就可以用多态的方法来代替重载的方式,提高了程序的可维护性。

public class RPG {
public static void main(String[] args) { SwordsMan swordsMan = new SwordsMan();
swordsMan.setName("Justin");
swordsMan.setLevel(1);
swordsMan.setBlood(200); Magician magician = new Magician();
magician.setName("Monica");
magician.setLevel(1);
magician.setBlood(100); showBlood(swordsMan);
showBlood(swordsMan); } static void showBlood(Role role) {
System.out.printf("%s 血量 %d%n", role.getName(), role.getBlood());
}
}

代码运行截图如下:

6.1.3

·重新定义:在继承父类之后,定义与父类中相同的方法部署,但执行内容不同。

首先要在Role中重新定义fight()的实际意义

public class Role {
private String name;
private int level;
private int blood;
public void fight(){}
···

其次在主程序中调用fight

···

       drawFight(swordsMan);
drawFight(magician); } static void drawFight(Role role) {
System.out.print(role.getName());
role.fight();
···

代码运行截图如下:

6.1.4

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

·含有抽象方法的类,一定要在class前标示abstract;子类如果继承抽象类,意识继续标示abstract,另一种就是操作方法。

6.2.1

·protect成员:在Role中name。level.blood被定义为private,无法直接在子类中存取,因此可让子类直接定义为protected类型。被声明protected成员之后,相同包中的类可以直接存取,不同包的类可以在继承后的子类直接存取。

定义如下:

public class Role {
protected String name;
protected int level;
protected int blood;
···

6.2.2

·如果想取得父类中的方法定义,可以在调用方法前,加上super关键字;

·重新定义方法要注意,对于父类中的方法权限,只能扩大不能缩小。若原来成员public,子类中重新定义时不可为private或protected。

6.2.3

·如果累有继承关系,在创建子类实例后,会先进行父类定义的初始流程,再进行子类中定义的初始流程。

·构造函数可以重载,父类中可重载多个构造函数,如果子类构造函数中没有制定执行父类中那个构造函数,会默认调用父类中无参数构造函数。

6.2.4

·final:在指定变量值后,如果不想再改变变量值,可以在声明变量时加上final。

·如果对象数据成员被声明为final,一定要有对该数据成员指定值的动作!

·class前也可以加上final关键字,表明这个类是最后一个类,不会有子类,不能继承。

6.2.5

·子类只能继承一个父类,如果定义类时没有使用extends关键字指定继承任何类,那一定是继承java.lang.Object。

·定义ArrayList类,可以不限长度地收集对象。

以下实例时将收集访客名称转为大写后显示:

public class RPG {
public static void main(String[] args) { SwordsMan swordsMan = new SwordsMan();
swordsMan.setName("Justin");
swordsMan.setLevel(1);
swordsMan.setBlood(200); Magician magician = new Magician();
magician.setName("Monica");
magician.setLevel(1);
magician.setBlood(100); drawFight(swordsMan);
drawFight(magician); } static void drawFight(Role role) {
System.out.print(role.getName());
role.fight();
}
}

代码运行结果截图:

·toString的定义代码为:

public String toString(){

return getClass().getName()+ “@”+Integer.toHexString(hashCode());

}

·equals()的定义代码为:

public boolen equal(Object obj){

return (this==obj);

}

6.2.6

创建对象会占据内存,如果程序执行流程中已无法再使用某个对象,该对象就会被当作垃圾,由GC认定垃圾对象然后垃圾收集释放。

6.2.7

在用户输入、显示结果等环节未定,也可以编写代码片段,运用抽象方法:



public abstract class GuessGame {
public void go(){
int number = (int) (Math.random()*10);
int guess;
do {
print("输入数字'");
guess = nextInt(); } while(guess != number);
println("猜中啦"); } public void println(String text){
print(text + "\n"); }
public abstract void print(String text);
public abstract int nextInt(); }
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 nextlnt() {
return scanner.nextlnt();
}
}
    public static void main(String[] args) {
GuessGame game = new ConsoleGame();
game.go();
}
}

代码运行结果截图:

第七章何谓接口

7.1.1

·区别于继承,接口定义的是行为,可以使用interface关键字定义。

·以下程序代码定义了接口,可以用于定义行为但不定义操作

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

·对接口中定义的方法有两种:

1.操作接口中定义;

2.再度将该方法标示为abstract;

public class Human implements Swimmer {
private String name;
public Human(String name){
this.name = name;
}
public String getName(){
return name; }
@Override
public void swim(){
System.out.printf("人类%s游泳%n",name);
}
}

·Submarine操作了Swimmer,但没有继承Fish。

  public class Submarine implements Swimmer {
private String name; public Submarine(String name) {
this.name = name; } public String getName() {
return name;
} @Override
public void swim() {
System.out.printf("潜水艇%s潜行%n", name);
} }

7.1.2

·多态语法的判断:判断“右边是不是拥有左边的行为”或者“右边对象是不是操作了左边接口”

·只要操作接口对象一直,都可以使用doSwim的方法,提高了系统的可维护性。

程序范例如下:

public class Ocean {
public static void main(String[] args) {
doSwim(new Ugly("尼莫"));
doSwim(new Shark("兰尼"));
doSwim(new Human("贾斯汀"));
doSwim(new Submarine("黄色一号")); } static void doSwim(Swimmer swimmer){
swimmer.swim();
}
}

程序代码截图:

7.1.3

·为了满足用户多需求,例如满足有的东西即会飞又会游泳,可以使用interface定义Flyer接口

public interface Flyer {
public abstract void fly(); }

·定义Seaplane操作Swimmer与Flyer接口;类可以继承,并能操作某些接口,因此它即能飞又能又能游;

public class Seaplane implements Swimmer,Flyer {
private String name;
public Seaplane(String name){
this.name = name;
}
@Override
public void fly(){
System.out.printf("海上飞机 %s 在飞 %n",name); }
@Override
public void swim(){
System.out.printf("海上飞机%s 航行海绵%n",name);
}
}

·定义游泳选手是一种人,同时拥有Swimmer的行为

public class Human {
protected String name;
public Human(String name){
this.name = name; } public String getName(){
return name;
}
}
public class SwimPlayer extends Human implements Swimmer {
public SwimPlayer(String name){
super(name); } @Override
public void swim(){
System.out.printf("游泳选手 %s 游泳 %n",name );
}
}

·接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。

public interface Diver extends Swimmer {
public abstract void dive();
}
public class Boat implements Swimmer {
protected String name;
public Boat(String name){
this.name = name;
} @Override
public void swim(){
System.out.printf("船在水面 %s 航行 %n", name);
} }

·定义潜水艇即在浅海游泳,也可以在深海潜行

public class Submarine extends Boat implements Diver {
public Submarine(String name){
super(name);
} @Override
public void dive(){
System.out.printf("潜水艇 %s 潜行%n",name);
}
}

7.2.1

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

例如:

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

·接口中的方法没有操作时,必须是公开且抽象的。

·枚举常数范例:

public interface Action {
public static final int STOP = 0;
public static final int RIGHT = 1;
public static final int LIFT = 2;
public static final int UP = 3;
public static final int DOWN = 4;
}

·在枚举常数时要使用“=”指定值,否则会编译出错。

·Some与Other定义的execute()

1.表示不同行为,Service有两个不同的操作方法,Some与Other在名称上有所不同。

2.表示相同行为,可以定义一个父接口,当定义execute()方法,而some与other继承该接口,各自定义自己的doSome()与doOther()方法。

7.2.2

·撰写java时有临时某个类或操作某个接口并建立实例,因为只用一次所以不需要为这些类定义名称,此时可以运用匿名类

语法:

new 父类()|接口(){

//类本体操作

};

·操作接口范例;

Some some = new Some() { //操作Some接口并直接产生实例

public void doService(){

System.out.println(“do something”);

}

};

接口应用举例

·建立Client对象封装信息


public class Client {
public final String ip;
public final String name;
public Client(String ip,String name){
this.ip = ip;
this.name = name;
}
}

·若程序其他部分希望在Client加入或移除时可以收到通知,可以将Client加入或移除的信息包装为ClientEvent;

public class ClientEvent {
private Client client;
public ClientEvent(Client client){
this.client = client;
} public String getName(){
return client.name;
} public String getIp(){
return client.ip;
} }

·新增和移除时可以用到

public interface ClientListener {
void clientAdded(ClientEvent event);
void clientRemoved(ClientEvent event);
}
import java.util.ArrayList;
public class ClientQuene {
private ArrayList clients = new ArrayList();
private ArrayList listeners = new ArrayList(); public void addClientListener(ClientListener listener){
listeners.add(listener); }
public void aVoid(Client client){
clients.add(client);
ClientEvent event = new ClientEvent(client);
for(int i=0;i<listeners.size();i++){
ClientListener listener = (ClientListener)listeners.get(i);
listener.clientAdded( event);
}
} public void remove(Client client){
clients.remove(client);
ClientEvent event = new ClientEvent(client);
for (int i=0;i< listeners.size();i++){
ClientListener listener = (ClientListener) listeners.get(i);
listener.clientRemoved(event);
}
}
}
public class MultiChat {
public static void main(String[] args) {
Client c1 = new Client("127.0.0.1","Caterpillar");
Client c2 = new Client("192.168.0.2","Justin"); ClientQuene quene = new ClientQuene();
quene.addClientListener(new ClientListener() {
@Override
public void clientAdded(ClientEvent event) {
System.out.printf("%s 从 %s 联机%n",
event.getName(),event.getIp());
} @Override
public void clientRemoved(ClientEvent event) {
System.out.printf("%s 从 %s 脱机%n",
event.getName(),event.getIp());
}
}); quene.add(c1);
quene.add(c2);
quene.remove(c1);
quene.remove(c2);
}
}

代码运行结果截图:

7.2.3

使用enum枚举常数,enum定义了特殊的类,继承自java.lang.Enum,直接撰写程序继承Enum类会被编译程序拒绝,编译过后,会产生Action.class

public enum Action{
STOP,RIGHT,LEFT,UP,DOWN
}

教材学习中的问题和解决过程

第六章以及第七章有很多代码多是嵌套,如果有一部分无法编译成功那最后的程序就不能运行。但是这样编程可维护性强,思路清晰,以后要多加练习,希望自己也能编译出这种完整性的可维护性强的代码。

代码调试中的问题和解决过程

问题一:

出错原因在于大写的I与小写的L十分相近,printInt错写成printlnt了···

问题二:

在运行最后一个匿名内部类的时候,编译MultiChat一直找不到add类型,才发现前面的queue错写成quene,但更改了以后还是出错,发现原来前面的ClientQueue文件名就错写成ClientQuene了。。。

其他(感悟、思考等,可选)

本周代码量有增多,代码片段组合成代码整体,多代码片段嵌套、调用,更深入的理解了JRK在运行时的过程。更系统的了解了一些大游戏在制作时的思想,逻辑。但在真正理解和运用绝不是这一周的时间,希望以后能够多思考,多多体会编程大师的思维模式。

开源中国代码托管截屏





学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 2/4 18/38
第三周 500/1000 3/7 22/60
第四周 300/1300 2/9 30/90

参考资料

20145238-荆玉茗 《Java程序设计》第4周学习总结的更多相关文章

  1. #20145238荆玉茗《网络对抗》-逆向及Bof进阶实践

    20145238荆玉茗<网络对抗>-逆向及Bof进阶实践 实践目的:注入shellcode 准备一段shellcode代码 Shellcode实际是一段代码(也可以是填充数据),是用来发送 ...

  2. 20145238-荆玉茗 《Java程序设计》第一周学习总结

    20145238 <Java程序设计>第一周学习总结 教材学习内容总结 Java三大平台:由于java领域的应用越来越广,根据不同级别的应用开发区分了不同的应用版本,后正式更名为Java ...

  3. 20145213《Java程序设计》第九周学习总结

    20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...

  4. 20145213《Java程序设计》第二周学习总结

    20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...

  5. 20145213《Java程序设计》第一周学习总结

    20145213<Java程序设计>第一周学习总结 教材学习内容总结 期待了一个寒假,终于见识到了神秘的娄老师和他的Java课.虽说算不上金风玉露一相逢,没有胜却人间无数也是情理之中,但娄 ...

  6. 21045308刘昊阳 《Java程序设计》第九周学习总结

    21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...

  7. 20145330孙文馨 《Java程序设计》第一周学习总结

    20145330孙文馨 <Java程序设计>第一周学习总结 教材学习内容总结 刚开始拿到这么厚一本书说没有压力是不可能的,开始从头看觉得很陌生进入不了状态,就稍微会有一点焦虑的感觉.于是就 ...

  8. 20145337 《Java程序设计》第九周学习总结

    20145337 <Java程序设计>第九周学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC可以 ...

  9. 20145337 《Java程序设计》第二周学习总结

    20145337 <Java程序设计>第二周学习总结 教材学习内容总结 Java可分基本类型与类类型: 基本类型分整数(short.int.long).字节(byte).浮点数(float ...

  10. 20145218《Java程序设计》第一周学习总结

    20145218 <Java程序设计>第一周学习总结 教材学习内容总结 今天下午看了Java学习的视频,感觉很是新奇,之前觉得Java学起来是艰难枯燥的,但通过第一章的学习觉得如果自己可以 ...

随机推荐

  1. R语言安装程序包

    自动安装(在线安装) 在R的控制台,输入 install.packages("gridExtra") # 安装 gridExtra install.packages("s ...

  2. 26-----BBS论坛

    BBS论坛(二十六) 26.发布帖子前台代码逻辑完成 (1)front/hooks.py from .views import bp from flask import session,g from ...

  3. idea各种快捷键

    工作的的时候,如果不知道idea一些方便的快捷键会大大影响工作效率,今天打算看看这些小技巧: https://blog.csdn.net/linsongbin1/article/details/802 ...

  4. Index Skip Scan in Oracle in 11g

    http://viralpatel.net/blogs/oracle-index-skip-scan/ in 11g the same sql use index skip scan but in 1 ...

  5. 用LaTeX画树形结构

    用LaTeX画树形结构,比如:文件目录树形图,程序中函数调用关系图等. 找到的一个不错的资源: http://www.texample.net/tikz/examples/feature/trees/ ...

  6. MS-DOS

    MS-DOS doskey /history /reinstall /buffersize /macros doskey di=dir /w/p defrag 磁盘碎片整理 xcopy deltree ...

  7. Datastructure

    时间复杂度的计算 计算最坏情况下执行语句的次数(含有n) 去掉常数项, 只保留最高项, 去掉系数 最后的结果一般是1, logn, n, nlogn, n^2, 2^n, n!, n^n 时间复杂度所 ...

  8. POJ 1456——Supermarket——————【贪心+并查集优化】

    Supermarket Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit  ...

  9. c#实体转化

    经常会遇到把一个实体转化成另一个实体这样的情况,实体的属性一个一个手写去转化不反对,但不是啥好的方法:可以使用反射写一个通用的实体转化类,针对任何实体转化,不用再去自己手写. public stati ...

  10. deployment删除后,副本集未删除,解决之道

    在删除的body上加上,body.setPropagationPolicy("Foreground");就可以删除deployment的同时连同副本集一同删除.