当前位置: 首页 > news >正文

类变量和类方法

文章目录

  • 1.类变量-提出问题
  • 2.类变量内存布局
  • 3.什么是类变量
  • 4.如何定义类变量
  • 5.如何访问类变量
  • 6.类变量使用注意事项
  • 7.类方法基本介绍
  • 8.类方法的调用
  • 9.类方法经典的使用场景
  • 10.类方法使用注意事项和细节讨论

1.类变量-提出问题

在main方法中定义一个变量count,当一个小孩加入游戏后count++,最后个count 就记录有多少小孩玩游戏 。

问题分析:

count是一个独立于对象,很尴尬,以后我们访问count很麻烦,没有使用到OOP。因此,我们引出类变量/静态变量。

package com.hspedu.static_;

public class ChildGame {

    public static void main(String[] args) {

        //定义一个变量 count, 统计有多少小孩加入了游戏
        int count = 0;

        Child child1 = new Child("白骨精");
        child1.join();
        //count++;
        child1.count++;

        Child child2 = new Child("狐狸精");
        child2.join();
        //count++;
        child2.count++;

        Child child3 = new Child("老鼠精");
        child3.join();
        //count++;
        child3.count++;

        //===========
        // 类变量,可以通过类名来访问
        System.out.println("共有" + Child.count  + " 小孩加入了游戏...");
        // 下面的代码输出什么?
        System.out.println("child1.count=" + child1.count);//3
        System.out.println("child2.count=" + child2.count);//3
        System.out.println("child3.count=" + child3.count);//3



    }
}

class Child { //类
    private String name;
    // 定义一个变量 count ,是一个类变量(静态变量) static 静态!!!
    // 该变量最大的特点就是会被 Child 类的所有的对象实例共享!!!
    public static int count = 0;
    public Child(String name) {
        this.name = name;
    }
    public void join() {
        System.out.println(name + " 加入了游戏..");
    }
}

2.类变量内存布局

https://blog.csdn.net/x_iya/article/details/81260154/

https://www.zhihu.com/question/59174759/answer/163207831

有些书说在方法区… jdk 版本有关系,记住两点:

(1) static变量是同一个类所有对象共享

(2) static类变量,在类加载的时候就生成了.静态变量是类加载的时候,就创建了,所以不用创建对象实例也能直接通过 类名.类变量名 访问。

3.什么是类变量

类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。这个从前面的图也可看出来。

4.如何定义类变量

定义语法:

访问修饰符static数据类型变量名;[推荐]

static访问修饰符数据类型变量名;

5.如何访问类变量

类名.类变量名

或者对象名.类变量名【静态变量的访问修饰符的访问权限和范围和普通属性是一样的】

推荐使用:类名.类变量名;

6.类变量使用注意事项

  1. 什么时候需要用类变量

当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义学生类,统计所有学生共交多少钱。Student (name, staticfee)

  1. 类变量与实例变量(普通属性)区别

类变量是该类的所有对象共享的,而实例变量是每个对象独享的。

  1. 加上static称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量

  2. 类变量可以通过类名.类变量名或者对象名.类变量名来访问,但java设计者推荐我们使用类名.类变量名方式访问。【前提是满足访问修饰符的访问权限和范围】

  3. 实例变量不能通过类名.类变量名方式访问。

  4. 类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了.就可以使用类变量了。

  5. 类变量的生命周期是随类的加载开始,随着类消亡而销毁。

7.类方法基本介绍

类方法也叫静态方法。形式如下:

访问修饰符 static 数据返回类型 方法名(){}【推荐】

static 访问修饰符 数据返回类型 方法名(){}

8.类方法的调用

使用方式:

类名.类方法名或者对象名.类方法名

package com.hspedu.static_;

public class StaticMethod {
    public static void main(String[] args) {
        //创建2个学生对象,叫学费
        Stu tom = new Stu("tom");
        //tom.payFee(100);
        Stu.payFee(100);//对不对?对

        Stu mary = new Stu("mary");
        //mary.payFee(200);
        Stu.payFee(200);//对


        //输出当前收到的总学费
        Stu.showFee();//300

        //如果我们希望不创建实例,也可以调用某个方法(即当做工具来使用)
        //这时,把方法做成静态方法时非常合适
        System.out.println("9开平方的结果是=" + Math.sqrt(9));


        System.out.println(MyTools.calSum(10, 30));
    }
}
//开发自己的工具类时,可以将方法做成静态的,方便调用
class MyTools  {
    //求出两个数的和
    public static double calSum(double n1, double n2) {
        return  n1 + n2;
    }
    //可以写出很多这样的工具方法...
}
class Stu {
    private String name;//普通成员
    //定义一个静态变量,来累积学生的学费
    private static double fee = 0;

