3. 定义一个类
一、访问控制符
1. 3个访问控制符 & 4个访问控制级别
①Java提供了3个访问控制符:private、protected、public
②上列3个访问控制符分别代表了3个访问控制级别,还有1个不加任何访问控制符(以default表示)的访问控制级别,即一共4个访问控制级别
- private(当前类访问权限):如果一个成员使用private修饰,则这个成员只能在当前类的内部被访问
- default(包访问权限):如果一个成员或一个外部类不使用任何访问控制符修饰,则这个成员或外部类可以被相同包下的其他类访问
- protected(子类访问权限):如果一个成员使用protected修饰,则这个成员既可以被相同包下的其他类访问,也可以被不同包中的子类访问
- public(公共访问权限):如果一个成员或一个外部类使用public修饰,则这个成员或外部类可以被所有类访问
private | default | protected | public | |
同一个类中 | √ | √ | √ | √ |
同一个包中 | √ | √ | √ | |
子类中 | √ | √ | ||
全局范围内 | √ |
2. 使用访问控制符的基本原则
- 外部类通常都希望被其他类自由使用,所以大部分外部类都使用public修饰。
- 类里的绝大部分成员变量都应该使用private修饰;只有一些static修饰的、类似全局变量的成员变量可能考虑使用public修饰。
- 希望暴露出来给其他类自由调用的方法应该使用public修饰;只用于辅助实现该类的其他方法称为工具方法,工具方法应该使用private修饰;如果某个类主要用作其他类的父类,且该类中包含的大部分方法可能仅希望被其子类重写,而不想被外界直接调用,则应该使用protected修饰。
二、定义一个类
/* * 示例:定义一个类 */ [修饰符] class 类名 { // 成员1:零个到多个构造器定义 [修饰符] 构造器名(形参列表) { // ... } // 成员2:零个到多个成员变量 [修饰符] 类型 成员变量名 [= 默认值]; // 成员3:零个到多个方法 [修饰符] 方法返回值类型 方法名(形参列表) { // ... } // 成员4:零个到多个初始化块 [修饰符] { // ... } }
1. 外部类的修饰符:{public, final | abstract, 省略}
①外部类不处于任何类的内部,所以protected和private对外部类没有意义,也就不能使用private和protected修饰
②外部类通常都希望被其他类自由使用,所以大部分外部类都使用public修饰
- public:可以被所有类访问
- default:只能被同一个包中的其他类访问
③final修饰的类不可被继承,所以若某个类不想被继承,则可以使用final修饰该类
2. 构造器的修饰符:{public | protected | private, 省略}
①由于构造器主要用于被其他方法调用(以返回该类的实例),所以通常把构造器设置成public访问权限,除非在一些极端的情况下,业务需要限制创建该类的对象
- public:允许系统中任何位置的类来创建该类的对象
- protected:被其子类调用
- private:阻止其他类创建该类的实例
3. 成员变量的修饰符:{public | protected | private, static, final, 省略}
①final修饰的成员变量一旦获得初始值,便不能被重新赋值
4. 方法的修饰符:{public | protected | private, static, final | abstract, 省略}
①final修饰的方法不可被重写
5. 初始化块的修饰符:{static, 省略}
①使用static修饰的初始化块被称为静态初始化块,用于初始化类
补充:内部类的修饰符:{public | protected | private, static, final | abstract, 省略}
三、类的成员剖析
1. 构造器
①作用:在创建对象时执行初始化
②构造器名必须和类名相同,且没有返回值类型
③如果程序员没有为Java类提供构造器,则系统会为该类提供一个无参数的构造器,其执行体为空
④一旦程序员提供了自定义的构造器,系统就不再提供默认的构造器
补:其实在构造器执行之前,系统已经创建了一个对象(包含为该对象分配内存空间、为该对象执行默认初始化),只是这个对象还不能被外部程序访问,只能在该构造器中通过this来引用。
2. 成员变量
①作用:描述类或对象包含的状态数据
②成员变量分为类变量和实例变量,定义成员变量时有static修饰的就是类变量
③类变量从该类的准备阶段起开始存在,直到系统完全销毁这个类,其作用域与这个类的生存范围相同
④实例变量从该类的实例被创建起开始存在,直到系统完全销毁这个实例,其作用域与对应实例的生存范围相同
⑤成员变量无须显式初始化,对于类中定义的类变量或实例变量,系统会在该类的准备阶段或创建该类的实例时进行默认初始化,成员变量默认初始化时的赋值规则与数组动态初始化时数组元素的赋值规则完全相同
补1:只有程序员没有显式初始化成员变量时,系统才会进行默认初始化,如果程序中已经为成员变量指定了初始值(包括定义成员变量时指定默认值,在初始化块、构造器中指定初始值),系统就不会进行默认初始化。
补2:成员变量是随类初始化或对象初始化而初始化的。当类初始化时,系统会为该类的类变量分配内存,并分配默认值;当创建对象时,系统会为该对象的实例变量分配内存,并分配默认值。也就是说,当执行静态初始化块时可以对类变量赋初始值;当执行普通初始化块、构造器时可对实例变量赋初始值。因此,成员变量的初始值可以在定义该变量时指定默认值,也可以在初始化块、构造器中指定初始值。
补3:系统不会对局部变量进行默认初始化,局部变量必须由程序员显式初始化。
3. 方法
①作用:描述该类或该类的实例的行为特征或功能实现
②方法分为静态方法和普通方法,定义方法时有static修饰的就是静态方法
③使用static修饰的方法属于该类,否则方法属于该类的实例
④同一个类中的一个方法调用另一个方法时,如果被调用的方法是普通方法,则默认使用this作为调用者
⑤同一个类中的一个方法调用另一个方法时,如果被调用的方法是静态方法,则默认使用类作为调用者
4. 初始化块
①作用:对类或类对象进行初始化
②没有名字,使用static修饰的初始化块被称为静态初始化块
③一个类中可以有多个初始化块,相同类型的初始化块按定义的次序先后执行
④(普通)初始化块在创建类对象时隐式执行,而且它们在执行构造器之前执行
⑤静态初始化块在类初始化阶段隐式执行,通常用于对类变量执行初始化处理
⑥(普通)初始化块和声明实例变量时指定的默认值都是类对象的初始化代码,它们的执行顺序与源程序中的排列顺序相同
⑦静态初始化块和声明类变量时指定的初始值都是该类的初始化代码,它们的执行顺序与源程序中的排列顺序相同
四、Java的命名规则
类名:由一个或多个有意义的单词连缀而成,每个单词首字母大写,其他字母全部小写,单词与单词之间不使用分隔符
变量名:由一个或多个有意义的单词连缀而成,第一个单词首字母小写,后面每个单词首字母大写,其他字母全部小写,单词与单词之间不使用分隔符
方法名:与变量名命名规则相同,但建议以英文动词开头