Java入门
- 一个Java程序只能有一个public类,最多只能有一个,可以没有,但不能有多个,并且文件名字要以这个类的名字相同。
- 利用javac对Java程序进行编译,编译会得到很多*.class的文件,对于这种类型的文件,我们可以用javap对这样的文件进行反编译,得到我们的源文件。
- 一般代码遵循Kernighan风格,即左大括号‘{’写在上一行的行尾,有大括号‘}’独占一行。
- 编译出的众多class文件中,其中我们只能运行主类,用java这个命令。
- 注释有两种: 单行注释// 多行注释/* */
例如:
基本数据类型与数组
标识符与关键字
- 标识符特点:
- 标识符由字母、下画线、美元符号和数字组成,长度不受限制。
- 标识符的第一个字符不能是数字字符。
- 标识符不能是关键字。
- 标识符不能是true、false和null。
- 标识符中的字母区分大小写。
- Unicode标准字符集可以识别65536个字符,前128个字符刚好是ASCII码。
一些关键字:abstract、assert、boolean、break、byte、case、catch、char、class、const、continue、default、do、double、else、enum、extends、final、finally、float、for、goto、if、implements、import、instanceof、int、interface、long、native、new、package、private、protected、public、return、short、static、strictfp、switch、synchronized、this、throw、throws、transient、try、void、volatile、while
基本数据类型
- 逻辑类型——boolean 只有true和false
- 整数类型
- int:分配4个字节内存,取值范围是-2^31 ~ 2^31-1
- byte:分配1字节内存,取值范围是-27~27-1
- short:分配2个字节内存,占16位,取值范围-2^15 ~ 2^15 -1
- long:分配8个字节,占64位,取值范围是-2^63 ~ 2^63 -1
- 字符类型——char:分配2个字节内存,占16位,最高位不是符号位,没有负数的char,取值范围为0~65535
- 浮点类型
- float:常量后面必须要有后缀f或F,只保留8位有效数字,分配4个字节,占32位。
- double:后面可有后缀d或D,但允许省略该后缀,保留16位有效数字,分配8个字节内存,占64位。
- 一些特殊的字符——:\n(换行),\b(退格),\t(水平制表符),’(单引号),"(双引号),\(反斜线)等。
例如:
类型转换运算
- 类型精度排序(从低到高): byte short char int long float double
- 把级别低的变量的值赋给高级别的变量,系统自动完成数据类型的转换;但把级别高的变量的值赋给级别低的变量时,必须使用类型转换运算,其格式:(类型名)要转换的值。
例如:
输入、输出数据
- 输入数据需要导入一个Scanner的类,使用该类创建对象,然后这个对象调用下列方法,{nextBoolean(),neatByte(), nextShort(),nextInt(),nextLong(),nextFloat(),nextDouble()},读取用户在命令行输入的各种基本类型数据。
- 输出基本类型数据用System.out.println()或System.out.print(),区别是前者输出数据后自动换行,后者不换行。另外在JDK1.5中新增了和C语言中printf函数类似的输出方法,System.out.printf(),输出的格式与C语言相同。注:在jdk13中,使用System.out.print()出错
- 一些格式符表示的含义:%d(输出int类型),%c(输出char类型),%f(输出float类型,小数部分最多保留6位),%s(输出字符串数据),%md(输出的int类型的数据占m列),%m.nf(输出浮点型数据占m列,小数点保留n位)
例如:
数组
- 申明数组的两种格式:
数据元素类型 数组名[]; // 这是一维数组,二维数组就在加一个[]
数据元素类型 [][] 数组名; // 这是一个二维数组,一维数组就去掉一个[]就可以了
- 为数据分配元素,格式: 数组名 = new 数组元素的类型[数组元素的个数]; // 和C语言不同的,Java允许使用int型变量的值指定数组的元素的个数。
- 数组的长度求法,格式:数组名.length // 二维数组时显示的是当中一维数组的个数。
- 声明数组的同时就可以初始化。 例: float boy[] = {3.1f, 23.8f}; // 二维数组可以用多个一维数组来进行初始化。
- 两个类型相同的数组,一旦二者有相同的引用,那么二者就具有一样的单元。
例如:
运算符、表达式和语句
运算符与表达式
- 加(+)、减(-)、乘(*)、除(/)、求余(%)运算都是二目运算,及连接两个操作元的运算符。
- 加减运算的优先级是4级,乘除求余运算的优先级是3级。
- ++x(–x):使用x之前,先使x的值增(减)1.
- x++(x–):使用x之后,使x的值增(减)1.
- 算数混合运算中,如果有变量精度高于int型,则运算结果取最高精度;如果所有变量精度都低于int型,则运算结果取int精度。
- Java允许把不超出byte、short和char的取值范围的算术表达式赋给byte、short和char型变量。
- 关系运算符是二目运算符,优先等级为6的有:>、<、>=、<=;优先等级为7的有:==、!=
- 逻辑运算符:与(&&,二目运算,优先等级11)、或(||,二目运算,优先等级12)、非(!,单目运算,优先等级2)。逻辑运算的结果只能是true或false,和C不同,C中结果为0或非0。且Java的逻辑运算只能对boolean型进行运算。
- 位运算:与&、或|、异或^
- instanceof运算符:二目运算符,左边的操作元是一个对象,右面是一个类。当左面的对象是右面类或子类创建的对象时,给运算符的运算结果是true,否则是false
语句概述
- 可以用{}吧一些语句包括起来构成复合语句。
- 一个分号也是一条语句,称作空语句。
if条件分支语句
- 和C基本相同,但判断的表达式只能是Boolean类型,只有一个语句可以不用{}。
- Python中写习惯了elif,Java和C相同,是else if
switch开关语句
- switch中判断表达式的值可以为byte、short、int、char型,但不可以是long型数据。给定的常量值中不能有重复值。
- switch每一次执行,只有遇到break,才会停止执行。
- 当表达式的值和给定的常量值都不相同,如果有default,那么会执行default中的语句。
循环语句
- for循环中和C相同,有3个表达式,表达式1完成必要的初始化工作,表达式2完成判断,其值只能是Boolean类型,表达式3用于修改变量,改变循环条件。
- while循环先判断是否满足条件,满足再执行语句;do-while循环先执行一遍语句,再判断是否满足条件。
break和continue语句
- break——整个循环直接结束。
- continue——立刻结束本次循环,开始执行下一次循环。
for语句与数组
- JDK1.5后的版本对增加了for语句的功能,可以方便的遍历数组。格式为:for(声明循环变量: 数组的名字){…}
- 声明的循环变量不可以使用已经声明过的变量。
例如:
类与对象
类
- 类声明和类体,类体一部分是变量声明,另一部分是方法。全局变量(成员变量)的有效范围是整个类,与书写的位置无关,局部变量只在方法内有效,且和书写位置有关。
- 如果局部变量的名字和成员变量的名字相同,那么成员变量被隐藏,即该成员变量在这个方法内暂时失效。
- 声明变量时可以初始化,如果声明后未初始化,那只能在方法进行赋值语句,在方法外赋值语句是非法的。
- 局部变量没有默认值,和C不同,C没有初始化会有一个值。
- 类的UML图属于结构图,常用于描述一个系统的静态结构。分为三层:
- 一层为名字层,如果类名字是常规字形,表明该类是具体类,如果名字是斜体字形,表明该类是抽象类。
- 第二层是变量层,也是属性层。
- 第三层是方法层,也称为操作层。
构造方法与对象的创建
- 构造方法是类中的一种特殊方法,当程序用类创建对象时需要使用它的构造方法。类的构造方法的名字必须与它所在的类的名字完全相同,且没有类型。允许在一个类中编写若干个构造方法,但必须保证它们的参数不同,参数不同是指:参数的个数不同,或参数个数相同,但参数列表中对应的某个参数的类型不同。
- 如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句。
例如:
- 类是一种数据类型,类声明的变量叫对象变量,简称对象。
- 创建对象分两步:
- 声明对象(格式:类的名字 对象的名字),此时这个对象在内存中还没有任何数据,称为空对象,空对象不能使用,因为它还没有得到任何“实体”;
- 为声明的对象分配变量(格式:对象的名字=new 类的名字),new运算符和类的构造方法进行运算,运算期间做两件事:
- 第一件事是为各个变量分配内存空间,然后执行构造方法中的语句,如果成员变量在声明时没有指定初值,所使用的构造方法也没有对成员变量进行初始化操作,那么整型默认初值为0,浮点型默认0.0,boolean型默认初值为false,对于引用型默认初值为null;
- 第二件事是计算出一个称作引用的值(该值包含这代表这些成员变量内存位置及相关的重要信息,是一个十六进制数),把该引用赋给对象。完成以上两步,才算完整的创建了对象。
- 对象操作自己的变量(体现对象的属性):对象.变量;
- 对象调用类中的方法(体现对象的行为):对象.方法;
例如:
- 不能让一个空对象去调用方法产生行为。如果使用了空对象,那代码的编译是通过的,但运行时会出现异常NullPointerException。
- 对象(变量)负责存放引用,以确保对象可以操作分配给该对象的变量以及调用类中的方法,分配给对象的变量被习惯地称作对象的实体。
- 在Java中,对于同一个类声明的两个对象,允许进行赋值操作(对象1=对象2;),此时两个对象的实体完全相同。
- Java有“垃圾收集”机制,这种机制周期地检查某个实体是否已不再被任何对象所拥有(引用),如果发现这样的实体,就释放实体占有的内存。
- 如果希望Java虚拟机立刻进行“垃圾收集”操作,可以让System类调用gc()方法。
类与程序的基本结构
- Java类与程序的基本结构,一个Java应用程序可以有多个源文件,一个源文件可以由若干个类构成,这些类可以在一个源文件中,也可以分布在若干个源文件中。
- Java应用程序有一个主类,即含有Main方法的类,Java应用程序可以从主类开始执行。将相应的源文件保存在相同的文件夹下,可以分别对其进行编译,也可以只编辑主类。当主类中用其它源文件中的类申明对象的时候,我们可以只编译含有主类的源文件,Java系统会自动的先编译主类需要的其它源文件。
参数传值
- Java中,方法所有的参数都是“传值”,也就是参数变量的拷贝。
- 基本数据类型的参数,向该参数传递的值级别不能够高于该参数。
- 类型相同的两个数组,一但引用相同,就有一样的单元(元素)。
- 类型相同的两个对象,一旦引用相同,就有一样的实体(变量)。
- 可变参数使用“…”表示若干个参数,这些参数的类型必须相同,并且最后一个参数必须是方法的参数列表中的最后一个参数。
例如:
对象的组合
- 一个类的成员变量可以是Java允许的任何数据类型,因此,一个类可以把某个对象作为自己的一个成员变量,如果用这样的类创建对象,那么该对象中就会有其它的对象,也就是说,该类的对象将其它对象作为自己的组成部分,这就是人们常说的Has-A。
- 如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法。
- 通过组合对象来复用方法有两个特点:
- 通过组合对象来复用方法也称“黑盒”复用,因为当前对象只能委托所包含的对象调用其方法,当前对象对对象所包含的对象的方法的细节(算法的细节)一无所知;
- 当前对象随时可以更换所包含的对象,即对象所包含的对象属于弱耦合关系。
例如:
实例成员与类成员
- 类体中包括成员变量的声明和方法的定义,而成员变量又可以细分为实例变量和类变量。声明变量时,用关键字static给予修饰的称作类变量,否则称作实例变量(类变量也称为static变量、静态变量)。
- 实例变量和类变量的区别:
- 不同对象的实例变量互不相同
- 所有对象共享类变量
- 通过类名直接访问类变量
例如:
- 类中的方法也可分为实例方法和类方法。方法声明时,方法类型前面不加关键字static修饰的是实例方法,加static关键字修饰的是类方法(静态方法)。
- 对象可以调用实例方法和类方法,类方法也可以直接用类名调用,实例方法可以操作实例变量和类变量,但类方法只能操作类变量。如果一个方法不需要操作类中的任何实例变量,就可以满足程序需要,就可以将这样的方法设计为一个static方法。
方法重载
- Java中存在两种多态:重载(Overload)和重写(Override)。
- 方法重载:一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同。两个方法的参数不同是指满足以下条件之一:
- 参数的个数不同
- 参数的个数相同,但参数列表中对应的某个参数的类型不同。(注:如果两个方法名字相同,参数的类型也相同,只是参数的排列顺序不同,这样重载会出现歧义,我们应当避免重载出现歧义)
this关键字
- this是Java的一个关键字,表示某个对象。this可以出现在实例方法和构造方法中,但不可以出现在类方法中。
包
- 包是Java语言有效的管理类的一个机制。不同Java源文件中可能出现名字相同的类,如果想区分这些类,就需要使用包名。包名的目的是有效的区分名字相同的类,不同Java源文件中的两个类名字相同时,它们可以通过隶属不同的包来相互区分。
- 通过关键字package声明包语句。package语句作为Java源文件的第一条语句,且最多只有一个包语句。(package格式为:package 包名;)
- 如果一个类有包名,那么不能随意存放,应该按照包名进行存储。
例如:
import语句
- import语句用于引入包中的类,import语句必须写在package语句后。书写形式:
- import 包名.类名;
- import 包名.*;(导入这个包中的所有类)。
- Java类库中大约有130多个包,例如:
- java.lang:包含所有的基本语言类
- javax.swing:包含抽象窗口工具集中的图形、文本、窗口GUI类
- java.io:包含所有的输入/输出类
- java.util:包含实用类
- java.sql:包含操作数据库的类
- java.net:包含所有实现网络功能的类
- 引入自己包中的类,把程序使用的自定义包名所形成的目录都放在一个同一个文件夹中。
例如:
访问权限
- 访问权限:指对象是否可以通过“.”运算符操作自己的变量或通过“.”运算符调用类中的方法。
- 访问限制修饰符有private、protected和public,它们都是Java的关键字,用来修饰成员变量或方法。
- 特别注意:在编写类的时候,类中的实例方法总是可以操作该类的实例变量和类变量;类方法总是可以操作该类中的类变量,与访问限制没有关系。
- 私有变量和私有方法:用private修饰的成员变量和方法称为私有变量和私有方法。当该类的对象出现的位置是其它另外一个类,那么该对象不能访问自己的private成员。
- 共有变量和共有方法:用public修饰的成员变量和方法称为共有变量和共有方法。该类的对象总能方法自己的public成员。
- 友好变量和友好方法:不用private、public和protected修饰符修饰的成员变量和方法称为友好变量和友好方法。该类的对象出现的位置是同包的一个类,那么该对象能访问自己的友好成员。
- 受保护的成员变量和方法:用protected修饰的成员变量和方法被称为受保护的成员变量和受保护的方法。该类的对象出现的位置是同包的一个类,那么该对象能访问自己的protected成员。
- 友好和protected的区别在类的继承时会得以体现。
- 类申明时,如果在class前面加上了public关键字,就称这样的类是一个public类。不加public修饰的类被称作友好类,那么另外一个类中使用友好类创建对象时,要保证它们在同一个包中。不能用protected和private修饰类。
- 访问限制修饰符按访问权限从高到低的排列顺序是public、protected、友好的、private。
基本类型的类封装
- Java的基本数据类型包括boolean、byte、short、char、int、long、float和double。Java同时也提供了基本数据类型相关的类,实现了对基本数据类型的封装。这些类在java.lang包中,分别是Byte、Integer、Short、Long、Float、Double和Character。
- Double和Float类:(Float类相同,调用的方法为floatValue())
Double duixiang = new Double(4.14); // 使用Double类构造方法创建一个Double类型的对象
duixiang.doubleValue(); // 返回该对象含有的double型数据
- Byte、Short、Integer、Long类:和之前的相同,调用自己的方法返回该对象含有的基本数据。
Byte duixiang = new Byte();
duixiang.byteValue();
- Character类:这些类型都有很多的静态方法,我们可以通过反编译来查看这些方法,有使用手册更好。
javap java.lang.Character // 反编译这个类,我们可以在终端里看到它的静态方法
对象数组
- 数组是相同类型的变量按顺序组成的集合,一个数组中存放的全部是同一个类型的对象,这就是对象数组。
Student [] stu; // 声明一个学生的对象数组
stu = new Student[10]; // 说明这个对象数组的长度
注:上述代码仅仅定义了数组stu有10个元素,并且每个元素都是一个Student类型的对象,但这些对象目前都是空对象,因此在使用数组stu中 的对象前,应当创建数组所包含的对象。
JRE扩展与jar文件
- Java运行环境提供的类库只是核心类,不能满足用户的所有需求。所以,Java运行环境提供了扩展(\jre\lib\ext),只要将类打包为jar格式的文件,放入扩展中,程序就可以使用import语句使用扩展中的类了。
例如:
文档生成器
- 使用JDK提供的javadoc.exe可以制作源文件类结构的html格式文档。
javadoc 文件名.java // 这时会生成若干个html文档,查看文档可以知道源文件中类的组成结构。
javadoc -d 路径 文件名.java // 还可以使用参数-d指定生成文档所在的目录
子类与继承
子类和父类
- 在类的声明中,通过使用关键字 extends 来定义一个类的子类,格式如下:
class 子类名 extends 父类名 {
...
}
- Java的继承关系形成树形结构,根节点是Object类(Object是java.lang包中的类),即所有类的祖先类。
- 一个类(除了Object类)有且仅有一个父类,可以有多个或零个子类。类默认就是Object的子类,不需要故意继承。
子类的继承性
- 子类和父类在同一个包中的继承性:子类自然的继承了父类中不是private的成员变量和方法,并且访问权限保持不变。
- 子类和父类不在同一个包中的继承性:子类只继承父类中的protected和public访问权限的成员变量和方法。
- B类是A类的子类,C类是B类的子类,D类是C类的子类。如果用D类在D本身中创建了一个对象,那么该对象总是可以通过“.”运算符访问继承的或自己定义的protected变量和方法,但是,如果另一个other类中用D类创建了一个对象object,该对象通过“.”运算符访问protected变量和方法的权限如下所述:
- other和D类在一个包里:可以访问这些protected变量和方法
- other和D类不在一个包里:对于子类D从父类继承的protected变量和方法,需要追溯到这些变量和方法所在的祖先类,只要这些祖先类和other类在同一个包中,就可以访问。
子类与对象
- 用子类创建一个对象的时候,计算机为其分配内存,父类中的变量,即使是未继承的变量,也会在这个过程中被分配内存,子类所创建的对象可以通过继承的方法间接的去访问这些未被继承的变量。
- instanceof运算符是Java独有的双目运算符,其左面的操作元是对象,右面的操作元是类,当左面的操作元是右面的类或其子类所创建的对象时,instanceof运算的结果是true,否则是false.
成员变量的隐藏和方法重写
- 编写子类的时候,如果声明的成员变量的名字和父类继承来的成员变量的名字相同(声明的类型可以不同),在这种情况下,子类会隐藏所继承的成员变量。
- 子类隐藏的成员变量的特点如下:
- 子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员变量。
- 子类对象仍然可以通过从父类继承的方法操作被子类隐藏的成员变量。
- 子类通过重写可以隐藏已继承的方法(方法重写称为方法覆盖)。
- 重写方法:指子类中定义一个方法,这个方法的类型和父类的方法的类型一致或者是父类的方法的类型的子类型(所谓子类型,是指如果父类的方法的类型是“类”,那么允许子类的重写方法的类型是“子类”),并且这个方法的名字、参数个数参数类型和父类的方法完全相同。
- 重写父类的方法时,不允许降低方法的访问权限,但可以提高访问权限。
super 关键字
- 子类一旦隐藏了了继承的成员变量或方法,那么子类创建的对象不再拥有该变量,该变量将归super关键字所拥有。
- 当super调用被隐藏的方法时,该方法中出现的成员变量是被子类隐藏的成员变量或继承的成员变量。
例如:
- 当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法。如果父类有多个构造方法,子类调用父类不带参数的构造方法。
- 由于子类不继承父类的构造方法,因此子类在其构造方法中需要使用super来调用父类的构造方法,而且super必须是子类构造方法的头一条语句。如果在子类的构造方法中没有明显的写出super关键字来调用父类的构造方法,那么默认就有super()。
- 如果一个类里定义了一个或多个构造方法,那么Java不提供默认的构造方法(不带参数的构造方法),因此,当在父类中定义多个构造方法时,应当包括一个不带参数的构造方法,防止子类省略super时出现错误。
final 关键字
- 可以使用final将类声明为final类。final类不能被继承,即不能拥有子类。
final class A {
...
}
- 有时候出于安全性的考虑,将一些类修饰为final类。例如Java在java.lang包中提供的String类对于编译器和解释器的正常运行有很重要的作用,Java不允许用户扩展String类,为此,Java将它修饰为final类。
- 如果用final修饰父类中的一个方法,那么这个方法不允许子类重写,也就是不允许子类隐藏可以继承的final方法。
- 如果成员变量或局部变量被修饰为final,那它就是常量,程序在声明常量时必须指定该常量的值。
对象的上转型对象
- 当用子类创建的一个对象,并把这个对象的引用放到父类的对象中,这时称父类创建的这个对象是子类这个对象的上转型对象。
父类 a;
子类 b = new 子类();
a = b;
- 对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能(上转型对象相当于子类对象的一个“简化”对象)。
- 上转型对象具有的特点:
- 上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能调用子类新增的方法(失掉了一些行为)。
- 上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。
- 可以将对象的上转型对象再强制转换到一个子类对象,这时,该对象又具备了子类所有的属性和功能。
- 不可以将父类创建对象的引用赋值给子类声明的对象。
- 如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法。
例如:
继承与多态
- 多态性就是指父类的某个方法被子类重写时,可以各自产生自己的功能行为。
abstract类和abstract方法
- 用关键字abstract修饰的类称为abstract类(抽象类),用关键字abstract修饰的方法称为abstract方法(抽象方法)。
- 对于abstract方法,只允许声明,不允许实现(没有方法体),而且不允许使用final和abstract同时修饰一个方法或类,也不允许使用static修饰abstract方法。
- abstract类中可以有abstract方法。
- abstract类不能用new运算符创建对象。
- 如果一个非abstract类是abstract类的子类,它必须重写父类的abstract方法,并给出方法体;如果一个abstract类是abstract类的子类,它可以重写父类的abstract方法,也可以继承父类的abstract方法。
- abstract类的对象可以作为上转型对象。
例如:
面向抽象编程
- 所谓面向抽象编程,是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,即所设计类中的重要数据是抽象类声明的对象,而不是具体声明的对象。
开—闭原则
- 开-闭原则,就是让设计的系统对扩展开放,对修改关闭。
接口与实现
接口
- 使用关键字interface来定义一个接口。分为接口声明和接口体:
interface Printable {
final int MAX=100; // 等价于 public static final int MAX=100;
void add();
float sum(float x,float y);
}
- 接口体中包含常量的声明(没有变量)和抽象方法两部分。
- 接口体中只有抽象方法,没有普通方法,而且接口体中所有的常量和抽象方法的访问权限一定是public,而且是static常量(允许省略public、final和static修饰符)。
实现接口
- 一个类需要在类声明中使用关键字implements声明该类实现一个或多个接口。如果实现多个接口,用逗号隔开接口。
class A implements 接口1, 接口2
- 如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的所有方法。
- 由于接口中的方法一定是public abstract方法,所以在类重写接口方法时不仅要去掉abstract修饰符、给出方法体,而且方法的访问权限一定要明显的用public来修饰(否则就降低了访问权限)。
- 定义接口时,如果关键字interface前面加上public关键字,就趁这样的接口是一个public接口。public接口可以被任何一个类实现。如果不加public修饰,就称为友好接口,友好接口可以被与该接口在同一包中的类实现。
- 如果父类实现了某个接口,那么子类也就自然实现了该接口。
- 接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。
例如:
接口回调
- 和类一样,接口也是Java中一种重要的数据类型,用接口声明的变量称为接口变量。
- 接口属于引用型变量,接口变量中可以存放实现该接口的类的实例的引用,即存放对象的引用。
例如:
理解接口
- 理解的关键点:
- 接口可以抽象出重要的行为标准,该行为标准用抽象方法来表示。
- 可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被该类实现的接口方法,即体现该类根据接口里的行为标准给出的具体行为。
接口与多态
- 由接口产生的多态就是指不同的类在实现同一接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
例如:
接口参数
- 如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。
例如:
abstract类与接口的比较
- abstract类和接口的比较如下:
- abstract类和接口都可以有abstract方法。
- 接口中只可以有常量,不能有变量;而abstract类中既可以有常量,也可以有变量。
- abstract类中也可以有非abstract方法,接口不可以。
面向接口编程
- 通过在接口中声明若干个abstract方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。
内部类与异常类
内部类
- Java支持在一个类中定义另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。
- 内部类和外嵌类之间的重要关系如下:
- 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
- 内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。
- 内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。
例如:
- 内部类可以被修饰为static内部类,static内部类就是外嵌类中的一种静态数据类型,这样程序可以在其它类中使用static内部类来创建对象。
匿名类
- 创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉声明后的类体,称作匿名类。
- 匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象。
例如:
- Java允许直接用接口名和一个类体创建一个匿名对像,此类体被认为是实现了这个接口的类去掉类声明后的类体,称作匿名类。
new 接口名() {
实现接口的匿名类的类体
};
例如:
异常类
- Java使用throw关键字抛出一个Exception子类的实例表示异常发生。
- Java使用try-catch语句来处理异常,将可能出现的异常操作放在try-catch语句的try部分,一旦try部分抛出异常对象,或调用某个可能抛出异常对象的方法,并且该方法抛出了异常对象,那么try部分将立刻结束执行,转向执行相应的catch部分。
try {
包含可能发生异常的语句
}
catch(ExceptionSubClass1 e) {
...
}
catch(ExceptionSubClass2 e) {
...
}
例如:
- 编写程序时可以扩展Exception类定义自己的异常类,然后根据程序的需要来规定哪些方法产生这样的异常。
- 一个方法在声明时可以使用throws关键字声明要产生的若干个异常,并在该方法的方法体中具体给出产生异常的操作。
例如:
断言
- 断言语句在调试代码阶段非常有用,断言语句一般用于程序不准备通过捕获异常来处理的错误。当发生某个错误时,要求程序必须立刻停止执行。
- 断言语句的语法格式
// 使用关键字assert声明断言语句
assert booleanExpression;
assert booleanExpression:messageException;
例如:
目前,Java基础部分的笔记就记录到这里,笔记基于的教材是《Java2使用教程》(第5版),部分内容记录可能不够全面,还有知识点遗漏的地方。算是我自己学习Java的一个预习笔记吧,后续在Java的学习中,我依然会整体笔记发布出来,希望对你有所帮助。