【Java随记】面向对象高级——静态

前言

本篇文章讲的是我们在面向对象编程中很常见的一个关键字static。
static读作静态,可以用来修饰成员变量,也能修饰成员方法。
接下来我们先来学static修饰成员变量。

一、静态

1.1 static修饰成员变量

Java中的成员变量按照有无static修饰分为两种:类变量、实例变量。

它们的区别如下图:

静态变量:属于类的,只需要通过类名就可以调用:类名.静态变量

实例变量:属于对象的,需要对象才能调用:对象.实例变量

代码演示(静态变量和实例变量的调用):

public class TestDemo1 {
    //类变量
    static String TestName;

    //实例变量(对象的变量)
    int TestAge;
}
public class TestDemo2 {
    public static void main(String[] args) {
        //目标:掌握有无static修饰成员变量的用法,特点。
        //1、类变量的用法
        //类名。类变量(推荐)
        TestDemo1.TestName = "三炮";

        //对象.类变量(不推荐)
        TestDemo1 s1 = new TestDemo1();
        s1.TestName = "二大爷";

        TestDemo1 s2 = new TestDemo1();
        s2.TestName = "大爷";

        System.out.println(s1.TestName);//大爷
        System.out.println(TestDemo1.TestName);//大爷

        //2、实例对象的用法:属于每个对象的变量
        //对象.实例变量
        s1.TestAge = 666;
        s2.TestAge = 999;
        System.out.println(s1.TestAge);//666

        //System.out.println(TestDemo1.Testage);//会报错
    }
}

以上代码的内存原理(以案例为例子,数值稍有不同):

 小段总结

1、类变量:属于类,在内存中只有一份,用类名调用

2、实例变量:属于对象,每一个对象都有一份,用对象调用

1.2 static修饰成员变量的应用场景

学习完static修饰成员变量的基本使用之后,接下来就是static修饰成员变量在实际工作中的应用

在实际开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住。

例子:
需求:系统启动后,要求用于类可以记住自己创建了多少个用户对象。

 第一步:先定义一个User类,在用户类中定义一个static修饰的变量,用来表示在线人数;

public class User {
    public static int number;
    //每次创建对象时,number自增一次;
    public User(){
        User.number++;
    }
}

第二步:写一个测试类,在测试类中创建4个User对象,然后打印number的值,观察number的值是否自增

public class Test {
    public static void main(String[] args) {
        //创建4个对象
        new User();
        new User();
        new User();
        new User();

        //查看系统创建了多少个User对象
        System.out.println("系统创建的User对象个数:" + User.number);
    }
}

运行以上的代码,查看执行结果是:系统创建的User对象个数:4

1.3 static修饰成员方法

接下来是static修饰成员方法。

成员方法根据有无static也分为两类:类方法、实例方法

有static修饰的方法,是属于类的,称为类方法 ;调用时直接用类名调用即可。

无static修饰的方法,是属于对象的,称为实例方法;调用时,需要使用对象调用。

案例:
演示类方法、实例方法的基本使用

先定义一个Student类,在类中定义一个类方法、定义一个实例方法

public class Student {
    double score;

    //类方法
    public static void printHelloWorld(){
        System.out.println("Hello World!");
        System.out.println("Hello World!");
    }

    //实例方法(对象的方法)
    public void printPass(){
        //打印成绩是否合格
        System.out.println(score >= 60?"成绩合格" :"成绩不合格" );
    }
}

再定义一个测试类,注意类方法,对象方法调用的区别

public class Test2 {
    public static void main(String[] args) {
        //1、调用Student类中的方法
        Student.printHelloWorld();
        
        //2、调用Student类中的实例方法
        Student s = new Student();
        s.printPass();
        
        //使用对象也能调用类方法(IDEA不会提示,要打完才会提示,不推荐)
        s.printHelloWorld();
    }
}

接下来是static修饰成员方法的内存原理

1、类方法:static修饰的方法,可以被类名调用,是因为它是随着类的加载而加载的;所以类名直接就可以找到static修饰的方法

2、实例方法:非static修饰的方法,需要创建对象后才能调用,是因为实例方法中可能会访问实例变量,而实例变量需要创建对象后才存在。所以实例方法,必须创建对象后才能调用。

1.4 工具类

在学完static修饰方法之后,还有一个有关类方法的应用知识,叫做工具类

如果一个类中方法全都是静态的,那么这个类中的方法就全都可以被类名直接调用,由于调用起来非常方便,就像伊戈尔工具一样,所以就把这样的类叫做工具类。

