1. 关键字static
static是Java的关键字,可以修饰成员变量和成员方法。
1.1 修饰成员变量
1.1.1 特点
- 加关键字static的成员变量 -> 静态变量:
静态成员变量属于类属性,内存中只加载一次 - 不加关键字static的成员变量 -> 实例变量:
实例成员变量属于实例属性,每次创建新实例会初始化变量
1.1.2 访问格式
静态成员变量:
类.变量名(推荐)
实例.变量名
实例成员变量:
实例.变量名
1.1.3 定义场景
静态成员变量:
属性属于类,且需要实例共享或者是常数等(例:圆周率3.14)
实例成员变量:
属性属于所有实例共性,但是每个实例属性值并不相同
1.1.4 示例
public class StaticTest1 {
// 定义静态成员变量
public static double PI = 3.14;
// 定义实例成员变量
public double result;
public static void main(String[] args) {
// 计算圆的周长
StaticTest1 staticTest1 = new StaticTest1();
// 圆的半径为2
staticTest1.result = 2 * 2 * StaticTest1.PI;
System.out.println(staticTest1.result);
}
}
PI是属于静态成员变量,需要共享,所有圆相关的计算都需要它,所有他是静态共享的。
简单的内存描述:
- 类加载后再堆内存中创建PI变量
- 方法区加载main方法,之后开始运行将main方法加载到栈内存中
- 初始化StaticTest1类,在堆内存中创建实例,将实例地址返回给staticTest1实例变量名
- 这时实例staticTest1中静态变量指向的是类加载是创建的静态变量PI
- 执行计算,赋值给staticTest1实例成员变量
- 输出结果
1.2 修饰成员方法
1.2.1 特点
- 加关键字static的成员方法 -> 静态成员方法:
静态成员方法属于类,内存中只加载一次,所有对象共用功能 - 不加关键字static的成员方法 -> 实例成员方法:
实例成员方法属于实例特有方法
1.2.2 访问格式
静态方法:
类.静态方法
实例.静态方法(不推荐)
成员方法:
实例.成员方法
1.2.3 定义场景
静态方法表示类共用的功能,并不属于特定对象方法。比如计算加法都是两数相加,这是特定功能,每个实例计算的过程都一致。在程序中为了方便单独访问。
成员方法表示实例特有方法。比如学生实例,每个人说话的声音都是不同的,这就是特有功能,某某人说得话,具有一定识别性。在程序中需要访问成员变量。
1.2.4 示例
public class Student {
// 定义静态方法
public static void task() {
System.out.println("所有学生的任务是学习");
}
// 定义实例方法
public void sleep() {
System.out.println("每个学生的睡姿都有自己的独特性");
}
public static void main(String[] args) {
// 直接调用静态方法
Student.task();
// 调用实例方法
Student student = new Student();
student.sleep();
}
}
你可能会想,任务task方法也是学生的独特方法,这样想确实也没问题。这就要看你抽象出来的方法是否具备所有对象共有。比如sleep这个方法也可以是静态方法,毕竟所有学生都需要休息,但是要具体到每个学生休息情况就变成独有的。
1.3 代码块
代码块是类的五大部分之一(代码块,构造方法,成员变量,方法,内部类),在java中使用{}括起来的就是代码块
1.3.1 格式和示例
静态代码块:
static {
...
}
代码块:
{
...
}
示例:
public class StaticTest2 {
// 静态代码块
static {
System.out.println("静态代码块执行");
}
// 代码块
{
System.out.println("类代码块执行");
}
public static void main(String[] args) {
// 创建示例
StaticTest2 staticTest2 = new StaticTest2();
}
}
1.3.2 特点及场景
静态代码块
- 特点:类加载执行,只执行一次
- 场景:做一些静态资源加载
代码块
- 特点:每次创建实例调用构造方法时执行,在构造方法之前执行。
- 场景:初始化实例资源
1.4 注意事项
静态关键字主要应用在工具类和常量中,在实际开发中,工具类是必不可少的。
静态关键字还可以修饰类,这将牵扯到内部类,将在下章说明
- 静态方法只能访问静态成员变量,不可以访问实例成员变量。
- 实例可以访问静态成员
- 静态方法中不可以使用this关键字(下面会说)
2. 关键字this、super和extends
- 关键字this、super主要在继承方面体现到的比较多。this表示当前实例,super表示父类。
- java中提供关键字extends,使一个类和另一个类建立继承关系,被继承类为父类,继承类为子类。
- 继承类(子类)可以直接使用父类的属性和成员方法,这样就大大提高代码的复用性。
2.1 继承(extends)
格式:
public class 类名 extends 父类类名 {
...
}
优势:
- 提高代码的复用性,减少冗余代码
- 增强代码的扩展性
设计规范:
- 提取类之间相同属性
- 子类独有属性不要放在父类中
- 所有类设计符合面对对象逻辑
2.2 继承的特点
- 子类可以继承父类的属性和行为,但是不能继承父类构造器
- java是单继承,一个子类只能有一个父类(很符合现实生活)
- 不支持多继承,但支撑多层继承
- java中所有类都是Object的子类
- 子类可以继承父类私有成员变量,但是不能直接访问(可以通过公共方法和构造器访问和设置)
- 不继承静态变量,可以共享
2.3 继承成员访问
在子类中访问成员(就近原则)
- 先子类局部范围访问
- 然后子类成员访问
- 父类成员访问
- 以上都没有则报错
如果子父类出现重名成员,则优先使用子类。若想调用父类,格式如下:
super.父类成员变量/父类成员方法
2.4 方法重写
- 简介:子类继承父类时,子类实现了和父类相同的方法,我们就称子类方法为重写方法。
- 格式:当子类重写父类方法时,需要在方法上添加@override注解
- 要求:①重写的方法必须与父类方法相同,除了名称,参数列表也要一致。②私有方法不能被重写。③子类重写方法时,访问权限必须大于等于父类方法访问权限。
示例:
public class People {
private String name;
public void showName() {
System.out.println("我的名称:" + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Teacher extends People {
public Teacher() {
super.setName("Tome");
}
@Override
public void showName() {
System.out.println("我是教师。我的名字是" + getName());
}
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.showName();
}
}
2.5 子类构造器
- 子类构造函数执行时都先执行父类的默认构造函数
- 子类构造函数第一行默认是super()不写也存在
- 如果父类无默认构造器将报错
- 如果父类无构造器,也可以手动调用父类构造器。(例:super(param...))
2.6 this和super
关键字 | 访问成员 | 构造器 | 说明 |
---|---|---|---|
this | this.成员变量/this.方法名(...) | this(...)本类构造器 | 代表当前调用类对象引用 |
super | super.成员变量/super.方法名(...) | super(...)父类构造器 | 代表当前调用类对象父类引用 |
注意:
this(...)和super(...)只能放在方法的第一行,所以这两个方法不能在同一个方法中出现。
3. 类执行顺序
// 父类
public class People {
private String name;
private String sex;
private int age;
static {
System.out.println("执行People静态代码块");
}
{
System.out.println("执行People代码块");
}
public People() {
System.out.println("执行People构造器");
}
// get and set
}
// 子类
public class Student extends People {
private int studentId;
private String pro;
static {
System.out.println("执行Student静态代码块");
}
{
System.out.println("执行Student代码块");
}
public Student() {
System.out.println("执行Student构造器");
}
// get and set
}
// 测试类
public class Test {
public static void main(String[] args) {
Student student = new Student();
}
}
运行Test类可以看见执行后的结果:
执行People静态代码块
执行Student静态代码块
执行People代码块
执行People构造器
执行Student代码块
执行Student构造器
本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。