20145233韩昊辰 第四周总结
20145233 《Java程序设计》第4周学习总结
教材学习内容总结
一、继承与多态
1.继承的定义
面对对象中,子类继承父类,避免重复的行为定义,不过并非为了避免重复定义行为就使用继承,滥用而继承会导致程序维护上的问题。
程序代码重复在程序设计上就是不好的信号,多个类间出现重复的代码时,设计上可以考虑的改进方式之一,就是把相同的程序提升为父类。
在java中,继承时使用extends关键字,private成员也会被继承,只不过子类无法直接存取,必须通过父类提供的方法来存取。
在Java中,子类只能继承一个父类,继承有个重要的关系,就是子类和父类之间会有is-a的关系,要开始理解多态,必须先知道操作的对象是哪一类。
这里举一个书上的例子(这个游戏RPG例子我觉得十分成功,通过对这四个代码的充分理解,我终于搞清楚了什么是继承。):
第一个是可以运行的RPG软件。
package ch06;
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(200);
System.out.printf("魔法师: (%s,%d,%d)%n",magician.getName(),magician.getLevel(),magician.getBlood());
}
}
第二个这是被继承的代码。
package ch06;
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;
}
}
这个是对于剑士的定义,通过继承来实现。
package ch06;
public class SwordsMan extends Role {
public void fight(){
System.out.println("挥剑攻击");
}
}
这个是对于魔法师的定义,通过继承来实现。
package ch06;
public class Magician extends Role {
public void fight(){
System.out.println("魔法攻击");
}
public void cure(){
System.out.println("魔法治疗");
}
}
虽然SwordsMan与Magician没有定义getName()、getLevel()、与getBlood()等方法,但从Role继承了这些方法,所以就如同例子中可以直接使用。
继承的好处之一,就是若要将name、level、blood改为其他名称,那就只要修改Role.java就可以了,只要是继承Role的子类都无须修改。
最后的程序运行结果:
2.多态与is-a
在Java中,子类只能继承一个父类,继承除了可避免的行为定义外,还有个重要的关系,那就是子类和父类之间会有is-a的关系。
编译程序就是语法检查器,要知道程序片段为何可以通过编译,为何无法通过编译,就是将自己当做编译程序,检查语法逻辑是否正确,方式是从=号的右边往左边读:右边是不是左边的一种。
什么是多态?以抽象讲法解释,就是使用单一的接口操作多种类型的对象。检查多态语法逻辑是否正确,方式是从右边往左读:右边是不是一种左边呢?如果不是就会编译失败,如果加上扮演语法,编译程序就会让程序代码通过编译,不过后果自负,也就是扮演失败,执行时会抛出ClassCastException。
3.重新定义
在继承父类之后,定义与父类中相同的方法部署,但执行内容不同,这称为重新定义。因为对父类中已定义的方法执行不满意,所以在子类中重新定义执行。
4.final关键字
如果class前使用了final关键字定义,那么表示这个类是最后一个了,不会再有子类,也就不能被继承。定义方法时,也可以是限定该方法为final,这表示最后一次定义方法了,也就是子类不可以重新定义final方法。
二、接口与多态
1.接口定义行为
类要操作接口,必须使用implements
关键字。操作某接口时,对接口中的定义的方法有两种处理方式,一是操作接口中定义的方法,二是再度将该方法标示为abstract
。例如:
public abstract class Fish implements Swimmer {
protected String name;
public Fish(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public abstract void swim();
}
对于“定义行为”可以使用interface
关键字定义,接口中的方法不能操作,直接标示为abstract
,而且一定是public
。
类可以操作两个以上的类,也就是拥有两个以上的行为。类可以同时继承某个类,并操作某些接口,接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。
2.接口语法细节
使用interface
来定义抽象的行为外观,方法要声明为public abstract
,无须且不能有操作。为了方便,也可以省略public abstract
,编译程序会协助补齐。可以使用接口枚举常数,只能定义为public static final
,为了方便,也可以省略public static final
。
接口可以继承别的接口,也可以同时继承两个以上的接口,也是使用extends
关键字。
enum
语法可用于定义枚举常数,enum
实际上定义了类,而enum
中列举的常数实际上是public static final
,无法撰写程序直接实例化枚举类型,因为构造函数权限设定为private
,只有类中才可以实例化。
教材学习中的问题和解决过程
在敲第六章的代码的时候,虽然已经看了继承的含义,我开始以为是在代码中通过某种代码来将这几个不同的代码联系在一起,所以并没有将他们放在同一个文件夹下,所以导致在idea中,其中的很多都是红色表示错误,并且执行的时候总是显示如下的错误:
我最后仔细看书后明白了,在继承的时候,需要将他们放在同一个文件夹下,这样子类就会继承父类,可以不用多次重复的敲相同的代码。终于在搞清楚这些之后,我又不小心将代码中的.敲成了,导致一直是错误执行,我搞不清楚这是为什么,因为笔记本电脑上显示的实在太小,最后,仔细再次看书上的代码,终于理解了那部分代码是swordsMan.getName()
定义的一种函数,中间使用的是.就好比System.out.println
,之间的句号一样。
代码调试中的问题和解决过程
在第七章的代码中,与第六章有些类似地方,需要将所有的.java文件放在同一个文件夹下,通过继承和接口来使它们之间产生联系。(这里面我产生的很多小的粗心错误就不再陈述了。)
并且在这两章的代码中,有很多重复的类名,书上的解决方案是在后面加上阿拉伯数字来进行区分。
@Override是Java5的元数据,自动加上去的一个标志,告诉你说下面这个方法是从父类/接口 继承过来的,需要你重写一次,这样就可以方便你阅读,也不怕会忘记
@Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处:
1>可以当注释用,方便阅读
2>编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错
比如你如果没写@Override而你下面的方法名又写错了,这时你的编译器是可以通过的(它以为这个方法是你的子类中自己增加的方法)
使用该标记是为了增强程序在编译时候的检查,如果该方法并不是一个覆盖父类的方法,在编译时编译器就会报告错误。
本周代码托管截图
之前我都是在网页直接新建的文件来传的代码,这周在使用git软件穿代码,目前还在调试,稍晚的时候我会在这里贴上我的git代码上传图片。这里的是手动网页上传的,不够全。
其他(感悟、思考等,可选)
从开学接触Java到现在已经有四周时间了,我已经从一个在Java方面的小白逐步成长为已经可以看懂代码并理解再加以运用的大学生了。在第三周中我用了大量的时间来理解了封装和对象的含义,上周的学习就给了我一种紧迫的感觉,在这周的学习中,这种感觉更为强烈,因为本周我还有计算机等级考试,还要在平时的时候复习下c语言的知识,导致我的时间分配出现了问题这说明还是我的时间规划不够完善,这是我需要改进的地方。
通过老师所说的方法,每周我都会去看看学的更好的同学的博客,看看他们在学习中会遇到什么什么问题,再对比我在学习本章内容中的问题,常常会发现我所没注意到的,并被我忽略的问题,这样可以强化自己的知识面,并且,在自己遇到问题的时候,他人的解决方法会给我另一种思路,从另一个角度来看待问题,这样会对知识学的更加完善。
老师上周分享了一个积极主动地敲代码的博客,我真的有些感触,在这段时间的学习中,我敲了很多书上的代码,再敲这些代码之前,我会先看书来理解,但是常常并不能很好地理解书中的概念,但是一敲代码我就会慢慢理解,为什么这里要这样,那里要那样,不再是对着课本发呆,一直在概念的苦海中挣扎,因为在对代码有了理解之后,对于概念定义的理解程度也是成几何倍增长的。积极主动地敲代码真的是一种学习语言的好方式,不但锻炼了自己学习语言的能力,还对课本内容有了深入的理解,我要继续坚持做下去。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 4000行 | 24篇 | 350小时 | |
第一周 | 150/150 | 2/2 | 15/15 | |
第二周 | 200/350 | 2/4 | 20/35 | |
第三周 | 350/700 | 2/6 | 30/65 | |
第四周 | 500/1200 | 1/7 | 35/100 |