20155232 2016-2017-3 《Java程序设计》第4周学习总结

20155232 2016-2017-3 《Java程序设计》第4周学习总结

教材学习内容总结

  • 第六章 继承与多态

所谓继承就是避免多个类间重复定义共同行为。

1.重复在程序设计上就是不好的信号,如果要改进就可以把相同的程序代码提升为父类。

2.使用新的关键字extends表示继承并且扩充原先没有的行为。继承的好处就是若要修改,无需在继承的子类中去修改。
注意private成员会被继承,不过无法直接存取,必须通过父类提供的方法存取。

3.子类只可继承一个父类,子类与父类之间会有is-a的关系。
例如:


Role role1 = new SwordsMan()
SwordsMan swordsman = role1; //x
SwordsMan swordsman = (SwordsMan)role1; //ok

第二条语句会出现编译错误。第三条语句在执行时会抛出classcastexception。

4.多态

使用单一接口操作多种类型的对象

5.重新定义

定义与父类中相同的方法部署,但执行的内容不同(override)。
在JDK5之后,内建标注

@Override

如果在子类的某个方法前标注,表示要求编译程序检查该方法是不是重新定义了父类的某个方法。

6.抽象方法,抽象类

如果某方法区块中真的没有任何程序的代码操作,可以使用

abstract

标示该方法为抽象方法。

注意抽象类不能使用new生成对象

7.protected成员

相同包中的类可以直接存取,不同包中的类可以在继承后的子类中直接存取。

public / package / protected / private
image
提示依照权限由小至大来区分就是private,无关键字,protected,与public。

8.重新定义的细节

如果想取得父类中的方法定义,可以在调用方法前加上super关键字。
可以使用super调用父类方法,不能定义为private。

注意重新定义方法时,对于父类中的方法权限,只能扩大不能缩小。

9.再看构造函数

构造函数可以重载,父类中可重载多个函数。如果想执行父类中某构造函数,可以使用super()指定。

注意this()与super()只能择一调用,而且要在构造函数第一行执行。

10.再看final关键字

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

定义方法时,也可以使用,表示子类不可以重新定义final方法。

11.java.lang.Object

如果继承时没有使用extends关键字指定任何类,那么继承的是java.lang.Object。

12.instanceof运算符可以用来判定对象是否由某个类创建,左操作数是对象,右操作数是类。

13.垃圾收集

无法通过变量引用的对象就是GC认定的垃圾对象。

垃圾回收前会调用finalize()方法,但由于调用时机无法确定,建议不要使用finalize()方法。

  • 第七章

1.使用接口(interface)定义行为
类要操作接口,必须使用implemnts关键字。
操作接口时,对接口中定义的方法有两种处理方式,一是操作接口定义的方法,二是再度将方法标示为abstract。

继承与操作接口的区别:继承时有“是一种”的关系,操作接口则表示“拥有行为”。

2.如果增加新的需求,原有的程序无需修改,只需要针对新需求撰写程序,就是有弹性,具有可维护性的程序

3.类可以操作的两个以上的类,也就是拥有两种以上的行为。

4.接口默认

在接口中枚举常数,一定要使用=指定值,否则编译错误。
注意要在类中定义枚举常数也是可以的,不过要明确写出public static final。

5.匿名内部类

在撰写java程序的时候,会面临临时继承某个类或操作某个接口并建立实例的需求,由于只使用一次,不需要定义名称。可以使用匿名类。
在JDK8之前要在匿名内部类中存取局部变量,必须是final,否则编译错误。

注意局部变量的生命周期比对象短。java的做法是传值。

6.使用enum枚举常数

enum实际上定义了类,而enum中列举的常数,实际上是public static final ,且为枚举类型实例,无法撰写程序直接实例化枚举类型,因为构造函数权限设定设定为private。

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

  • 在第六章刚开始时,书上提到不能滥用继承,那么滥用继承会导致什么样的后果?
    首先我上网搜索了一下怎么样才算滥用继承。

两个判定是否是滥用继承的重要依据:

1.如果一个类从核心用意和设计初衷上天然是另一个类的子类,这种继承是天经地义的,并不存在破坏封装的说法。

2.在允许多继承的语言里,如果一个类需要使用到来自另一个父类(特质)的“全体”字段和方法,或都反过来说,把某个父类(特质)的全体成员赋予另一个类时,如果从这两个类的设计用意和代表的概念上没有任何的违和感,那么,这时候使用继承也是正当的,没有破坏封装的嫌疑。

那么危害有哪些呢?
image

  • 2.书上提到在重新定义方法中,要注意,对于父类中的权限,只能扩大不能缩小,为什么?
  • 举个例子,在父类中是public的方法,如果子类中将其降低访问权限为private,那么子类中重写以后的方法对于外部对象就不可访问了,这个就破坏了继承的含义。

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

  • 在输入p161代码后,如下:
    image但是运行不出书上的结果:
