教材学习内容总结

学习目标

  • 理解封装、继承、多态的关系
  • 理解抽象类与接口的区别
  • 掌握S.O.L.I.D原则
  • 了解模式和设计模式
  • 能正确覆盖方法
  • 了解垃圾回收机制
  • 掌握Object类
  • 掌握enum

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

继承

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

    我理解的就是:在编写程序的过程中可能会出现部分代码重复的现象,把重复的部分单独定义为一类(父类),在其他代码中(子类)直接继承,这样子类可直接使用父类的方法,子类的对象也可以使用父类的方法,同时避免了大段代码的重复出现的问题。
关键字 extend
public class SwordsMan extends Role{
//SwordsMan会继承Role的行为,并对Role的行为进行扩充,仅在SwardsMan中使用新定义的行为
public void fight(){
System.out.println("挥剑攻击");
}
}

上述代码表示,类SwordsMan继承了类Role,类SwordsMan扩充了类Role的行为,也就是类Role中有定义的程序代码,类SwordsMan因为继承而都拥有了。

需要注意的是:

在Java中,子类只能继承一个父类,也就是说只能有一个爸爸。

  • IS-A:因为子类继承了父类,所以子类是一种父类
  • 运用“IS-A”关系判断语法的正确性:方式:判断等号右边是否为等号左边的子类,以下两例均无法通过编译:
 SwordsMan swordsMan = new Role();
Magician magician = new Rile();
//Role 为 SwordsMan 和 Magician 的父类,右边类不是左边类的子类,所以编译不通过
Role role1 = new SwordsMan();
//SwordsMan 是一种 Role ,这条语句可以通过编译
SwordsMan swordsMan = role1;
//role1 为 Role 声明的名称,编译程序认为 Role 不一定是一种 SwordsMan,编译失败
  • 住嘴语法:在等号右边加括号声明即可通过编译,但执行不一定能通过,例如:
Role role2 = new Magician();
SwordsMan swordsMan = (SwordsMan) role2;
//在 role1 前加括号声明关系,编译能通过,但执行时不一定能通过,要根据参考的对象实际类型判断,本例让魔法师扮演剑士,执行时会出现错误
  • 多态:使用单一接口操作多种类型的对象。我的理解是:就子类和父类来讲,一个父类可以有很多子类,在程序中就可以通过一个父类操作很多它的子类,这样比较方便,同时使程序具有更高的可维护性
  • 封装是继承的基础,继承是多态的基础
  • 重新定义:在继承父类之后,定义与父类中相同的方法部署,但各子类中执行的内容不同。父类定义了方法,但是没有内容,子类可以重新定义父类中的实际行为。因父类定义了方

    法,所以可以运用多态,传入子类中定义的方法,实现一些功能操作。
  • 注意:在重新定义父类中某个方法时,子类必须撰写与父类方法中相同的签署,就是定义的方法的名字要完全一样
  • 注意:重新定义方法时,对于父类中的方法权限,只能扩大但不能缩小,若原来成员public子类中重新定义时不可为 privateprotected
  • 标注:@Override 如果在子类中某个方法前标注@Override,表示要求编译程序检查,该方法是不是真的重新定义了父类中的某个方法,如果不是的话,就会引发编译错误

抽象方法、抽象类:

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

public abstract void fight();
  • 抽象类:Java中规定内含抽象方法的类,一定要在 class 前标示 abstract ,表示一个定义不完整的抽象类
  • 类中若有方法没有操作,且标示为 abstract,表示这个类定义不完整,定义不完整的类不能用来生成实例,就好像设计图不完整就不能拿来生产成品
  • 如果尝试用抽象类创建实例,会引发编译错误
  • 子类如果想继承抽象类,对于抽象方法有两种做法:(如果两种做法都没有实施,就会引发编译错误)

    1. 继续标示该方法为 abstract(该子类因此也是个抽象类,必须在class前标示 abstract)

    2. 操作抽象方法
继承语法细节
protected:被声明为 protected 的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类中直接存取,存取时可用“this”,具体的权限关键字与范围如下:
关键字 类内部 相同包类 不同包类
public 可存取 可存取 可存取
protected 可存取 可存取 子类可存取
可存取 可存取 不可存取
private 可存取 不可存取 不可存取
super

