Java 语言的最大特点是使用面向对象的思想进行设计和编码。
类简介
在面向对象的语言中,大多使用class来表示一种新类型,Java 也采用了该关键字。
在类中可设置两种类型的元素:字段(也称为数据成员)和方法(也称为函数成员)。
字段
基本数据类型字段和引用类型字段
基本数据类型就是值类型数据
类型字段和实例字段
类型字段:字段属于类型
实例字段:字段属于类型实例
final 字段和非 final 字段
final字段表示常量字段,其值一旦设置后不能更改。
static 字段 和非 static 字段
static字段为类字段,非static字段为实例字段
方法
传值和传引用
特别说下final参数。
final参数可类比C#的out参数或ref参数,但作用稍不同。final参数的语义是不可在方法体中修改参数。对于基本类型,表示该基本类型不可被重新赋值;对于引用类型,表示不能更改参数引用所指向的对象。
类方法和实例方法
static 方法和普通方法。
final 方法和非 final 方法
final方法表示不可继承方法,所有的私有方法都是final方法。
重载
函数签名:不包括返回值
可变参方法
static void params(Object...args) {for(Object obj: args) {System.out.println(obj + " ");}}
使用数据类型 + … + 参数名的方法表示可变参数。
static 关键字
static 关键字(和C#一致):静态类、静态成员(静态字段、静态方法)
静态导包
static关键字可以修饰import导入的包,表示默认引用导入包的所有静态数据。
静态类
静态字段
静态方法
final 关键字
final关键字用来说明这是一个常量(constant)。
可能使用final关键字的三种情况:数据、方法和类。
final数据
一个永不改变的编译时常量。
final可以修饰非引用和引用。
一个在运行时被初始化,且不会改变的数据。(运行时赋值一次)
static final则表示类常量,在加载类时,已完成初始化。
未初始化final
也称“空白final”。空白final是指被声明为final但又未给定初值的字段。
编译器需确保空白final在使用前必须被初始化。
final参数
无法更改参数引用所指向的对象。
final方法(方法不可覆盖)
设计:将方法锁定,防止继承类修改它的含义。(不可覆盖)
性能:提高效率。将方法在编译期转化为内嵌方法。(效率不高,不再作为特性)
所有private方法都隐式指定为final。
final方法并没有控制方法的访问权限,只是保证该方法不可被子类覆盖。
如可以使用public权限控制final方法的访问权限。示例代码如下:
public class Main {public final void test1(){System.out.println("test1");}protected final void test2(){System.out.println("test2");}private final void test3(){System.out.println("test3");}}
final类
不希望继承的类。因不可继承,所以其方法均为final。(不可覆盖)
final优化(避免final滥用)
使用ArrayList替换 Vector(过多使用final)
使用HashMap替换 Hashtable(过少使用final)
初始化和清理(构造器)
在C程序编码时,很多错误都是由于程序员忘记初始化变量和占用内存回收造成。
C++和Java引入构造器,确保每个对象都能初始化。并通过垃圾回收机制,确保对象的清理。
在Java中,“初始化”和“创建”捆绑在一起,两者不能分离。
构造器
Java中使用构造器确保初始化。
成员默认值和初始化
默认值:局部变量必须初始化、类的成员变量会设置默认值。
初始化方式:指定初始化、构造函数初始化
指定初始化
直接为变量设置初值使用方法为变量设置初值构造函数初始化(较常用)
构造函数中成员初始化原则:
静态成员未初始化时,会设置默认初始值
先静态对象后非静态对象
先字段、再初始化块,再构造函数、再其他方法
this 关键字
this 逃逸清理:终结处理和垃圾回收
finalize()方法
作用一:作为垃圾回收机制的补充,释放不基于new方法创建的对象占用的内存空间(如本地方法调用C或C++分配的内存空间)
作用二:执行垃圾回收之外的清理工作如关闭文件句柄)。
访问控制
Java提供访问权限修饰符,以供类库开发人员向客户端程序员指明成员的可用或不可用。
package
在使用Java的类之前,面对的一个问题是如何将第三方开发的类绑定到一个当前类中。Java引入package的概念,用于将这组类限定在指定名称空间。类似的,在C#中引入namespace。访问控制修饰符的作用会因在相同包或单独包中,而受到影响。
个人理解:1. 单一类过于独立,需要使用一个逻辑概念,将实现某一特定功能的关联类整合起来,这时引入了package;2. 使用package后,还可将类的import和export职责,分离到package上。
package(包)内包含一组类,它们在单一的名字空间之下被组织在一起。(类比C#的namespace),包的命名是全小写,使用点号分隔。
创造独一无二的包名
将所有文件收入一个子目录,然后定义一个独一无二的目录名(如Internet域名)。
使用ClassPath指定.class文件所在路径,或jar包的存储位置(c:\access\java\grape.jar)
包访问权限
默认访问权限。处于同一个包内的所有成员可自动访问,但对包外的所有类,这些成员都是private。
public
private
protected
类访问权限
外部类的访问权限只能是public和包访问权限。private和protected类不能被外部访问。如果这个类是一个内部类(成员类),则四种访问修饰符都能使用。
封装
访问权限的控制常被称为具体实现的隐藏。把数据和方法包装进类中,以及具体实现的隐藏,常共同被称为封装。
封装的两个方面:封装数据和方法(定义类)、控制访问权限(添加访问修饰符)。
复用(继承/组合/代理)
组合
将对象引用置于新类中。(在新类中产生现有类的对象或使用现有类的静态方法)
编译器不会为每个引用都创建默认对象。必须手动初始化这些引用。
继承(单根继承)
按照现有类来创建新类。
代理
将一个对象置于所要构造的类中(类比组合),但同时在新类中暴露该成员对象的所有方法(类比继承)。可见,代理是组合+手动继承。
继承与组合的选用
多用组合,少用继承。仅在必须进行向上转型时,才使用继承。
组合技术通常用于需要使用现有类的功能而非它的接口的情况。
继承继承则用于需要使用现有类的接口的情况。
多态(后期绑定/动态绑定/运行时绑定):可扩展性
(策略模式)
通过动态绑定实现多态,实现在调用父类方法时,表现出子类的特性。
引用类型转换
向上转型
绑定
将一个方法调用同一个方法体关联起来称为绑定。根据绑定发生的时间,将其分为前期绑定和后期绑定。
前期绑定
在程序执行前进行绑定。C语言只有一种方法调用,即前期绑定。
后期绑定(动态绑定/运行时绑定)
在运行时根据对象的类型进行绑定。Java中除了static方法和final方法(private方法是final方法的一种),其他所有方法都是后期绑定。
构造器与多态
尽量不要在构造器中使用后期绑定的方法,以避免多态带来的不确定性。
协变返回类型(多态的扩展)
优化策略
多用组合,少用继承
继承(is-a)与扩展(is-like-a)
接口
接口与工厂
内部类
使用内部类可以实现真正意义上的多重继承。
内部类实现了闭包,可以替代指针实现callback操作。
内部类是将一个类的定义放在另一个类的内部。
内部类可以:1.隐藏代码实现细节;2.获取外部类的访问权限
内部类实现延迟加载。
内部类与迭代器模式
使用内部类实现一个迭代器
局部内部类
在方法体中定义内部类。
匿名类
嵌套类
嵌套类特指声明为static的内部类(静态内部类)。
嵌套类仅能访问外部类的静态成员。
C#中嵌套类对应Java的非static的内部类。
原创不易,如果本文对您有帮助,欢迎关注我,谢谢 ~_~