【Java基础08】静态关键字static和继承(this、super、extends)

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 注意事项

静态关键字主要应用在工具类和常量中,在实际开发中,工具类是必不可少的。
静态关键字还可以修饰类,这将牵扯到内部类,将在下章说明

  1. 静态方法只能访问静态成员变量,不可以访问实例成员变量。
  2. 实例可以访问静态成员
  3. 静态方法中不可以使用this关键字(下面会说)

2. 关键字this、super和extends

  • 关键字this、super主要在继承方面体现到的比较多。this表示当前实例,super表示父类。
  • java中提供关键字extends,使一个类和另一个类建立继承关系,被继承类为父类,继承类为子类。
  • 继承类(子类)可以直接使用父类的属性和成员方法,这样就大大提高代码的复用性。

2.1 继承(extends)

格式:

public class 类名 extends 父类类名 {
	...
}

优势:

  1. 提高代码的复用性,减少冗余代码
  2. 增强代码的扩展性

设计规范:

  1. 提取类之间相同属性
  2. 子类独有属性不要放在父类中
  3. 所有类设计符合面对对象逻辑

2.2 继承的特点

  1. 子类可以继承父类的属性和行为,但是不能继承父类构造器
  2. java是单继承,一个子类只能有一个父类(很符合现实生活)
  3. 不支持多继承,但支撑多层继承
  4. java中所有类都是Object的子类
  5. 子类可以继承父类私有成员变量,但是不能直接访问(可以通过公共方法和构造器访问和设置)
  6. 不继承静态变量,可以共享

2.3 继承成员访问

  1. 在子类中访问成员(就近原则)
  • 先子类局部范围访问
  • 然后子类成员访问
  • 父类成员访问
  • 以上都没有则报错
  1. 如果子父类出现重名成员,则优先使用子类。若想调用父类,格式如下:
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

关键字访问成员构造器说明
thisthis.成员变量/this.方法名(…)this(…)本类构造器代表当前调用类对象引用
supersuper.成员变量/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构造器


本章结束,用于个人学习和小白入门,大佬勿喷!希望大家多多点赞收藏支撑支撑!

源码 【GitHub】 【码云】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值