在Java中,如果想取得父类中的方法定义,可以在调用方法前加上“super”关键字,例如:

 public String toString(){
return "剑士" + super.toString();
  • 注意:可以使用 super 关键字调用的父类方法,不能定义为 private(因为这就限定只能在类内使用)
  • 构造函数
  • 创建子类实例后,会先执行父类构造函数定义的流程,再执行子类构造函数定义的流程
  • 构造函数可重载
  • 如果子类构造函数中没有指定执行父类中哪个构造函数,默认会调用父类中无参数的构造函数,例如:
 class Some {
Some() {
System.out.println("调用Some()");
}
}
class Other extends Some{
Other(){
//子类构造函数中没有指定执行父类中哪个构造函数,则调用父类中无参数的构造函数
System.out.println("调用Other()");
}
}
//先执行Some中的流程,再执行Other中的流程,最后的结果是:先显示“调用Some()”,再显示“调用Other()”
  • 若父类中自行定义了构造函数,在父类中就不会加入任何构造函数了,此时若子类没有指定调用父类哪个函数,就会编译失败
  • final
  • 类加 final:如果class前加了final,则表示这个类是最后一个了,不会再有子类 → 这个类不能被继承(例:String 在定义时就已经限定为 final 了)
  • 方法加 final:定义方法时也可以限定该方法为 final,表示最后一次定义方法 → 子类不可以重新定义 final 方法
  • java.lang.Object
  • java.lang.Object 是所有类的顶层父类,这代表了 Object 上定义的方法,所有对象都继承下来了,只要不是被定义成 final 方法,都可以重新定义
  • java中所有对象,一定“是一种”Object
  • 如果定义类时没有使用 extends 关键字指定继承任何类,那一定是继承了 java.lang.Object,以下两段代码是等价的
public class Some{}
public class Some extends Object{}
  • toString()
  • toString()的作用:传入对象
  • toString()是 Object 上定义的方法
  • toString()调用方法:以下两段代码是等价的,调用的时候选取第二种方式调用即可
Syetem.out.println(swordsMan.toString());
System.out.println(swordsMan);
equals()
  • equlas()是 Object 类有定义的方法,程序代码如下:
public boolean equals(Object obj){
return(this == obj);
}
  • 若果没有重新定义 equals(),使用 equals() 方法时,作用等同于 ==
  • 要比较实质相等性,必须自行重新定义equals()
instanceof
  • 用途:判断对象是否由某个类创建,左操作数是对象,右操作数是类,也就是判断 instanceof 左边的对象是否由右边的类创建
  • 并非只有左操作数对象为右操作数类直接的实例才能返回 true,只要左操作数类型是右操作数类型的子类型,instanceof 也返回 true
  • 垃圾收集
  • 垃圾:如果程序执行流程中已无法再使用某个对象,该对象就只是徒豪内存的垃圾
  • 垃圾收集机制:GC
  • 执行流程中,无法通过变量参考的对象,就是GC认定的垃圾对象
  • GC在进行回收对象前,会调用对象的 finalize() 方法(这是 Object 上定义的方法),如果在对象被回收前有些事情想做,可以重新定义 finalize() 方法

教材第七章内容总结——接口与多态

何谓接口

  • 接口:书上没有明确地给出接口的定义,我理解的接口就是一段程序中可能有很多类会有共同的行为,但这些类本身并不具有任何关系,如果使用继承的话程序架构会不合理,所以使用统一的接口表示这些类具有共同的行为
interface

可定义行为,例如:

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

类要操作接口,必须使用 implements 关键字,例如:

public abstract class Fish implements Swimmer{
}
  • 操作某接口时,对接口中定义的方法有两种处理方式:

    1. 操作接口中定义的方法

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

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

  • 多态语法合法性判断:判断等号右边是不是拥有等号左边的行为,即等号右边的对象是不是操作了等号左边的接口,以下这个例子就可以通过编译:

Swimer swimmer = new Shark();//因为 Fish 操作了 Swimmer 接口,即 Fish 拥有了 Swimmer 行为。Shark 继承 Fish ,所以Shark 拥有 Swimmer 行为

  • 扮演语法:会操作 Swimmer 接口的不一定继承Fish,加上扮演语法即可通过编译,例如:
Swimmer swimmer = new Shark();
Fish fish = (Fish)swimmer;

以下的例子将会抛出 ClassCastException 错误:

Swimmer swimmer = new Human();//将 swimmer 参考到 Human实例
Shark shark = (Shark)swimmer;//让 swimmer 扮演鲨鱼

已经将 swimmer 参考到 Human 实例了,再让他扮演鲨鱼就会出现错误

  • 解决需求变更问题:我们可以定义一些拥有不同行为的接口,定义一些类作为父类,当增加新的需求的时候,可以操作接口,代表拥有接口的行为,也可以继承父类,代表这个新的类“是一种”父类,原有的程序无需修改,只针对新的需求撰写程序即可
  • 在java中,类可以操作两个以上的接口,也就是拥有两种以上的行为
  • 在java中,接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为,例如:
public interface Diver extends Swimmer{  //接口 Diver 继承了接口 Swimmer
public abstract void dive();
}
接口语法细节
  • 在java中,可使用 interface 定义抽象的 行为与外观,如接口中的方法可声明为 public abstract ,例如:
public interface Swimmer{
public abstract void swim();
}
  • 接口中的方法没有操作的时候,一定要是公开抽象,可以省略 public abstract ,例如:
public interface Swimmer{
void swim(); //此处默认是 public abstract
}
  • 由于默认一定是 public ,在类操作接口的时候也要撰写 public
interface Action{
void execute();
} class Some implements Action{
void execute(){
//Some 类在操作 execute() 方法时,没有撰写 public ,因此默认为是包权限,这等于是将 Action 中的 public 方法缩小为包权限,所以编译失败
//将 Some 类的 execut() 设为public 才可通过编译
System.out.println("做一些服务");
}
}

在 interface 中,只能定义 public static final 的枚举常数 ,例如:

public interface Action{
public static final int STOP = 0;
}

如下撰写程序时,编译程序会自动展开为 public static final

public interface Action{
int STOP = 0;
}
  • 在接口中枚举常数,一定要使用 = 指定值,否则编译错误
  • 接口可以继承别的接口,可以同时继承两个以上的接口,使用 extends 关键字 ,代表了继承父接口的行为,例:
interface Action{
void executes();
}
// 定义 Acton 为父接口
interface Some extends Action{
void doSome();
}
interface Other extends Action{
void doOther();
}
// Some 和 Other 接口继承 Action 接口
public class Service implements Some,Other{
// Service 继承 Some 和 Other 接口
@Override
public void execute(){
System.out.println("execute()");
}
// Service 重新定义 execute() 方法
@Override
public void doSome{
System.out.println("doSome()");
}
@Override
public void doOther{
System.out.println("doOther()");
}
// Service 重新定义 doSome 和 doOther 方法
}
匿名内部类
  • 某些子类或接口操作类只使用一次,不需要为这些类定义名称,这时可使用匿名内部类
  • 语法:
new 父类()|接口(){
//类本体操作
};
  • JDK8 之前,若要在匿名内部类中存取局部变量,则该局部变量必须是 final ,否则会发生编译错误

final int[] numbers = {10,20};

enum

enum 可定义枚举常数,但实际上 enum 定义了特殊的类,继承自 java。lang.Enum ,编译过后会产生 Action.class 文件,可用这个 Action 声明类型,例如:

public class Game {
public static void main(String[] args){
play(Action.RIGHT);
play(Action.UP);
//只能传入 Action 实例
} public static void play(Action action){
// action 参数声明为 Action 类型,所以只接受 Action 的实例,这样就不需要必须使用 default 检查,编译程序在编译时期会进行类型检查
switch(action){
case STOP:
out.println("播放停止动画");
break;
case RIGHT:
out.println("播放向右动画");
break;
case LEFT:
out.println("播放向左动画");
break;
case UP:
out.println("播放向上动画");
break;
case DOWN:
out.println("播放向下动画");
break;
}
}
}
  • enum中列举的常熟,实际上是 public static final ,且为枚举类型实例,因为构造函数权限设定为 private ,只有类中才可以实例化

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

问题一

Java中的继承和C语言中调用函数有何区别?

Answer:

Java语言与C语言本身就是两种不同思维的语言。C语言是面向过程的语言,就是我们要干一件事情,那么一步一步逐次来做,直到完成,其中可能就要调用一些函数,被调用的函数也是过程执>行的。但是Java程序的开发思路是面向对象的,它是有一个类,这个类有属性,有方法。我们要干一件事的时候,就通过该类所定义的或者说是具体化的对象(Object)来调用自己的方法来完成,这里所说的方法,也可以理解为是一个函数(类似于C语言中的),但是只不过这个方法现在是属于这个类的,属于这个对象的,是有“主人”的,只有通过它的“主人”才能调用它。而面向对象的Java有一个特点就是继承,当某一个类A继承了类B那么类A就可以使用类B的方法了,因为A继承了B,同样A的对象也可以使用B的方法了。

问题二

继承类和接口有何区别?

Answer:

  1. 不同的修饰符修饰(interface),(extends)
  2. 在面向对象编程中可以有多继承!但是只支持接口的多继承,不支持“继承”的多继承。而继承在java中具有单根性,子类只能继承一个父类
  3. 在接口中只能定义全局常量,和抽象方法,而在继承中可以定义属性方法,变量,常量等。
  4. 某个接口被类实现时,在类中一定要实现接口中的抽象方法,而继承想调用那个方法就调用那个方法,毫无压力。

    举个有趣的例子:

    当使用继承的时候,主要是为了不必重新开发,并且在不必了解实现细节的情况下拥有了父类我所需要的特征。

    但是很多时候,一个子类并不需要父类的所有特征,它可能只是需要其中的某些特征,但是由于通过继承,父类所有的特征都有了,需要的和不需要的特征同时具备了。而那些子类实际上不需要用到的,有时候甚至是极力避免使用的特征也可以随便使用,这就是继承的副作用。特别是允许多重继承的Java语言中,很容易引起不容易发现的错误。所以在java的语言中,会创造出各种规定来限制子类使用父类中的某些方法。

    如果狗的主人只是希望狗能爬比较低的树,但是不希望它继承尾巴可以倒挂在树上,像猴子那样可以飞檐走壁,以免主人管不住它。那么狗的主人肯定不会要一只猴子继承的狗。

    设计模式更多的强调面向接口。猴子有两个接口,一个是爬树,一个是尾巴倒挂。我现在只需要我的狗爬树,但是不要它尾巴倒挂,那么我只要我的狗实现爬树的接口就行了。同时不会带来像继承猴子来带来的尾巴倒挂的副作用。这就是接口的好处。

    Java技术发展也有好多年了,一个很明显的趋势就是继承的使用越来越少,而接口的使用越来越广泛了。其实只要稍微比较一下JDK里面那些最早就有的类库和最近才加进去的类库,就可以很明显的感觉到java技术领域的编程风格的变迁,由大量的继承到几乎无处不用的面向接口编程。

    接口不是替代继承。比如说我现在就是要我的动物去爬树,我根本就不需要知道到底是狗去爬树还是猴子。我提取出“能爬树”的动物去爬。这个能爬树的动物既可以是猴子,也可以是狗。这样不是很灵活吗?
    狗(爬树,咬人)
猴子(爬树,尾巴倒挂)

如果我既要爬树也要咬人,那么我当然可以选狗,也可以创建一个接口(爬树咬人),然后让狗实现(爬树咬人)接口。

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

学完了这两张,OOP的基本内容就完成了,可以自己动手写一些小程序了~

不同于书上有原始代码,自己从零开始一行一行敲还是很容易出现问题~

为了将这几章的知识融入代码增强理解,我写了如下程序:

/**
* Created by XiaYihua on 2017/1/26.
*/ abstract class Person{
private String name;
private int age;
private String sex; public void say(){System.out.println("Hello!");}; public void setName(String name){
this.name = name;
}
public String getName(){return name;} public void setAge(int age){
this.age = age;
} public int getAge(){return age;} public void setSex(String sex){
this.sex = sex;
}
public String getSex(){return sex;} public abstract void Address(); } class Student extends Person{
private int score;
private String address; public void setScore(int score){
this.score = score;
}
public int getScore(){return score;} public void say(){
super.say();
System.out.println("My score:");
} public void setAddress(String address){
this.address = address;
}
public String getAddress(){
return address;
} public void Address(){
System.out.println("Address: " + getAddress());
} } interface brain{
public abstract void learn();
} interface mouth{
public abstract void teach();
} class Teacher implements brain, mouth{
String grade;
int age; @Override
public void learn() {
System.out.println("I'm learning!");
} @Override
public void teach() {
System.out.println("I'm teaching!");
} public void setAge(int age){
this.age = age;
}
public int getAge(){return age;} public void setGrade(String grade){
this.grade = grade;
}
public String getGrade(){return grade;} } class People{
public static void main(String[] args){
Student P1 = new Student();
P1.say();
P1.setName("Sherlock");
P1.setAge(20);
P1.setSex("Male");
P1.setScore(100);
P1.setAddress("221B"); System.out.println("Name:" + P1.getName() + "\nAge:" + P1.getAge() + "\nSex:" + P1.getSex()+"Score:" + P1.getScore());
P1.Address(); Teacher T1 = new Teacher();
T1.learn();
T1.teach();
T1.setAge(35);
T1.setGrade("Senior 1"); System.out.println("Age:" + T1.getAge() + "\nGrade:" + T1.getGrade());
} }

这个例子融合了抽象类、继承、接口等知识点,虽然没有用到全部细节,但是却让我对这几章的核心知识有了深层次的掌握。

运行结果:

在写的过程中有过小错误:



上面这个错误就是println、print、printf的区别问题,idea联想的第一个就是println,所以在写的时候没有发现格式化输出和println的冲突。

三者的详细区别已经在第三周的博客中总结完成了。

代码托管截图



https://git.oschina.net/xyh20145226/java-besti-is-2015-2016-2-20145226-2/tree/master/src?dir=1&filepath=src&oid=521ad5dd7b419812d6b342bb970ba6c33cd6c7b4&sha=45fff2cdd5eba8ebe469473c18d6c37d17c87529

寒假已全部完成。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第二周 200/400 1/3 12/52
预备作业 0/400 1/4 15/67
第三周 500/900 1/5 10/77
第四周 500/1500 1/6 15/92

参考资料

20145226 《Java程序设计》第4周学习总结的更多相关文章

  1. 20155312 2016-2017-2 《Java程序设计》第九周学习总结

    20155312 2016-2017-2 <Java程序设计>第九周学习总结 课堂内容总结 两个类有公用的东西放在父类里. 面向对象的三要素 封装 继承 多态:用父类声明引用,子类生成对象 ...

  2. 20155213 2016-2017-2 《Java程序设计》第九周学习总结

    20155213 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 JDBC(Java DataBase Connectivity)即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. mongo数据库导入导出数据

    一.Mongodb导出工具mongoexport Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指定导出的数据项,也可以根 ...

  2. WebKit由三个模块组成-Webkit模块介绍

    2.       Webkit 源代码由三大模块组成: 1). WebCore, 2). WebKit, 3). JavaScriptCore. WebCore:排版引擎核心,WebCore包含主要以 ...

  3. Spring JPA 主键

    JPA主键生成器和主键生成策略 JPA中创建实体时,需要声明实体的主键及其主键生成策略.我们有一个实体类叫做Email,其主键上声明如下: @Id @Column(name = "EMAIL ...

  4. vue2.* 目录结构分析 数据绑定 循环渲染数据 数据渲染02

    一.目录 结构分析 node_modules:项目依赖文件(也可以说是模块) src:开发时所用的资源 assets:静态资源文件 App.vue:根组件(最基础的公共页面) main.js:实例化v ...

  5. CNN识别验证码2

    获得验证码图片的俩个来源: 1.有网站生成验证码图片的源码 2.通过python的requests下载验证码图片当我们的训练样本 我们通过第一种方式来得到训练样本,下面是生成验证码的php程序: &l ...

  6. 【小游戏】flappy pig

    (1)这款游戏的画面很简单:一张背景图,始终就没有变过: (2)这款游戏的对象只有俩:一个小鸟(有三种挥动翅膀的状态)以及一对管道(有管道向上和向下两个方向): http://www.cnblogs. ...

  7. WEB安全 魔术引号及注入类型

    一.魔术引号 1. magic_quotes_gpc 变量 什么是魔术引号 Warning本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除.当打开时,所有的 '(单引号),&q ...

  8. ethereumjs/merkle-patricia-tree-1-简介

    https://github.com/ethereumjs/merkle-patricia-tree SYNOPSIS概要 This is an implementation of the modif ...

  9. HDU 1165 公式推导题

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1165 Eddy's research II Time Limit: 4000/2000 MS (Java/Othe ...

  10. Kafka个人总结

    Kafka 应对场景:消息持久化.吞吐量是第一要求.状态由客户端维护.必须是分布式的.Kafka 认为 broker 不应该阻塞生产者,高效的磁盘顺序读写能够和网络 IO 一样快,同时依赖现代 OS ...