静态Static
静态资源
静态资源
属性 和 方法 可以被标记为 static。
代表 不需要对象 依附于类
有没有对象都无所谓,有类 就有静态资源
名词
静态 / 非静态
案例
1 2 3 public class Cla { public static int a = 3;}
1 2 3 4 5 public class Dla { psvm { Cla.a = 4; }}
与 final 结合 表达全局常量
1 2 3 public class Math { public static final double PI = 3.1415926...;}
静态资源 共享特性
唯一性
一个类 不管有多少个对象 都只为一个静态属性 开一个数据格
相比而言, 一个非静态属性, 会为每个对象开数据格
共享特性
因为唯一,所以所有对象共享
案例
使用 静态属性追踪自增 id
1 2 3 4 5 6 7 8 9 10 public class Item { private static int currentId = 0; private int id; public Item() { id = currentId; currentId ++; }}
静态资源 全局特性
全局性
因为唯一,所以全局
与 public 组合使用 表达全局属性
public 哪都能访问
static 一个类就一个
1 2 3 4 5 public class Driver { public void run() { Board.size = 15; }}
1 2 3 4 5 public class Board { public void test() { Console.println(Board.size); }}
将 Model 标记为 静态
可以将一些 Model 层数据标记为 静态资源
从而减少数据在 Controller 之间传输的代码
静态资源 访问规则
外部 访问 静态资源
静态资源所在地 和 需要调用的地方 不是一个类
类名引导
主推
1 2 3 public class S { public static int a = 3;}
1 2 3 4 5 6 7 8 public class A { public void func1() { S.a = 4; } public static void func2() { S.a = 4; }}
S 类型的变量引导
不好但合法
1 2 3 public class S { public static int a = 3;}
1 2 3 4 5 6 public class A { public void func1() { S s = new S(); s.a = 10; }}
内部 访问 静态资源
静态资源所在地 和 需要调用的地方 是一个类
类名引导
推荐 1
1 2 3 4 5 6 public class S { public static int a = 3; public void f() { S.a = 2; }}
使用 this 引导
不好但合法
1 2 3 4 5 6 public class S { public static int a = 3; public void f() { this.a = 2; }}
省略引导
等效于 类名 引导
推荐 2
1 2 3 4 5 6 public class S { public static int a = 3; public void f() { a = 2; }}
静态函数内 访问 其它资源
static 方法内 不能使用 this
无法在 static 方法内 访问 内部的 非 static 资源
1 2 3 4 5 6 7 8!9!10!11 12 13 14 15 public class Cla { public int instanceVar = 1; public static int staticVar = 1; public void instanceMethod() { a = 2; } public static void staticMethod() { instanceVar = 1; this.instanceVar = 1; Cla.instanceVar = 1; staticVar = 1; this.staticVar = 1; Cla.staticVar = 1; }}
但可以 在 static 方法内 访问 有对象的 任何资源
1 2 3 4 5 6 7 8 9 10 11!12 13 14 public class Cla { public int instanceVar = 1; public static int staticVar = 1; public void instanceMethod() { a = 2; } public static void staticMethod() { Cla a = new Cla(); a.instanceVar = 1; a.staticVar = 1; Cla.instanceVar = 1; Cla.staticVar = 1; }}
静态绑定Static Binding
什么是
静态方法,会在编译时确定下来,不会在运行时再确定
静态方法,不会被方法覆盖
1 2 3 4 5 public class Animal { public static void func() { Console.println("Animal func") }}
1 2 3 4 5 public class Person extends Animal { public static void func() { Console.println("Person func") }}
1 2 3 4 5 6 7 8 9 10 11 12 public class Main { public void run() { Person.func(); Animal.func(); Person person = new Person(); person.func(); Animal animal = new Person(); animal.func(); }}
静态初始化块Static Initialization Blocks
案例
属性可以直接赋值
1 2 3 public class Cla { private int num = 10;}
复杂时,可以转移到构造方法里
1 2 3 4 5 6 7 8 9 10 public class Cla { private LinkedList<Integer> nums; public Cla() { nums = new LinkedList<Integer>(); for (int i = 0; i < 10; i++ ) { nums.add(i); } }}
静态属性初始化
1 2 3 4 5 6 7 8 9 10 public class Cla { private static LinkedList<Integer> nums; static { nums = new LinkedList<Integer>(); for (int i = 0; i < 10; i++ ) { nums.add(i); } }}
静态属性开辟空间之后,会被调用一次
之后每次创建对象都不会调用这块的代码
大总结
三大关系
有 组合
代码重用
1 2 3 4 5 6 7 public class Player { private Weapon weapon; private int atk; public int totalAtk() { ... }}
是 继承
代码重用 + 多态
1 2 3 4 5 public class Person extends Animal { public void think() { ... }}
能 接口
多态
1 2 3 4 5 public class Mage implements Attacking { public void attack(...) { ... }}
建议
谨慎使用继承
三大特性
封装 Encapsulation
调用方 不知道 也不该知道 具体实现的细节
继承 Inheritance
代码重用 + 多态
其实 接口 和 组合更好
多态 Polymorphism
调用方 不知道 也不该知道 具体调到了哪个代码
完整结构
类
public class 类名 extends 父类 implements 接口列表 { 静态属性; static { ... } 静态方法(){ ... } 属性; { ... } 构造方法(){ } 方法(){ } }
接口
public interface 接口名 extends 接口列表 { 静态属性; static { ... } 静态方法(){ ... } 方法(); }