第一章 final关键字

1. final关键字基本语法

  • final修饰的类无法继承。
  • final修饰的方法无法覆盖。
  • final修饰的变量只能赋一次值。
  • final修饰的引用一旦指向某个对象,则不能再重新指向其它对象,但该引用指向的对象内部的数据是可以修改
  • final修饰的实例变量必须手动初始化,不能采用系统默认值。
  • final修饰的实例变量一般和static联合使用,称为常量,例如:public static final double PI = 3.1415926;

第二章 抽象类

1. 抽象类概念

1.1 什么是抽象类

类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类。类本身是不存在的,所以抽象类无法创建对象(无法实例化)。

类到对象是实例化。对象到类是抽象。

1.2 抽象类怎么定义

[修饰符列表] abstract class 类名{
类体;
}

2. 抽象类基础语法

  • 抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的。
  • final和abstract不能联合使用,这两个关键字是对立的。(final修饰的不可以被其它类继承,而abstract修饰的是用来被子类继承的)
  • 抽象类的子类可以是抽象类。也可以是非抽象类;抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数 ```java //1.所有的class都必须有一个构造方法,如果你没有在代码里声明构造方法, //系统会自动给你生成一个公有无参的构造方法。而只要你自己声明了一个构造方法, //无论有参无参,私有公有,系统就不再帮你生成默认无参构造器了。 //2.所有的子类构造器都要求在第一行代码中调用父类构造器,如果不写,系统默认去调用父类的无参构造器。 //所以,如果把系统默认配给的方法也算进去,class A{}的代码实际上是

class A{

public A(){}

}

B继承 A 的时候,则是

abstract class B extends A{ public B(){
super(); } } //要试验出这继承规则的内部情况,也很简单,在最上面那个简单试验代码里,加上个私有构造器,有参无参都行。

class A{

private A(){}

}

  1. - 抽象类虽然无法实例化,但是**抽象类有构造方法,这个构造方法是供子类使用的**。
  2. - 抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中;即当抽象方法的子类为非抽象类时,需要将父类的抽象方法实现(覆盖)
  3. > 抽象方法表示没有实现的方法(没有方法体的方法)例如:
  4. > public abstract void doSome();
  5. > 抽象方法特点是:
  6. > 特点1:没有方法体,以分号结尾
  7. > 特点2:前面修饰符列表中有abstract关键字
  8. <a name="wb4q2"></a>
  9. # 第三章 接口
  10. <a name="1wza3"></a>
  11. ## 1. 接口的基本语法
  12. <a name="4J9jU"></a>
  13. ### 1.1 接口基本知识
  14. 1、接口也是一种“引用数据类型”。编译之后也是一个class字节码文件。
  15. 2、接口是完全抽象的。(抽象类是半抽象。)或者也可以说接口是特殊的抽象类。
  16. 3、接口怎么定义,语法是什么?<br />[修饰符列表] interface 接口名{}
  17. 4、接口支持多继承,一个接口可以继承多个接口。
  18. 5、接口中只包含两部分内容:<br />一部分是:常量(public static final可以省略),一部分是:抽象方法;接口中没有其它内容了。只有以上两部分。
  19. 6、接口中所有的元素都是public修饰的。(都是公开的。)
  20. 7、接口中的抽象方法定义时:public abstract修饰符可以省略。
  21. 8、接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
  22. 9、接口中的常量的public static final可以省略。
  23. <a name="bctL1"></a>
  24. ### 1.2 接口基本语法
  25. - 类和类之间叫做继承,类和接口之间叫做实现(implements)。
  26. - 当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖、重写)。
  27. - 一个类可以同时实现多个接口。(对于计算机来说,一个机箱上有多个接口,一个接口是接键盘的,一个接口是接鼠标的)
  28. - 接口A和接口B虽然没有继承关系,但是写代码的时候,可以互转;编译器没意见,但是运行时可能出现:ClassCastException
  29. > 之前有一个结论:无论向上转型还是向下转型,两种类型之间必须要有继承关系,没有继承关系编译器会报错。(这句话不适用在接口方面。)最终实际上和之前还是一样,需要加:instanceof运算符进行判断。向下转型养成好习惯。转型之前先if+instanceof进行判断。
  30. ```java
  31. public class Test03{
  32. public static void main(String[] args){
  33. // 多态该怎么用呢?
  34. // 都是父类型引用指向子类型对象
  35. A a = new D();
  36. //a.m2(); // 编译报错。A接口中没有m2()方法。
  37. B b = new D();
  38. C c = new D();
  39. // 这个编译没问题,运行也没问题。
  40. // 调用其他接口中的方法,你需要转型(接口转型。)
  41. B b2 = (B)a;
  42. b2.m2();
  43. // 直接向下转型为D可以吗?可以
  44. D d = (D)a;
  45. d.m2();
  46. M m = new E();
  47. // 经过测试:接口和接口之间在进行强制类型转换的时候,没有继承关系,也可以强转。
  48. // 但是一定要注意,运行时可能会出现ClassCastException异常。
  49. // 编译没问题,运行有问题。
  50. //K k = (K)m;
  51. if(m instanceof K){
  52. K k = (K)m;
  53. }
  54. }
  55. }
  56. interface K{
  57. }
  58. interface M{
  59. }
  60. class E implements M{
  61. }
  62. // --------------------------------------------------------------------
  63. interface X{
  64. }
  65. interface Y{
  66. }
  67. interface Z extends X,Y{ //接口和接口支持多继承。
  68. }
  69. //------------------------------------------------------------------
  70. interface A{
  71. void m1();
  72. }
  73. interface B{
  74. void m2();
  75. }
  76. interface C{
  77. void m3();
  78. }
  79. // 实现多个接口,其实就类似于多继承。
  80. class D implements A,B,C{
  81. // 实现A接口的m1()
  82. public void m1(){
  83. }
  84. // 实现B接口中的m2()
  85. public void m2(){
  86. System.out.println("m2 ....");
  87. }
  88. // 实现接口C中的m3()
  89. public void m3(){
  90. }
  91. }

