01_面向对象高级_static

Static

static 的中文意思是"静态",它可以修饰成员变量、成员方法

1. Static 修饰成员变量
  • static 修饰的成员变量,也称之为"类变量"
  • 类变量它是属于类的,与类一起加载,在内存中只有一份,会被类的所有对象共享
  • 无 static 修饰的成员变量,称之为 " 实例变量 (对象变量) "
  • 实例变量 (对象变量) 是属于对象的,每个对象中都有一份
public class HelloWorld {
    public static void main(String[] args) {
        
        Human.name = "人类";  // 直接通过 "类名.类变量名" 的方式来访问(推荐此方法)
        Human obj = new Human();
        obj.name = "人才";  // 也可以通过 "对象.类变量名" 的方式访问,但是不推荐此方法!
        
    }
}

class Human {
    // 类变量
    static String name;

    // 实例变量(对象的变量)
    int age;
}
2. 类变量的使用场景

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

import java.util.ArrayList;

public class HelloWorld {
    public static void main(String[] args) {
        // 创建一个集合,用来存放对象
        ArrayList list = new ArrayList();

        System.out.println(Human.number);  // 0
        for (int i = 0; i < 5; i++) {
            Human obj = new Human();
            list.add(obj);
        }
        System.out.println(Human.number);  // 5
    }
}

class Human {
    // 类变量
    static int number;  // 没必要自己手动初始化,因为默认自动初始化为 0

    public Human() {
        Human.number++;
        // 在同一个类中,访问自己类的类变量,可以省略不写前面的 Human
        // 即:可以将 Human.number++ 写成 number++
    }
}
3. static 修饰成员方法
  • 类方法:有 static 修饰的成员方法,属于类
  • 实例方法:无 static 修饰的方法,属于对象
public class HelloWorld {
    public static void main(String[] args) {
        Human.printHelloWorld();  // 直接通过"类名.类方法名"进行调用(推荐使用此方法)
        Human obj = new Human();
        obj.printHelloWorld();  // 不推荐使用此方法
        obj.printGood();
    }
}

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

    // 实例方法(对象的方法)
    public void printGood() {
        System.out.println("Good");
    }
}
4. 类方法的使用场景
  • 类方法最常见的应用常见是做工具类

  • 什么是工具类?

    简单的说,就是创建一个类,在里面写一些功能,方便别人去调用你写的工具;

    而在工具类中,使用的方法都是一些类方法,而不是实例方法

    因此,工具类没有创建对象的需求,建议将工具类的构造器进行私有,从而禁止他人创建对象

    另外要注意的是,一般情况下,每个方法都是用来完成一个功能的。

  • 为什么工具类中的方法要使用类方法,而不用实例方法?

    首先,实例方法确实也能够实现做工具类,但是!实例方法需要创建对象来调用,而如果大费周章创建了一个对象,却只是为了用它来调用实例方法,在操作上看,这是多此一举,在内存上看,它还浪费了内存。

  • 使用类方法设计工具类的好处

    提高了代码的复用;调用方便,提高了开发效率。

5. 代码块

**概述:**代码块是类的5大成分之一(成员变量、方法、构造器、代码块、内部类)

代码块分两种

  • **静态代码块:**static { }

    特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次

    作用:完成类的初始化,例如:对类变量的初始化赋值

  • 实例代码块:{ }

    特定:每次创建对象时,都会先执行实例代码块,再执行构造器

    作用:和构造器一样,都是用来完成对象的初始化操作的,例如:对实例变量进行初始化赋值

public class HelloWorld {
    public static void main(String[] args) {
        // 先加载一次类,执行一次 static{},再同步执行 Human.number
        System.out.println(Human.number);
        System.out.println(Human.number);
        System.out.println(Human.number);

        // 实例代码块——功能演示
        Human obj = new Human();
        Human obj2 = new Human(25);
        
        // 程序运行结果:
        /*
            静态代码块执行了~~
            1
            1
            1
            警告!有人创建了对象!对象内存地址: login.Human@682a0b20
            此人使用了[无参]构造器创建对象
            警告!有人创建了对象!对象内存地址: login.Human@3d075dc0
            此人使用了[含参]构造器创建对象
        */
    }
}

class Human {
    static int number;

    // 静态代码块
    static {
        System.out.println("静态代码块执行了~~");
        number++;
    }

    // 实例代码块
    {
        System.out.println("警告!有人创建了对象!对象内存地址: " + this);
    }

    public Human() {
        System.out.println("此人使用了[无参]构造器创建对象");
    }

    public Human(int age) {
        System.out.println("此人使用了[含参]构造器创建对象");
    }
}
6. 单例设计模式

什么是设计模式?

  • 一个问题通常有n种解法,其中肯定是有一种最优解法,这种解法被人总结出来了,称之为设计模式
  • 设计模式有20多种,对应20多种软件开发中会遇到的问题

单例设计模式

  • 要求:确保一个类只有一个对象
  • 饿汉式单例:拿对象时,对象早就创建好了
  • 懒汉式单例:拿对象时,才开始创建对象
// 饿汉式单例

public class HelloWorld {
    public static void main(String[] args) {
        Human obj1 = Human.getObj();
        Human obj2 = Human.getObj();
        System.out.println(obj1 == obj2);  // true
    }
}

class Human {
    private static Human obj = new Human();  // 此行代码只会在类加载时,执行一次

    private Human() {
        
    }

    public static Human getObj() {
        return obj;
    }
}
// 懒汉式单例

public class HelloWorld {
    public static void main(String[] args) {
        Human obj1 = Human.getObj();
        Human obj2 = Human.getObj();
        System.out.println(obj1 == obj2);  // true
    }
}

class Human {
    private static Human obj;

    private Human() {

    }

    public static Human getObj() {
        if (Human.obj == null) {
            obj = new Human();
        }
        return obj;
    }
}

你可能感兴趣的:(Java进阶,java)