8.20
static关键字
- static是静态的意思,可以修饰成员变量和成员方法
静态与实例
-
静态成员变量:
-
- 有static修饰,成员变量只在内存中只存储一份,可以被共享访问,修改
- 访问方式:类名.静态成员变量名(如果在同一类中,这个**类名.**可以不写)
- 内存原理:静态成员变量在程序执行的时候会在堆内存的静态变量区开辟空间存储数据
-
实例成员变量:
-
- 无static修饰。成员变量只属于每个对象,也就不可以被共享访问,修改了
- 访问方式:对象名.实例成员变量名(因为实例成员变量是属于每个对象的,所以即使在同一类中**对象名.**也不能省略)
-
静态成员方法:
-
- 有static修饰,归属类,用类名访问
- 静态方法调用:类名.方法名(参数)
- 内存原理:
-
- 程序在执行时肯定是先加载类进入方法区,静态的成员变量/方法与类一起加载
- 然后把main方法提到栈内开始跑
- main方法中执行到有static修饰的方法时就会把此方法从方法区提到栈内,运行此方法
-
实例成员方法
-
- 内存原理
-
- main方法执行到创建对象语句时User u2=new User();
- 首先会在栈内开辟一段内存给U2,U2中存的是对象在堆内存的地址
- 来到堆内存分析对象。程序会在堆内存中开辟空间用来存这个对象的实例成员变量
- 开辟空间存实例成员方法的内存地址。此时的实例成员方法在方法区
- 实例成员方法被调用后也是直接提到栈内存中开始跑
总结
-
- 静态成员变量/方法不创建对象直接用类访问
- 实例成员变量/方法需要创建出具体的对象才能访问
- 如果一个方法的目的是实现一个共用的功能,则该方法可声明为静态方法
注意事项
- ==静态方法只能访问静态成员(==变量/方法),不能直接访问实例成员,需要创建对象间接访问
- 实例方法可以访问静态成员,也可以访问实例成员。
- 静态方法中不可以出现this,因为this关键字代表当前对象,而静态方法一般不是由对象调用的
static:工具类
Util
定义
- 类中都是一些静态方法,每个方法都是以完成一个共同的功能为目的,这个类给系统开发人员共同使用,提高了代码的复用性
- 说人话就是专门写一个类 这个类中写一个static修饰的方法,然后再别的类中调用这个方法。调用:类名.方法名
- 工具类中还有一个==私有的构造器(private)==目的是为了不让别人通过创建对象来调用这个类,因为这样会浪费内存,让他直接通过类名来调用这个类
static:代码块
Code
- 一个类中应包含:成员变量,构造器,代码块,内部类。代码块定义在类中方法外。
- 在java类中用=={}==围起来的部分叫做代码块
静态代码块
- 格式:static{}
- 特点:随着类的加载而优先加载,自动触发,只执行一次
- 如果把静态代码块里的代码放到方法中,这个方法被调用几次,这段代码就会被执行几次,这样程序执行效率就变低了
- 使用场景:在类加载的时候做一些静态数据的初始化,以便后续使用
构造代码块
- 几乎不用
- 格式:{}
- 特点:创建对象,调用构造器时执行,并且在构造器执行前执行
- 应用:初始化实例资源
工具类与代码块
- 在面向对象设计中,推崇每个类都应该具有单一的职责。
- 代码块里的东西是这个类单独使用的,别的类用不到这个功能
- 而工具类中的静态方法是还能多类都需要用
static:单例设计模式
Singleininstanse
工具类与单例
-
- 单例模式强调一个类只能有一个实例,而工具类强调一组静态方法,不需要实例化。工具类的方法通常是无状态的,不依赖于对象的特定状态。
- 单例模式的一个主要目的是提供全局访问点,以便在整个应用程序中共享一个实例。工具类的方法可以在任何地方通过类名来调用,但不会保留任何全局状态
-
设计模式:一个问题的最优解法就被称为设计模式
-
单例模式用处:确保一个类只能创建一个对象,用来实现一些需要确保在整个应用程序中只有一个实例存在的情况
-
单例模式好处:确保全局资源一致性,避免资源浪费,保证多线程环境中的安全性
饿汉单例模式
-
在用类获取对象的时候,对象已经被提前准备好了,确保了线程的安全性,不存在多线程并发问题
-
设计步骤:
-
-
定义一个类,并私有构造器,不私有的话就会导致别人可以在外面创建很多对象来访问这个类。
-
定义一个静态变量存储对象,因为我们要想办法对外提供一个此类的对象,不然这个类就一个对象都无法创建了
-
懒汉单例
- 在真正需要该对象的时候,才去创建一个对象(延迟加载对象)
- 实现步骤
-
- 构造器私有
- 定义一个静态成员变量(一定要把他私有private)负责存储一个对象,只加载一次,只有一份
- 提供一个方法对外返回单例对象
继承
Extends
- 他继承过来了就相当于他自己的,按照他自己的去用就行了
- Java中提供了一个关键字extends,使用这个关键字可以使一个类与另一个类创建起父与子的关系
- 作用:当子类继承了父类以后,就可以直接使用父类公共的属性和方法了,可以提升代码的复用性
- 子类们独有的属性,行为放在自己类中,子类们共同的特征放到父类中
- 内存分析
-
- 子类程序被执行时会在堆内存中开辟一段空间,这段空间被分为两部分,一份给自己(this)另一部分给他的父类(supper)
- 各自的变量和方法放到各自的空间中
特点
- 子类可以继承父类的属性和行为,但是不能继承父类私有构造器
- 一个类只能继承一个直接父类
- 不支持多继承,但支持多层继承
- Java中所有的类都是Object类的子类
- 在子类中访问成员变量,成员方法满足:就近原则
- 子父类成员变量/方法重名时:
-
- 指定访问子类:this.变量/方法名
- 指定访问父类:super.变量/方法名
- 在子类的方法中访问父类的成员:super.成员
方法重写
-
- 子类和父类中一模一样的方法声明(方法名形参列表相同),称子类的方法为重写的方法
- 应用场景:子类需要父类的功能,但父类的该功能不完全满足自己的需求时
- @Override:放在重写后的方法上,作为重写是否正确的校验注解,这样更安全
- 私有方法不能被重写
- 重写方法的访问权限一定要大于等于父类方法
- 子类不能重写父类静态方法
- 在子类的重写方法中应先调用一下父类此方法,然后在此基础上进行功能的增加
继承后子类构造器
- 若想要在创建对子类象时并给他的成员变量赋初始值,但是这个成员变量定义在了父类中,此时我们就需要通过子类的构造器去继承父类的构造器了
- 子类继承父类以后,子类中所有的构造器都默认先访问父类中无参构造器,在执行自己
- 因为子类在初始化的时候,有可能访问到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据(先有爸爸再有儿子)
- 倘若父类中没有无参构造器而子类中有无参构造器,这样程序就会报错
this与super
- this代表本类对象的引用,就是代表子类的一些东西
- super代表父类存储空间的标识
- this和super都只能出现在构造器的第一行,因此在同一个构造器中两者不能同时出现
关键字 | 访问成员变量 | 访问成员方法 | 访问构造器 |
---|---|---|---|
this | this.成员变量:访问的是本类(子类)成员变量 | this.成员方法:访问子类的成员方法 | this(…):在子类中访问子类自己的构造器,也就是访问兄弟构造器 |
super | super.成员变量:父类成员变量 | super.成员方法:父类成员方法 | super(…):在子类构造器中访问父类构造器 |
- this()的使用场景:
-
- 一个类中有两个及以上的构造器
- 在构造器1内调用构造器2。