三个修饰符
abstract—>抽象的
-
abstract可以修饰类
- 被abstract修饰的类称为抽象类—>abstract class 类名 { }
- 抽象类不能单独创建对象,但是可以声明引用—>抽象类类名 引用名;
- 抽象类中可以定义成员变量、成员方法
- 抽象类中有构造方法—>不写JVM会默认
- 抽象类中的构造方法是为创建子类对象时,JVM会默认创建一个父类对象时而用
-
abstract可以修饰成员方法:
- 被abstract修饰的方法称为抽象方法
- 抽象方法只有方法的声明部分,没有方法的实现部分({ }也不能有,并且以; 号结尾)
- 访问修饰符 abstract 返回值类型 方法名 ( 形参列表 ) ; —>abstract和访问修饰符没有位置的先后要求
- 抽象方法只能定义在抽象类中;抽象类既可以定义抽象方法,还可以定义非抽象方法。
-
抽象类可以被继承—>抽象类的子类
- 子类成为抽象类
- 如果子类不想成为抽象类,则必须覆盖 ( 并且实现 ) 父类所有的抽象方法
-
抽象类在应用层面上强制使用多态
-
通常将父类定义为抽象类,对一组对象的抽象概括总结
static—>静态的—>static修饰属性、方法、初始化代码块
-
static可以修饰属性
-
被static修饰的属性成为静态属性、静态变量、类变量。
-
不被static修饰的变量称为实例变量
-
访问修饰符 static 数据类型 变量名 ;
访问修饰符 static 数据类型 变量名 = 值 ; ---->访问修饰符和static没有位置先后要求
-
-
方法区---->静态属性存储的位置,像堆,栈一样,是个空间的名字
-
静态变量为类变量,和对象数量等没有关系,所有对象共享同一个静态属性
---->只有静态属性可以通过类名直接访问---->类名 . 静态属性名—>对象名 . 静态属性名也可以访问
-
static可以修饰成员方法
-
被static修饰的成员方法称为静态方法—>访问修饰符 static 返回值类型 方法名 ( 形参列表 ) { }
访问修饰符和 static 没有位置的先后要求,但要写在返回值类型的前边
----->类名 . 静态方法名 ( 实参 ) ; ( 建议使用 ) ------->对象名.静态方法名 ( 实参 )
-
-
static使用—>使用静态方法不看***对象***
- 静态属性和静态方法可以通过类名来调用,无需对象。但是非静态需要有对象才能调用,故静态方法不能访问本类的非静态成员(实例成员)
- 静态方法中只能直接访问本类的静态成员(静态属性和静态方法)
- 非静态方法中即可以访问本类的实例成员,也可以访问本类的静态成员
- 静态方法中不能使用this----->this指当前对象,static与对象无关。super同理,父类的也没有意义
- 静态方法能被子类继承 ; ---->静态方法只能被静态方法覆盖—>没有多态的应用 ( 因为与对象无关 )
-
static修饰属性范例:
java.util.Arrays.sort();
java.util--->包
Arrays---->类
sort()---->静态方法,Arrays类中的静态方法(类直接调用)
System.out.println(); --->唯一一个不用导的包,java.lang
System--->java.lang.System类(包名全小写)
out---->引用类型的静态属性(类直接调用),基本类型的没办法继续 . println
println()--->out 引用类型中的一个方法
public class TestMyClass3 {
public static void main(String[] args){
System.out.println(); //模仿解析
//out肯定不是基本数据类型,是的话没办法继续 . ,所以out必须是引用类型
A3.out3.println3(); //成品
}
}
class A3{
static B3 out3 = new B3();
}
class B3{
public void println3(){
System.out.println("模拟成功");
}
}
- static修饰初始化代码块
初始化代码块—>类以内,方法以外---->也称动态代码块
-
创建对象的时候,初始化代码块按照和实例变量定义的先后顺序,完成对实例变量的初始化
创建对象的过程:
- 分配空间:为属性赋默认值
- 初始化属性:为属性第二次赋值的机会—>初始化代码块在此过程被执行
- 执行构造方法中的内容
static修饰的初始化代码块
-
定义在类以内,方法以外,被static修饰的初始化代码块—>简称静态代码块
-
在***类加载*** 的时候,静态代码块按照和静态属性定义的先后顺序,完成对静态属性的初始化
- 只能对静态属性初始化,因为和对象没关系,只在类加载时调用
-
类加载
-
JAM第一次使用一个类的时候,它会通过classPath找到对应的 .class文件,对文件进行读取,读取类的相关信息 ( 包名、类名、父类、属性、构造方法、成员方法等 ) 并将信息保存到 JVM内存中,一个类类加载只进行一次 ( JVM不关闭的情况下 )
-
类加载的时机---->第一次使用一个类
-
第一次访问类中的静态成员 ( 静态属性或是静态方法 )
-
第一次创建该类的对象,会先进行类加载,再完成对象的创建—>只有先加载,JVM才知道里面有什么,此时静态代码块会被执行
-
子类类加载 会导致 父类先类加载---->先父类,再子类
-
第一次访问子类的静态成员,会导致先加载父类,再加载子类—>前提父类没有加载过
-
第一次创建子类对象,会先进行类加载,再完成对象的创建
-------------------------------带有类加载创建对象的过程--------------------------
---->先进行加载:先加载父类,再加载子类,并且先于对象创建
先加载父类:为父类静态属性分配空间,同时初始化静态属性 ( 父类静态代码块被执行 )
再加载子类:为子类静态属性分配空间,同时初始化静态属性 ( 子类静态代码块被执行 )
---->再完成对象的创建:先完成父类对象创建,再完成子类对象的创建
先完成父类对象的创建:初始化父类的属性,执行父类的初始化代码块,执行父类构造 方法
再完成子类对象的创建:初始化子类的属性,执行子类的初始化代码块,执行子类构造 方法
-
-
-
final(最终的、最后的)
-
—>可以修饰变量—>成员变量 ( 静态变量+实例变量 ) 和局部变量
- 只允许一次赋值,不允许更改,但是可以被多次使用—>通常被称为常量
- final修饰的实例变量,JVM不再为其赋予默认值。
- 声明的同时对其初始化
- 在构造函数中初始化,但必须保证每一个构造方法都对其初始化
- final修饰的静态变量也不再具有默认值
- 声明的同时对其初始化
- 利用静态代码块对其初始化
-
final修饰的引用
- 引用中存储的对象地址不能改变,但是可以对对象中非final的属性进行改变。
- final修饰的方法能被子类继承,可以使用但不能被覆盖
- final修饰的类不能被子类继承,即没有任何子类
- 如System、String、Math等类都被final修饰,不允许有子类
- 可以通过自定义一个类,由能否继承来判断是否被final修饰
总结
-
abstract:可以修饰类、方法
- 抽象类:不能创建对象,可以声明引用
- 抽象方法:只有方法的声明,没有方法的实现部分;而且抽象方法只能定义在抽象类中
- 抽象类的子类要求:成为抽象类或者覆盖父类所有的抽象方法
-
static:可以修饰属性、方法、初始化代码块
- 静态属性、类变量、静态变量:所有的对象共享一个静态属性,和创建多少对象无关
- 类名.类名属性访问
- 静态方法:只能在静态方法访问本类静态成员、不能直接访问本类非静态成员
- 类名.静态方法 ( 实参 )访问
- 静态代码块:在类加载的时候,按照和静态属性定义的先后顺序,完成对静态属性初始化
- 静态属性、类变量、静态变量:所有的对象共享一个静态属性,和创建多少对象无关
-
final:可以修饰变量 ( 实例变量、静态变量、局部变量 ) 、方法、类
- final修饰的变量:只允许一次赋值,可以多次使用,被称为常量
- final修饰的方法:不允许被覆盖
- final修饰类:不能被继承,即没有子类
-
abstract、static、final与构造方法
- abstract 不能修饰构造方法,被abstract 修饰的方法只有声明没有实现,实现部分需要子类覆盖,但是构造方法不能被继承
- static 不能修饰构造方法,static 修饰的构造方法可以直接通过类名使用,和对象无关,而构造方法用于创建对象,应用混淆,所有不允许static修饰构造方法
- final 不能修饰构造方法,final修饰的方法约束子类不能覆盖,但是本身构造方法不能被子类继承,谈不上覆盖
-
修饰符联合修饰一个成员方法
- private 和 abstract:非法的修饰符组合
- private修饰的方法不能被子类继承,但是abstract修饰的方法实现部分必须通过继承让子类覆盖
- static 和 abstract:非法的修饰符组合
- static修饰的方法可以直接通过类名进行访问,abstract修饰的方法只有声明部分,所有通过类名访问时是一个只有声明没有实现的半成品,无法运行
- final 和 abstract:非法的修饰符组合
- final约束子类不能覆盖此方法,但是abstract的实现必须通过子类覆盖给予实现,相互矛盾
- private、static和final:可以任意组合使用
- 一个方法必须有一个 ( 默认的default ) ,有且只有一个访问修饰符,但是可以同时具有多个修饰符
- 如public static final void m1() { }
- private 和 abstract:非法的修饰符组合