Java 是个纯面向对象语言,不支持过程式编程,所有操作都是基于对象。
一、类
类是 Java 中的一种引用数据类型,引用数据类型值都存储在堆中。类是构造对象的模板,每个类对象都是类通过 new 语句创建的。通过关键字 class 定义一个类,类的结构:
类名(ClassName)通常首字母大写,多个单词用驼峰式(CamelCase)命名法。一个类可以定义多个属性,多个构造函数,多个行为方法。类和类中定义的属性方法都需要有访问权限控制,不受限的访问将会导致程序混乱,不可控制。下面是 Java 语言中定义的修饰符,如下(继承类也叫子类):
说明:
friendly:缺省值,没有修饰词。当 friendly 修饰类时,可以被本包中的类继承;当修饰方法时,继承类不能访问。
public:公共的,所有类都能访问。
protected:受保护的,同包中本类和继承类可以访问,继承类访问的是其继承过来的方法,不能访问基类的 protected 方法。不同包中继承类不可见。
private:私有的,只有本类可以访问。
其它修饰词很好理解,这里看下 protected 的示例:
package p1;public class Base{protected void test(){}}---------------------------package p1;public class Son1 extends Base{}---------------------------package p11;import p1.Base;public class Son11 extends Base{}---------------------------// 测试package p1;import p11.Son11;public class Main{public static void main(String[] args){Son1 s1 = new Son1();Son11 s11 = new Son11();s1.test();s11.test();s1.clone(); // 报错,不能访问 Base 类中的 protected 方法s11.clone(); // 报错,不能访问 Base 类中的 protected 方法}}---------------------------package p11;import p1.Son1;public class Main{public static void main(String[] args){Son1 s1 = new Son1();Son11 s11 = new Son11();s1.test(); // 报错,不在同一包中,不能访问 protected 方法。下同s11.test(); // 报错s1.clone(); // 报错s11.clone(); // 报错}}
除了访问控制修饰符,Java 还定义了一些非访问控制修饰符:
说明:
static:静态方法属于类,不需要构造对象访问。
静态变量:也称类变量,无论实例化多个是个对象,静态变量只有一份数据,所以当静态变量值改变后,所有对象实例访问该静态变量都是新值。
静态方法:方法中不能访问非静态变量。main 方法也是一个静态方法,不对任何对象进行操作。每个类可以有一个 main 方法,这样可以对类进行单元测试。
final:表示最终状态。final 类不能被继承。final 方法可以被继承,但是不能被子类修改。final 属性不能被修改,所以必须显式的赋初始值,final 通常和 static 一起使用来定义常量。
abstract:抽象类不能用来实例化,抽象类只是对一些公用行为进行抽象,等待继承类进行扩充。抽象类可以包含非抽象方法,含有抽象方法的类必须声明为抽象类,抽象方法必须在字类中完善。abstract 不能和 static、final 同时使用。
synchronized:修饰的方法同一时间只能被一个线程访问。
transient:当对象被序列化时会跳过 transient 修饰的属性,一些敏感信息就不会被序列化,这样当对象被反序列化后,transient 修饰的属性就不会被读取到,信息更加安全。
volatile:每次线程访问时,都重新从共享内存中读取值,这样每次读取被 valatile 修饰的变量值都是最新的。
二、构造函数/方法
Java 规定与类同名(区分大小写)的方法就是该类的构造方法。一个类可以定义多个构造函数,只要保证方法签名不同即可。方法签名指包括方法修饰符、方法名称和方法入参在内的所有元素(不包括方法返回值),只要有一项不同则方法签名就不同。如果类没有定义构造函数,则系统会默认分配一个构造函数,属性值被设置成默认值。构造函数具有以下特点:
1) 构造函数必须与类名相同。2) 构造函数没有返回类型,也不能设置 void 返回类型。构造函数用于构建对象,所以不需要返回值。3) 构造函数的修饰词必须是 public。4) 一个类可以定义多个构造函数,只要构造函数签名不同即可。
定义一个 Person 类,多个构造函数:
这里构造器定义了多个,每个构造方法的入参不同。相同的方法名,不同的参数称为方法重载。给成员变量赋值时可以通过 this 关键字访问。
如果提供了多个构造器,那么在一个构造其中可以通过 this 访问另一个构造器,如:
初始化块(initializationblock),由 {} 包括的代码块,还可以通过 static 关键字修饰为静态初始化块,块代码可以有多个。创建对象时会先执行静态初始化块中代码,再执行初始化块中的代码,最后执行构造方法。如:
Java 有自动垃圾回收器,不需要人工释放内存, 所以 Java 没有析构方法。对象资源需要被释放时可以定义 close 方法,来手动是否资源,close 方法被调用后对象关联的资源会被回收。
三、类设计技巧
类的设计通常应该遵循以下一些技巧:
1. 保证数据私有,避免破坏封装性,导致数据被乱改。
2. 一定要对数据进行初始化 。
3. 不是所有的域都需要独立的域访问器和域更改器。
4. 将职责过多的类进行分解。
5. 类名和方法名要能够体现它们的职责。
6. 优先使用不可变的类。