目录
修饰符: 给代码添加某种特征或作用
abstract-抽象
抽象的,不是真实存在的,只是概念声明
抽象类
abstract 访问修饰符 class 类名{} 访问修饰符 abstract class 类名{}
修饰符之间的顺序不做要求
使用
-
无法实例化对象
-
仍然可以参与多态,做引用声明
-
通常情况下, 父类应为抽象类
-
抽象父类中仍然存在构造, 供子类构造使用
抽象方法
修饰符 返回值类型 方法名(形参列表);
使用
-
没有方法实现部分(方法体)
-
抽象父类中的方法是否应为抽象方法取决于子类是否会使用其方法内容
-
抽象类和抽象方法的关系:
-
抽象类中可以存在非抽象方法
-
抽象方法必须存在于抽象类
-
-
子类必须对继承的抽象方法提供方法重写,除非子类是抽象类
-
除非子类本身也身为父类,否则不可变为抽象类,必须提供重写
-
拥有抽象方法的抽象父类的作用:
解决子类之间的代码冗余问题
约束子类必须拥有某些内容
约束子类必须对方法进行重写
抽象的好处
-
抽象父类完全服务于子类, 更贴合程序设计和现实逻辑
-
优化代码结构
final-最终
最后的数据状态,不可再改变
修饰变量
-
变为常量,值不可改
属性
修饰符 数据类型 属性名;
特点
-
常量属性没有默认值
-
常量属性在创建时必须赋予初始值
-
赋值时机:
-
声明的同时直接赋值
public class Super { public final int NUM=100; }
-
在构造中进行赋值(必须确保所有构造中都有赋值操作)
public class Super { public final int NUM; public Super(){ NUM = 10; } public Super(int n){ NUM = n; } }
-
-
局部变量
局部常量只需确保无二次赋值即可,对赋值时机无要求
public static void main(String[] args) { final int N; N = 20; // N = 30; 不可二次更改 }
常量的标准命名规范: 全大写,多个组合之间_隔开
当修饰的变量为引用时, 意为对象内容可改,引用地址不可改
final Dog dog = new Dog(); dog.setName("小黑"); dog.setName("小白"); //dog = new Dog();引用地址不可改
修饰方法
可以被继承,不可被重写
修饰类
无法被继承
static-静态
修饰属性
变为静态属性, 也称为静态变量|类变量
使用
-
不被某个对象独有,被所有对象共享
-
静态属性和非静态属性存储位置的区别:
-
静态属性存储在方法区中, 一个类在内存中只会存储一份
-
非静态属性存储在对象空间中,每个对象都有一份
-
-
静态内容在内存中的存放标识为类名, 可以直接通过
类名.静态属性名
的方式进行访问 -
当静态属性进行封装之后, 不可手动直接访问, 必须通过调用getter|setter访问
-
getter|setter是静态的(常见): 可以通过
引用名.getter()|setter(实参)
访问, 也可通过类名.getter()|setter(实参)
直接访问 -
getter|setter不是静态的: 只能通过
引用名.getter()|setter(实参)
访问
-
-
静态属性和非静态属性出现在内存中时机的区别:
-
静态属性是在类加载的时候出现在内存中的
-
非静态属性是在对象创建时出现在内存中的
-
什么是类加载?
在第一次使用类内容时, 通过CLASSPATH类路径找到字节码文件,将字节码文件中的内容加载到虚拟机中的过程,称之为类加载, 通常只会触发一次
静态内容会在类加载的过程中完成空间分配
类加载的触发时机:
第一次创建对象时
第一次访问静态内容时
通过
Class.forName("类的全限定名")
强制触发类加载
全限定名: 包名.类名(例: java.util.Scanner)
子类的类加载会触发父类类加载
只声明引用不会触发类加载
public class ClassA { private static int num;//累加器属性,统计构造被执行的次数 public String str="这是实例属性|非静态属性"; //提供getter|setter-静态 public static int getNum(){ return num; } public static void setNum(int n) { num = n; } public ClassA(){ num++;//构造被执行,累加器+1 } }
修饰方法
会变成静态方法, 也就是函数
使用
-
无法访问非静态内容, 但是非静态方法可以访问静态内容
-
静态方法使用时非静态内容有可能并未存在
-
非静态方法执行时静态内容一定已经存在
-
-
可以通过
类名.静态方法名(实参)
直接调用访问(推荐) -
无法使用this和super关键字
-
静态方法执行时当前对象和父类对象可能并未存在
-
-
无法修饰局部变量
-
局部变量作用范围限制其无法成为类变量
-
局部变量在执行时才会出现在栈内存中, 晚于静态内容
-
-
static无法修饰构造
-
构造方法只能通过new关键字调用,无法通过类名调用
-
构造方法不可存放在静态内容区
-
-
父类静态方法子类可以继承
-
多态场景下, 只能执行父类方法体, 子类的重写无意义
-
静态内容的执行只关注引用类型
-
静态内容在方法区中不存在嵌套包含关系, 所以本质上子类并非
重写
父类方法,而是提供了一个重名的方法
-
修饰初始代码块(了解)
初始代码块
所有构造共有内容的提炼,会在构造方法体内容执行之前执行, 通常用于给属性赋值
语法
{ //初始代码块 }
位置
类以内, 方法以外, 通常写在属性正下方
使用
-
在创建对象时执行
-
可以执行多次
静态初始代码块
通常用来给静态属性赋值
语法
static{ //静态初始代码块 }
位置
与初始代码块相同
使用
-
无法访问非静态内容,不可使用this和super关键字
-
在类加载时执行
-
通常只会执行一次
abstract无法与private,static,final联用
private,static,final可以任意结合