剑士:(Justin, 1, 200)
魔法师:(Monica, 1, 100)

而是出现如下错误:

image

  • 解决方案:
    将代码加入,将两段代码合并!
    image
    在编译后又会报错,因为出现了两个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;
    }
    public void fight(){}
}
class SwordsMan extends Role{
    public void fight(){
        System.out.println("挥剑攻击");
    }

}
class Magician extends Role{
    //private  String fight;

    public void fight(){
        System.out.println("魔法攻击");
    }
    public void cure(){
        System.out.println("魔法治疗");
    }
}
public class RPG3 {
    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.println(role.getName());
        role.fight();
    }
}

运行结果:
image

  • 因为课本上给出的基本上都是代码段,刚开始不知道怎么同时运行两个程序(子类和父类),也不不知道如何编译,在查阅相关资料,问了同学之后,要将两个程序放在一个package中,然后先编译父类,在编译子类,最后运行即可。下面是过程的截图。

1.在同一个包(Array)中建立两个文件
image
2.并在两个代码段的开头都加入了

Package Array;

表示在同一个包中。
image
image
3.开始编译Guest代码段,出现错误
image
原因:未先编译父类的方法。

4.先编译父类的方法ArrayList.java在编译Guest.java:
image
5.最后在运行时又出现了错误如上图

6.修改如下:需要将写上 package的名称.代码段名称
(并且运行)
image
问题解决~!

代码托管

  • 代码提交过程截图:
    image

  • 代码量截图:
    image

  • 脚本截图
    image
    image
    image

上周考试错题总结

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

原因:linux的命令掌握的还不够熟练,很多命令因为不常用就容易忘记。

  • 4.填空:System.out.println(“”+52+25);的结果是(5225)
  • 5.填空:System.out.println(52+25+””);的结果是(77)

原因:这个我现在也不太懂,希望老师能讲解一下疑惑。

  • 19.CH04 填空:“30”转化为byte类型的30的语句是(Byte.parseByte(“30”);)。

原因:看书的时候这里没有仔细阅读,看书上给出的例子,不够熟练应用于实例中,还不够熟练掌握,做到举一反三。

感悟心得

  • 对教材感悟

在第六章中了解了继承的目的,继承就是避免多个类间重复定义共同行为,并且在修改过程中也避免了很多麻烦。还了解了多态与继承的关系,并且通过阅读教材大概知道了如何重新定义方法,重新定义时且若要取得父类中的方法定义,对于父类的方法权限,只能扩大但不能缩小。还知道了java.lang.Object是所有类追溯到最上层的父类。垃圾收集就是无法通过变量参考的对象,就是GC认定的垃圾对象。在第七章中,举例子介绍了接口定义行为,了解了接口的多态操作。两种方法的枚举常数。

  • 对考试感悟

这次考试比前两次的成绩提高了2分,很开心。因为这次看书看得比较仔细,所以翻书找的时候没有浪费太多时间,所以时间上相对充裕了,题也写完了。还需要在代码上多下功夫,做到每天都要敲代码。

  • 课本中代码的部分展示与思考
    p159页代码如下:
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可以如下继承:
image
出现了新的关键字extends,表示会扩充Role的行为,也就是继承,扩充了原本没有的fight行为。
Magician也可以进行继承:
image

p178页 定义的ArrayList类,可以不限长度收集对象,每次收集的对象会放在next索引处,使用size()方法得知已收集的对象个数。
image

注意如果使用无参数构造函数,则默认容量为16。

p186
image定义的抽象类,这个类是不完整的,所以显示输入输出就不能操作。

p187继承抽象类GuessGame:
将3个代码段放在同一个包下(Iheritance)
image
image

p186-187猜数字程序
也是将代码片段放在同一个package中,然后分别编译,最后运行。
image

image

p197-201
Oceanworld程序,了解了接口和继承的区别,以及优势。并了解了

interface
implements

关键字的定义及用法。继承会有“是一种”关系,操作接口则表示“拥有行为”所以会优先考虑接口而不是继承。

课本编海洋的程序:
image
image
image

在输入p202页Airplane代码段时
课本上代码出现错误:

package OceanWorld1;

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);

}

}

按照课本输入的Airplane.java但是代码为:

public class Seaplane ....

所以重新建立文件名,并进行编译,如下修改编译正确:
image

p209页程序:
image

image

image

p216
image
image
使用了匿名内部类。

与209页程序作对比,使用enum定义,不像之前play()方法可以传入任何int值,所以不需要使用default进行检查。
image

image

image

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 15/15 1/1 23/26
第二周 208/240 2/2 35/38
第三周 376/584 3/3 32/38
第四周 823/1407 4/4 28/30

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

参考资料

posted @ 2017-03-19 17:45  短爪爪爪  阅读(131)  评论(0编辑  收藏  举报