案例:
写一个生成验证码的工具类
public class MyUtils {
    public static String createCode(int n){
        //1、定义一个字符串,用来记录产生的验证码
        String code = "";

        //2、验证码是由所有的大小写字母或者数字字符组成
        //这里先把所有的字符写成一个字符串,一会从字符串中随机找字符用来生成验证码
        String data = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ";

        //3、循环n次,产生n个索引,再通过索引获取字符
        Random r = new Random();
        for (int i = 0; i < n; i++) {
            int index = r.nextInt(data.length());
            char ch = data.charAt(index);

            //4、把获取到的字符,拼接到code验证码字符串上。
            code += ch;
        }

        //最后返回code ,code 的值就是验证码
        return code;
    }
}

接着可以在任何位置调用MyUtils的createCode然后产生自定义长度的验证码

//这是一个登录界面
public class LoginDemo {
    public static void main(String[] args) {
        System.out.println(MyUtils.createCode(6));
    }
}
//注册界面
public class registerDemo {
    public static void main(String[] args) {
        System.out.println(MyUtils.createCode(6));
    }
}

以上就是工具类的使用

在补充一点,工具类里的方法全都是静态的,推荐用类名调用为了防止使用者用对象调用,我们可以把工具类的构造方法私有化

public class MyUtils{
    //私有化构造方法:这样别人就不能使用构造方法new对象了
    private MyUtils(){
        
    }
    
    //类方法
    public static String createCode(int n){
       ...
    }
}

1.5 static的注意事项

在使用static写代码的时候,如果出错了,如何更好更快的发现错误的地方并且改正

 以下是通用代码在出错修复后的程序代码

public class Student {
    static String schoolName;//类变量
    static double score;//实例变量

    //1、类方法中可以直接访问类的成员,不可以直接访问实例成员
    public void printHelloWorld(){
        //注意:同一个类中,访问类成员,可以省略不写。
        schoolName = "南小";
        printHelloWorld2();

        System.out.println(score);
        printpass();

        System.out.println(this);
    }

    //类方法
    public static void printHelloWorld2(){

    }

    //实例方法
    public static void printpass2(){

    }

    //实例方法
    //2、实例方法中既可以直接访问类成员,也可以直接访问实例成员
    //3、实例方法中可以出现this关键字,类方法中不可以出现this关键字
    public void printpass(){
        schoolName = "东上";
        printHelloWorld2();

        System.out.println(score);
        printpass2();

        System.out.println(this);
    }
}

1.6 static应用(代码块) 

代码块根据有无static修饰分为两种:静态代码块、实例代码块

静态代码块

public class Student1 {
    static int number = 80;
    static String scoolName = "南小";
    //静态代码块
    static {
        System.out.println("静态代码块执行了");
        scoolName = "南小";
    }
}

静态代码块不需要创建对象就能够执行

public class Test {
    public static void main(String[] args) {
        //目标:认识两种代码块,了解特点与 基本作用
        System.out.println(Student1.number);
        System.out.println(Student1.number);
        System.out.println(Student1.number);

        System.out.println(Student1.scoolName);
    }
}

执行代码的时候,没有创建对象的时候,静态代码块就已经执行了。

关于静态代码块重点注意:静态代码块,随着类的加载而执行,而且只执行一次。

示例代码块

 实例代码块的作用其实和构造器的作用是一样的,用来给对象初始化值;而且每次创建对象之前都会先执行示例代码块

public class Student2 {
    //实例变量
    int age;
    //实例代码块:实例代码块会执行在每一个构造方法之前
    {
        System.out.println("实例代码块执行");
        age = 18;
        System.out.println("有人创建了对象:" + this);
    }

    public Student2(){
        System.out.println("无参数构造器执行");
    }

    public Student2(String name){
        System.out.println("有参数构造器执行");
    }
}

 接下来在测试类中进行测试,观察创建对象时,实例代码块是否先执行

public class Test1 {
    public static void main(String[] args) {
        Student2 s1 = new Student2();
        Student2 s2 = new Student2("张三");
        System.out.println(s1.age);
        System.out.println(s2.age);
    }
}

对于实例代码块重点注意:实例代码块每次创建对象之前都会执行一次

1.7 static应用(单例设计模式)

关于static的应用有一个叫做单例设计模式的技巧。

所谓设计模式指的是,一类问题可能会有多种解决方案,而设计模式是在变成实践中,多种方案中的一种最优方案。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值