教材学习内容总结
一、继承与多态
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
,只有类中才可以实例化。
其他(感悟、思考等,可选)
本周学习主要收获是理解了继承、封装、多态之间的关系,垃圾回收机制,还了解了两个类的基本使用,但其中抽象类和接口的区别还没有准确搞懂,下去还需要再看一些。为了下周考试好得仔细了解课后习题。考个好成绩。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 3500行 | 30篇 | 300小时 | |
第一周 | 100/100 | 2/2 | 20/20 | 基础知识 |
第二周 | 300/300 | 4/4 | 40/38 | 深入了解 |
第三周 | 300/800 | 4/6 | 40/60 | 忘了更新 |
第四周 | 700/1200 | 6/8 | 60/90 |