1.3 继承和实现都存在的话,代码应该怎么写

  1. /*
  2. 继承和实现都存在的话,代码应该怎么写?
  3. extends 关键字在前。
  4. implements 关键字在后。
  5. */
  6. public class Test04{
  7. public static void main(String[] args){
  8. // 创建对象(表面看Animal类没起作用!)
  9. Flyable f = new Cat(); //多态。
  10. f.fly();
  11. // 同一个接口
  12. Flyable f2 = new Pig();
  13. // 调用同一个fly()方法,最后的执行效果不同。
  14. f2.fly();
  15. Flyable f3 = new Fish();
  16. f3.fly();
  17. }
  18. }
  19. // 动物类:父类
  20. class Animal{
  21. }
  22. // 可飞翔的接口(是一对翅膀)
  23. // 能插拔的就是接口。(没有接口你怎么插拔。)
  24. // 内存条插到主板上,他们之间有接口。内存条可以更换。
  25. // 接口通常提取的是行为动作。
  26. interface Flyable{
  27. void fly();
  28. }
  29. // 动物类子类:猫类
  30. // Flyable是一个接口,是一对翅膀的接口,通过接口插到猫身上,让猫变的可以飞翔。
  31. class Cat extends Animal implements Flyable{
  32. public void fly(){
  33. System.out.println("飞猫起飞,翱翔太空的一只猫,很神奇,我想做一只猫!!");
  34. }
  35. }
  36. // 蛇类,如果你不想让它飞,可以不实现Flyable接口
  37. // 没有实现这个接口表示你没有翅膀,没有给你插翅膀,你肯定不能飞。
  38. class Snake extends Animal{
  39. }
  40. // 想飞就插翅膀这个接口。
  41. class Pig extends Animal implements Flyable{
  42. public void fly(){
  43. System.out.println("我是一只会飞的猪!!!");
  44. }
  45. }
  46. // 鱼(默认实际上是存在继承的,默认继承Object。)
  47. /*
  48. class Fish extends Object implements Flyable{
  49. }
  50. */
  51. class Fish implements Flyable{ //没写extends,也是有的,默认继承Object。
  52. public void fly(){
  53. System.out.println("我是六眼飞鱼(流言蜚语)!!!");
  54. }
  55. }

