Java基础系列第一章 初识Java语言
Java基础系列第二章 Java语言基础
Java基础系列第三章 Java流程控制
Java基础系列第四章 Java数组与字符串
Java基础系列第五章 面向对象程序设计
Java基础系列第六章 Java异常处理
Java基础系列第七章 IO流
Java基础系列第八章 集合框架
Java基础系列第九章 线程
Java基础系列第十章 注解、泛型、反射和序列化
Java基础系列第十一章 JDBC技术
Java基础系列第十二章 Java网络编程
基本概念
面向对象程序设计(OOP)是当前主流的程序设计方法,通常具有封装、继承、多态着三大特性。其着中于对象的分解与相互作用,重点强调程序代码的可读性、可重复使用性、扩展性。
在现实生活中任何动物或事物都可当作一个对象,如需描述这个动物或事物,通常有两种方式:一是描述他的内部状态,二是描述他的外部行为。在程序中也可用状态和行为来描述,分别称为属性和方法。
对象抽象化,即使用程序记录对象的属性、方法和事件,其说明如下:
- 属性:指对象的静态外观描述或者对抽象的内在描述。类似Java中类的成员数据。
- 方法:指对象中的动态响应方式。是一种行为模式,代表一个对象的功能,类似Java中类的成员方法。
- 事件:对象可对外部事件做出的响应,对象也可主动发出事件消息。如Java中窗口组件可对事件做出响应与处理。
类与对象
类与对象基本概念
- 类:对某一类事物的描述,是抽象的、概念上的定义。类由数据成员(也称为属性、域变量、成员变量等)和函数成员(类的行为,也称方法)封装而成,类描述了对象的属性及行为。
- 对象:实际存在的属于该类事物的具体个体,因此也称实例。因一个对象由一组属性和对这组属性操作的方法构成,所以对象是属性和操作的封装体。
类的定义
定义类的一般结构,由成员变量和成员方法构成:
[类修饰符] class 类名称{
[修饰符] 变量类型 成员变量名; //可1个或多个
[修饰符] 返回值类型 方法名(参数类型 参数名, …){ //方法可1个或多个,参数可0或多个
语句块;
return 返回值类型一致的值;}}
类修饰符及含义
修饰符 | 含义 |
---|---|
public | 将一个类声明为公共类,它可以被任何对象访问 |
abstract | 将一个类声明为抽象类,没有实现方法,需要子类提供方法的实现,所以不能创建该类的实例 |
final | 将一个类声明为最终类 即 非继承类,表示它不能被其他类所继承 |
缺省 | 缺省修饰符时,则表示只有在相同包中的对象才能使用这个类 |
成员变量修饰符及含义
修饰符 | 含义 |
---|---|
public | 公共访问控制符。指定该变量为公共的,它可以被任何对象的方法访问 |
private | 私有访问控制符。指定该变量只允许自己类的方法访问,其他类(包含子类)都不能访问 |
protected | 保护访问控制符。指定该变量只可以被它自己的类及其子类或同一包中其他类访问,在子类可以覆盖此变量 |
缺省 | 缺省访问修饰符。指定该变量在同一包中其他类可以访问,而其他包中的类不能访问 |
final | 最终修饰符。指定此变量的值不能改变 |
static | 静态修饰符。指定该变量被所以对象共享 |
transient | 过渡修饰符。指定该变量是一个系统保留、暂无特别作用的临时性变量 |
volatile | 易失修饰符。指定该变量可同时被几个线程控制和修改 |
成员方法修饰符及含义
修饰符 | 含义 |
---|---|
public | 公共访问控制符。指定该方法为公共的,它可以被任何对象的方法访问 |
private | 私有访问控制符。指定该方法只允许自己类的方法访问,其他类(包含子类)都不能访问 |
protected | 保护访问控制符。指定该方法只可以被它自己的类及其子类或同一包中其他类访问 |
缺省 | 缺省访问修饰符。指定该方法在同一包中其他类可以访问,而其他包中的类不能访问 |
final | 最终修饰符。指定此方法不能被覆盖 |
static | 静态修饰符。指定不需要实例化一个对象就可以调用的方法 |
abstract | 抽象修饰符。指定该方法只声明方法头,而没有方法体,抽象方法需在子类被实现 |
synchronized | 同步修饰符。在多线程中,该修饰符用于对同步资源加锁,以防止其他线程访问,运行结束后解锁 |
native | 本地修饰符。指定该方法的方法体是用其他语言(如C++)在程序外部编写的 |
成员变量与局部变量区别
- 类中定义的变量是成员变量,方法中定义的变量或方法的参数是局部变量
- 从语法上:成员变量属于类,局部变量属于方法。成员变量可以用public、private等修饰符修饰,局部变量不能。成员变量和局部变量都可被final修饰。
- 从存储上:成员变量属于对象,存在于堆内存中,局部变量属于方法,存在于栈内存中。
- 从初值上:成员变量如果没赋初值,则自动一类型的默认初值赋值(被final修饰但没static修饰的成员变量须显示的赋值),局部变量不会自动赋初值,必须显示的赋值。
对象的创建与使用
对象的生命周期是:创建>使用>销毁。创建对象需:声明指向"由类所创建的对象"的变量,利用new运算符创建新的对象并指向变量。创建对象也叫实例化对象,如下:
类名 对象名 = new 类名();
对象的使用:创建对象后,即可对对象的成员进行访问。
对象名.成员变量
对象名.方法(); // 有参数则在()中添加参数即可,无参数则不填
对象名.方法(参数类型 参数名); // 参数类型可以是数值型、字符串、数组、对象等
对象名.方法(固定参数列表, 数据类型 … 可变参数名); // Java 5后提供可变参数,当参数个数不固定时可用。说明:可变参数必须位于最后一项,可变参数符号"…"需位于数据类型和名称之间,调用时编译器为可变参数隐式创建一个数组在方法体中以数组形式访问可变参数
匿名对象:创建对象时,可不定义对象的名称直接使用对象的方法。匿名对象只在堆内存中开辟空间。
new 类名().方法(); // 当只需进行一次方法调用时可用
方法(new 类名()); // 将匿名对象作为参数使用
类的特性
构造方法
实例化时(创建对象),首先为对象分配内存,执行该类的构造方法,然后返回该对象的引用并将其赋给引用变量。类通过定义构造方法产生对象。构造方法是一种特殊的方法,其特殊性如下:
- 构造方法的方法名与类名相同。
- 构造方法没有返回值,但不需要void。
- 构造方法的主要作用是完成对类对象的初始化工作。
- 构造方法一般不能直接调用,需用new运算符进行调用。
- 在创建一个对象的同时,系统会自动调用类的构造方法进行对象初始化。
- 类中如果没有构造方法,Java编译器会自动为该类生成一个默认的构造方法。
重载:方法与方法之间名称相同,参数个数不同或参数类型不同。因为构造方法名称与类名一致,因此一个类中有多个构造方法,这些方法都是构造方法的重载。
this():同一类中从一个构造方法调用另一个构造方法,必须使用this()语句进行调用。this()语句必须写在构造方法第一行位置。this通常指当前对象。
封装
类的封装指属性的封装和方法的封装。其特点是:信息隐藏、保护对象内部数据。
属性封装:private 属性类型 属性名称;
方法封装:private 方法返回值 方法名称(参数列表){}
只要是被封装的属性,就必须通过set和get方法设置和获取。开发中,类的属性必须封装。
继承
继承允许代码的重复使用,可表达树形结构中父代与子代的遗传现象。在继承关系中,被继承者称为"基类"或"父类",继承者称为"派生类"或"子类"。继承允许定义一个新类来继承现有的类,使用或更改继承过来的方法,并可在子类中新增属性或方法。
继承的语法:
权限修饰符 class 子类类名 extends 父类类名{}
继承的特性:
- 子类继承父类所有属性和方法,且可新增属性和方法。
- 子类不继承父类的构造方法。
- 子类不继承父类使用private修饰的成员变量和方法。
- 子类的变量或者方法与父类同名,则不能继承父类该变量或方法。
重写:发生在继承关系中。父类与子类方法同名,返回值类型相同,参数类型、参数个数、参数顺序相同。子类方法权限需大于父类,子类方法抛出异常与父类一致,子类不能重写父类声明的以final或static修饰的方法,子类必须重写父类声明的抽象方法或接口。
super:super关键字表示当前超类的对象。super关键字必须写在子类构造方法第一行位置。super表示从子类构造方法调用父类构造方法或从子类调用父类变量。this通常指父类对象。
多态
多态:指编写程序时定义同名方法但能实现不同的功能,即"同名异式"。在Java中分静态多态和动态多态。
- 静态多态:指在编译期间就决定的多态,如重载。
- 动态多态:指在执行期间才能确定的多态,如重写。
抽象类 & 接口
抽象类
类和类之间具有共同特征,抽象类就是将这些共同特征提取出来。用abstract修饰类称为抽象类。抽象类包含抽象方法的类。其特点如下:
- 抽象类属于引用数据类型。
- 类本身是不存在的,所以抽象类无法创建对象、无法实例化,抽象类是用来被子类继承的,子类继承后子类可以实例化。
- final和abstract不能一起用(final不能被继承,abstract只能被继承)。
- 抽象类的子类也可以是抽象类。
- 抽象类中的构造方法是供子类使用的。
- 用abstract修饰的方法称为抽象方法,抽象方法没有方法体。
- 抽象类中不一定有抽象方法,但抽象方法只存在于抽象类中。
- 一个非抽象类继承抽象类,必须把抽象类中的抽象方法实现/重写/覆盖。
- 父类型A引用指向子类型B对象(向上转型)—面向抽象编程(降低程序的耦合性,提高程序的扩展力),编程思想符合ocp原则。
A a = new B(); a.a中的方法:编译时执行A的方法,运行时执行B的方法(也称多态)
接口
由常量和公共的抽象方法组成。也可以理解为更纯粹的抽象类。其特点如下:
- 接口也是一种引用数据类型。
- 接口是完全抽象的(抽象类是半抽象的),或者说接口是特殊的抽象类。
- interface定义接口,写法[修饰符类型] interface 接口名{}。
- 接口支持继承,并支持多继承(接口和接口之间)。
- 接口中只包含常量和抽象方法。
- 接口中所有修饰符都是public。
- 接口中的抽象方法修饰符public 和 adstract可以省略,接口中的方法没有方法体。
- 接口中的常量修饰符public static final可以省略。
- 类与类之间叫继承,类与接口之间叫实现,继承用extends,实现用implements。
- 当一个非抽象类实现了一个接口时,必须将接口中的所有抽象方法实现/覆盖/重写。
- 一个类可以同时实现多个接口,类与类之间只能单继承。
- 接口之间有无继承都可进行强制类型转换,但可能会出现ClassCastException异常。
- 无论向上转型还是向下转型,两种类型之间必须要有继承关系(此不适用接口),向下转型先用if+instanceof进行判断。
修饰符 interface 接口名{
常量声明;
方法声明;
}
接口在开发中的作用:解耦合。类似于多态在开发中的作用。多态是面向抽象编程,即面向接口编程,降低程序的耦合性,提高程序的扩展力,符合ocp原则。调用者面向接口调用,实现者面向接口编写实现。
接口与抽象类的区别
1、抽象类是半抽象的 —— 接口是完全抽象的。
2、抽象类中有构造方法 —— 接口中没有构造方法。
3、类与类之间只能支持单继承 —— 接口与接口之间可以实现多继承。
4、一个抽象类同时只能继承一个类(单继承) —— 一个类可以同时实现多个接口。
5、接口中只允许出现常量和抽象方法。
枚举 & 程序包 & 嵌套类
枚举
枚举:当一个变量有多个固定取值时,可将其声明为枚举类型。枚举是一种特殊的类,也称枚举类,属于引用类型。
枚举声明如下:
修饰符 enum 枚举类名{
枚举成员
方法
}
修饰符:可以为public、private、internal。
枚举名:作为枚举名使用或者表示枚举成员的数据类型。
枚举成员:可列出的枚举常量,也叫枚举常量或枚举值。
枚举类与普通类的区别:
- 枚举类可实现一个或多个接口,使用enum关键字默认继承java.long.Enum类,枚举不能继承其他父类。
- 使用enum定义非抽象的枚举类时默认使用final修饰,因此枚举类不能派生子类。
- 枚举类实例化不能使用new运算符,应直接将枚举值赋值给枚举对象。
- 因为枚举类是类,因此可有构造方法和其他方法。但构造方法只能用private修饰。
- 枚举的所有枚举值必须在枚举体的第一行列出,否则枚举不能产生枚举值。枚举值默认使用 public static final修饰。
程序包
程序包:将程序中所有相关的类、接口或方法汇总整合并打包,也叫函数库。每个包对应一个文件夹,包中还可以再有包,称为包等级。同一包中类名不能重复,不同包中类名可以相同。
使用package语句创建包:
package 包名1.包名2.包名3…;
经过package声明后,在同一文件内所有类、接口或方法都被纳入相同包中。
package与import机制:
- package是Java程序中的包机制,方便程序的管理,不同功能的类放在不同的包下。
- package是一个关键字,后面跟包名,只出现在Java源代码的第一行。
- package规范,一般采用公司域名的倒序(公司域名有唯一性):公司域名倒序+项目名+模块名+功能名。
- import将需要的包引入,写在package下class上,可以使用*,代表某个目录下所有的包。
- java.lang.*下的包不需要import引入,同一包下也不需要引入。
Java常用包:
- java.lang:语言包。
- java.io:输入输出流的文件包。
- java.util:实用工具包。
- java.net:网络功能包。
- java.sql:数据库连接包。
- java.text:文本包。
嵌套类
嵌套类:在Java类的声明中可包含其他类声明的成员。嵌套类分为两种:静态嵌套类和非静态嵌套类。
内部类:将某类直接定义为另一个类的非静态内部成员。
内部类结构:
class 主类名{
主类语句;
class 内部类名{
内部类语句;
}}
由于内部类属于主类,因此可以直接存取对象的实例变量和方法,内部类中不能包含任何静态成员。
静态嵌套类:不同于内部类,其并不依赖主类创建的对象,静态嵌套类直接附属于主类。
静态嵌套类结构:
class 主类名{
主类语句;
static class 静态嵌套类名{
静态嵌套类语句;
}}
由于静态嵌套类不依赖主类,因此不可以直接存取对象的实例变量和方法,只能通过对象来间接存取或调用类的实例成员。
匿名类:不具有类名,可直接调用基类或接口的构造函数来创建派生类对象的类。
匿名类结构:
基类(或接口) 匿名对象 = new 基类(或接口)构造函数(){
匿名类成员的程序语句;
}
匿名类可继承其他类或接口,但一般只用于实现一个接口或继承一个特定的类。