三个修饰符
一、抽象(abstract)
-
抽象的意义:
- 抽象符合面向对象的思想:不存在的事物不应该被实例化(创建对象)
- 被子类继承:这些共性一定会被子类独特的实现所覆盖
- 使用多态:通过对父类的声明,批量管理子类对象
-
抽象的语法
-
abstract修饰类:
-
语法:访问修饰符 abstract class 类名
public abstract class TestAbstract{} abstract class TestAbstract2{}
-
特点:
- 抽象类无法直接创建对象(不可以使用new语句创建对象)
- 抽象类可以声明引用(多态的语法形式)
- 抽象类具有构造方法,但是无法被手动调用
- 抽象类具有对象,其对象无法独立存在,其作用是作为子类对象的基础
-
-
abstract修饰成员方法:
-
语法:访问修饰符 abstract 返回值类型 方法名 (形参列表);
public abstract void method(int a);
-
特点:
- 抽象方法只有声明,没有实现
- 抽象方法存在的意义在于被子类覆盖
-
-
抽象方法与抽象类之间的关系
- 如果一个类中有抽象方法,那么这个类必须声明为抽象类
- 抽象类中不一定具有抽象方法,抽象类中可以没有抽象方法
- 如果子类继承一个抽象类,并且该子类不想成为抽象类,那么必须覆盖父类中的所有抽象方法
-
abstract不能修饰构造方法
-
二、静态(static)
-
修饰符static可以修饰成员变量,成员方法,初始化代码块
-
修饰成员变量:
-
语法:访问修饰符 static 数据类型 变量名
class TestStatic{ public static int age = 10; }
-
特点:
-
被static修饰的成员变量又称为静态变量或者类变量
-
静态变量全类共享,与对象无关
-
静态变量可以使用类名直接访问
public class Test { public static void main(String[] args) { Animal a = new Animal(); int age1 = a.age;//可以通过对象访问 int age2 = Animal.age;//也可以通过类名访问 } } class Animal{ public static int age = 10; }
-
任何对静态变量的改变都将使其发生永久的改变,之后的访问都将访问其改变之后的结果
-
-
-
修饰成员方法:
-
语法:访问修饰符 static 返回值类型 方法名(形参列表){}
class Animal{ public static void method(){ } }
-
特点:
- 静态方法只与该类有关,与类的对象无关
- 静态方法中只能访问本类中的其他静态成员(静态变量,静态方法)
- 静态方法可以使用类名直接访问
- 静态方法中无法使用this.和super.
- 静态方法只能被静态方法覆盖,并且覆盖之后没有多态
-
-
类加载:
-
静态成员特点的成因:
- 其在内存中存在的区域不是在堆中,所以与对象无关
- 其初始化的时机优先于对象的创建,所以只能访问静态资源
-
初始化的时机:类加载
-
类加载:当虚拟机第一次使用某个类,尝试去读取该类信息的过程
-
从哪加载:硬盘
-
如何确定位置:classpath环境变量
-
加载哪些信息:所有信息(包,父类,属性,方法等)
-
加载几次:原则上只加载一次
-
何时加载:当使用某个类的时候加载
-
何时使用:
-
当访问该类的静态资源的时候
-
当创建该类对象的时候(创建该类自身的对象或者创建该类子类的对象)
-
主动类加载
Class.forName("包名.类名");
-
-
-
仅声明引用不会引起类加载
-
-
修饰初始化代码块
-
初始化代码块:在类中成员位置使用{},该{}成为初始化代码块,也叫动态代码块
class Animal{ { System.out.println("动态初始化代码块"); } }
-
动态代码块的特点:
- 动态代码块仅在创建对象的时候才会执行,每个代码块只执行一次,代码块中的代码自上而下运行
- 每次创建对象都会执行一次
- 动态代码块的作用:为成员变量赋值
-
静态初始化代码块:被static修饰的初始化代码块称为静态代码块
class Animal { static { System.out.println("静态初始化代码块"); } }
-
静态代码块的特点:
- 静态代码块仅在类加载的时候执行一次,与创建多少对象无关,代码块中的代码自上而下运行
- 静态代码块在给静态变量赋值的时候,如果静态变量具有初始值,那么该变量存储值的结果取决于静态代码块和静态变量声明的顺序
- 静态成员初始化的时机在静态代码块之前
-
注意:代码块中声明的变量也是局部变量,可以与成员变量重名,作用域仅在代码块中
-
三、最终(final)
-
修饰符final可以修饰类、变量、成员方法
-
修饰属性:
特点:被final修饰的变量没有默认值,仅允许一次赋值,赋值后其中的值不可改变-
修饰局部变量:语法:final 数据类型 变量名
class Animal { public void method(){ final int a = 5; } }
-
修饰成员变量:语法:访问修饰符 final 数据类型 变量名
class Animal { public final int a = 5; }
-
被final修饰的成员变量必须在实例化的时候被赋值
-
赋值的时机可以是初始值,可以使用动态代码块赋值,也可以是构造参数值
class Animal { public final int a; { a = 5;//初始化代码赋值 } }
-
如果使用构造参数对其进行赋值,必须保证所有的构造方法都对其进行过赋值
class Animal { public final int a; //使用构造参数赋值,每个构造方法都要保证为其赋值 public Animal(){ a = 5; } public Animal(int a){ this.a = a; } }
-
-
修饰静态变量:语法:访问修饰符 static final 数据类型 变量名
class Animal { public static final int A = 5; }
-
被final修饰的静态变量必须在初始化的时候被赋值
-
赋值的时机可以是初始值,也可以是静态代码块赋值
class Animal { public static final int A; static{ A = 5;//静态代码块赋值 } }
-
-
关于值不可改变:
- 基本数据类型表现为字面值不可改变
- 引用/对象类型表现为其中存储的地址值不可改变,但是其中的内容可以改变
-
-
修饰成员方法
-
语法:访问修饰符 final 返回值类型 方法名(形参列表){}
class Animal { public final void method(){ System.out.println("final method"); } }
-
特点:
- 本类中可以重载该方法
- 继承关系中,子类可以继承该方法,但无法对其进行覆盖
-
-
修饰类
-
语法:访问修饰符 final class 类名{}
public final class Animal{ }
-
特点:无法被继承,即没有子类
-
四、修饰符之间的联用
- 多个修饰符之间没有顺序要求
- 修饰符之间需要保证语法通过
private | abstract | static | final | |
---|---|---|---|---|
private | ------- | error | ok | ok |
abstract | error | ------- | error | error |
static | ok | error | ------- | ok |
final | ok | error | ok | ------- |