2. 接口在开发中的作用

  • 接口在开发中的作用,类似于多态在开发中的作用。
  • 面向接口编程,可以降低程序的耦合度,提高程序的扩展力,符合OCP开发原则;接口的使用离不开多态机制。(接口+多态才可以达到降低耦合度)

3. 类型和类型之间的关系

  • is a(继承)、has a(关联)、like a(实现)

    1. is a:

      1. Cat is a Animal(猫是一个动物)<br /> 凡是能够满足is a的表示“继承关系” <br /> b. has a:<br /> I has a Pen(我有一支笔)<br /> 凡是能够满足has a关系的表示“关联关系”<br /> 关联关系通常以“属性”的形式存在。<br /> c. like a:<br /> Cooker like a FoodMenu(厨师像一个菜单一样)<br /> 凡是能够满足like a关系的表示“实现关系”<br /> 实现关系通常是:类实现接口。

4. 抽象类和接口的区别

在这里我们只说一下抽象类和接口在语法上的区别(至于以后抽象类和接口应该怎么进行选择,通过后面的项目去体会)

  1. 抽象类是半抽象的。<br /> 接口是完全抽象的。
  2. 抽象类中有构造方法。<br /> 接口中没有构造方法。
  3. ** 接口和接口之间支持多继承。**<br /> 类和类之间只能单继承。
  4. 一个类可以同时实现多个接口。<br /> 一个抽象类只能继承一个类(单继承)。<br /> **接口中只允许出现常量和抽象方法**。

第四章 包

1. package概述及使用

1.1 package概述

package是java中包机制。包机制的作用是为了方便程序的管理。不同功能的类分别存放在不同的包下。

1.2 package怎么用

package是一个关键字,后面加包名。例如:package com.bjpowernode.javase.chapter17;

注意:package语句只允许出现在java源代码的第一行。

1.3 包名的命名规范

一般都采用公司域名倒序的方式(因为公司域名具有全球唯一性。)包名命名规范:公司域名倒序 + 项目名 + 模块名 + 功能名

1.4 对于带有package的java程序编译、运行

编译:
javac -d . HelloWorld.java
解释一下:
javac 负责编译的命令
-d 带包编译
. 代表编译之后生成的东西放到当前目录下(点代表当前目录)
HelloWorld.java 被编译的java文件名。
运行:
java com.bjpowernode.javase.chapter17.HelloWorld

2. import

2.1 import使用

  1. - import 完整类名;
  2. - import 包名.*;
  3. - import语句只能出现在package语句之下,class声明语句之上。

import java.util.Scanner;和import java.util.; 这样是不是效率比较低。 // 这个效率不低,因为编译器在编译的时候,会自动把变成具体的类名。 import java.util.; // 想省懒劲你不能太省了。 import java.; 这是不允许的,因为在java语言中规定,这里的*只代表某些类的名字。

2.2 import什么时候不需要

  1. - java.lang不需要
  2. - 同包下不需要

第五章 访问控制权限

1. 访问控制权限基本概念

1.1 访问控制权限都有哪些

private 私有
public 公开
protected 受保护
默认

默认不写不是说在前面加上default

1.2 控制的范围

访问控制修饰符 本类 同包 子类 任意位置
public 可以 可以 可以 可以
protected 可以 可以 可以 不可以
默认 可以 可以 不可以 不可以
private 可以 不可以 不可以 不可以

范围从大到小排序:public > protected > 默认 > private

1.3 访问控制权限修饰符可以修饰什么

属性(4个都能用)
方法(4个都能用)
类(public和默认能用,其它不行。)
接口(public和默认能用,其它不行。)

第六章 object类中的一些方法