    public Stu(String name) {
        this.name = name;
    }
    // 说明
    // 1. 当方法使用了static修饰后,该方法就是静态方法
    // 2. 静态方法就可以访问静态属性/变量
    public static void payFee(double fee) {
        Stu.fee += fee;//累积到
    }
    public static void showFee() {
        System.out.println("总学费有:" + Stu.fee);
    }
}

9.类方法经典的使用场景

当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法, 提高开发效率。

比如:

工具类中的方法utils。Math类、Arrays类、Collections集合类看下源码可以发现都是static方法。

10.类方法使用注意事项和细节讨论

  1. 类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区∶类方法中无this的参数。普通方法中隐含着this的参数。

  2. 类方法可以通过类名调用,也可以通过对象名调用。普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。

  3. 类方法中不允许使用和对象有关的关键字,比如this和super。普通方法(成员方法)可以。

  4. 类方法(静态方法)中只能访问静态变量或静态方法。普通成员方法,既可以访问非静态成员,也可以访问静态成员!!

package com.hspedu.static_;

public class StaticMethodDetail {
    public static void main(String[] args) {

        D.hi();//ok
        //非静态方法,不能通过类名调用
        //D.say();, 错误,需要先创建对象,再调用
        new D().say();//可以
    }
}
class D {

    private int n1 = 100;
    private static  int n2 = 200;
    public void say() {//非静态方法,普通方法

    }

    public static  void hi() {//静态方法,类方法
        //类方法中不允许使用和对象有关的关键字,
        //比如this和super。普通方法(成员方法)可以。
        //System.out.println(this.n1);
    }

    //类方法(静态方法)中 只能访问 静态变量 或静态方法
    //口诀:静态方法只能访问静态成员.
    public static void hello() {
        System.out.println(n2);
        System.out.println(D.n2);
        //System.out.println(this.n2);不能使用
        hi();//OK
        //say();//错误
    }
    //普通成员方法,既可以访问  非静态成员,也可以访问静态成员
    //小结: 非静态方法可以访问 静态成员和非静态成员
    public void ok() {
        //非静态成员
        System.out.println(n1);
        say();
        //静态成员
        System.out.println(n2);
        hello();

    }
}

练习:

package com.hspedu.static_;

public class StaticExercise03 {
}

class Person {
    private int id;
    private static int total = 0;
    public static void setTotalPerson(int total){
        // this.total = total;//错误,因为在static方法中,不可以使用this 关键字

        Person.total = total;
    }
    public Person() {//构造器
        total++;
        id = total;
    }
    //编写一个方法,输出total的值
    public static void m() {
        System.out.println("total的值=" + total);
    }
}
class TestPerson {
    public static void main(String[] args) {

        Person.setTotalPerson(3); // 这里没有调用构造器
        new Person(); // new了之后调用构造器,count++
        Person.m();// 最后 total的值就是4
    }
}

注意:

Person.setTotalPerson(3); 调用静态方法 这里还没有调用构造器

new Person(); new了之后才调用构造器,count++

因为构造器是在创建对象时完成对对象的初始化。


相关文章:

  • 《高效迁移学习:Keras与EfficientNet花卉分类项目全解析》
  • 大脑宏观结构中的富集俱乐部:图论分析视角
  • 嵌入式硬件篇---手柄控制控制麦克纳姆轮子
  • Webpack Vite 前端高频面试题
  • 详解部分依赖
  • go函数详解
  • H-vmunet: High-order Vision Mamba UNet for Medical Image Segmentation模型详解及代码复现
  • Drools规则引擎在临床路径逻辑中的编程实例讨论汇总
  • java通配符?, T, E, K, V, N(简单易懂)
  • 树莓派4B使用Ubuntu20.04连接不上热点
  • 从零开始学习PX4源码10(启动过程)
  • AI Agent系列(三) -Agent实现
  • 云原生服务网格:微服务通信的智能中
  • vue3-computed计算属性和reactive响应式系统结合使用
  • 01、Hive从入门到放弃,第一章:简单入门与安装
  • 引入其他 YML 配置源 —— Spring Boot 中的 `import` 功能
  • Leetcode-146.LRU缓存
  • Oracle RAC环境下自动清理归档日志实战指南
  • vscode更新后: 适用于 Linux 的 Windows 子系统必须更新到最新版本才能继续。可通过运行 “wsl.exe --update” 进行更新
  • 【从零开始学习计算机科学】操作系统(九)大容量存储器
  • 《歌手》回归,人均技术流,00后整顿职场
  • 外企聊营商|上海仲裁:化解跨国企业纠纷的“上海路径”
  • 专访|《内沙》导演杨弋枢:挽留终将失去的美好
  • 悬疑剧背后的女编剧:创作的差异不在性别,而在经验
  • 雷军内部演讲回应质疑:在不服输、打不倒方面,没人比我们更有耐心
  • 董军同德国国防部长举行会谈