本章需要了解学习的方法: protected Object clone() // 负责对象克隆的。

int hashCode() // 获取对象哈希值的一个方法。 boolean equals(Object obj) // 判断两个对象是否相等 String toString() // 将对象转换成字符串形式 protected void finalize() // 垃圾回收器负责调用的方法

1. toString()方法

1.1 如何学习这些方法

  • 第一种方法:去源代码当中。(但是这种方式比较麻烦,源代码也比较难)
  • 第二种方法:去查阅java的类库的帮助文档。

什么是API? 应用程序编程接口。(Application Program Interface) 整个JDK的类库就是一个javase的API。 每一个API都会配置一套API帮助文档。 SUN公司提前写好的这套类库就是API。(一般每一份API都对应一份API帮助文档。)

1.2 tostring方法学习

1、源代码长什么样?

  1. public String toString() {
  2. //源代码上toString()方法的默认实现是:
  3. //类名@对象的内存地址转换为十六进制的形式
  4. return this.getClass().getName() + "@" + Integer.toHexString(hashCode());
  5. }
  1. 2SUN公司设计toString()方法的目的<br /> 通过调用这个方法可以将一个“java对象”转换成“字符串表示形式”
  2. 3、其实SUN公司开发java语言的时候,建议所有的子类都去重写toString()方法;toString()方法应该是 一个简洁的、详实的、易阅读的。

2. equals方法

1、equals方法的源代码

  1. public boolean equals(Object obj) {
  2. //this代表的是当前调用方法的对象,如在主方法创建该类对象,并赋给a引用,
  3. //那么a.equals(obj);便是a == obj;
  4. return (this == obj);
  5. }

2、SUN公司设计equals方法的目的是什么?
以后编程的过程当中,都要通过equals方法来判断两个对象是否相等;equals方法是判断两个对象是否相等的。

3、我们需要研究一下Object类给的这个默认的equals方法够不够用!!!!
在Object类中的equals方法当中,默认采用的是“==”判断两个java对象是否相等。而“==”判断的是两个java对象的内存地址,我们应该判断两个java对象的内容是否相等。所以老祖宗的equals方法不够用,需要子类重写equals。

4、判断两个java对象是否相等,不能使用“==”,因为“==”比较的是两个对象的内存地址。

String类重写toString、equals方法

5、重写equals方法

  1. // 示例:
  2. // 重写规则:当一个用户的用户名和家庭住址都相同,表示同一个用户。
  3. // 这个equals判断的是User对象和User对象是否相等。
  4. public boolean equals(Object obj){
  5. // 用户名和用户名相同,住址和住址相同的时候,认定是同一个用户。
  6. //下面这几行代码可以当作一个模板
  7. if(obj == null || !(obj instanceof User)) return false;
  8. if(this == obj) return true;
  9. User u = (User)obj;
  10. if(this.name.equals(u.name) && this.addr.equals(u.addr)){
  11. return true;
  12. }
  13. return false;
  14. }

6、还需注意重写equals方法要彻底

3. finalize()方法

1、在Object类中的源代码:

  1. // GC:负责调用finalize()方法。
  2. protected void finalize() throws Throwable { }

2、finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的。

3、这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法
不同于equals、toString,equals和toString()方法是需要你写代码调用的;finalize()只需要重写,重写完将来自动会有程序来调用。

4、finalize()方法的执行时机:
当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。

5、finalize()方法实际上是SUN公司为java程序员准备的一个时机,垃圾销毁时机;
如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法当中。

提示:
java中的垃圾回收器不是轻易启动的,垃圾太少,或者时间没到,种种条件下, 有可能启动,也有可能不启动。 有一段代码可以建议垃圾回收器启动。 System.gc(); // 建议启动垃圾回收器。(只是建议,可能不启动,也可能启动。启动的概率高了一些。)

4. hashCode方法

1、在Object类中的源代码:

  1. public native int hashCode();

2、hashCode()方法返回的是哈希码:
实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值;所以hashCode()方法的执行结果可以等同看做一个java对象的内存地址。