01.java面向对象高级-类变量和类方法
1. 类变量
1. 基本介绍
类变量,也被称为静态变量,是在 Java 类中定义的变量,与类本身相关联,而不是与类的实例(对象)相关联。每个类变量只有一份副本,无论创建多少个类的实例,这些实例都共享相同的类变量。
通俗一点来讲将其比喻为某个班级的共享信息。假设你在一个学校,有很多班级,每个班级有很多学生。班级的名称、学校的地址等信息是所有学生共享的,就像在 Java 中的类变量一样。备注:举个例子,如果你想知道学校的地址,你只需访问学校这个实体的地址,而不需要问每个学生,因为它是共享的。
为了生动形象的描述让我们来看一个案例:(ChildGame.java)
public class ChildGame {
public static void main(String[] args) {
int count = 0;
//定义一个变量count,统计有多少小孩加入游戏
Child child1 = new Child("小白");
child1.join();
count++;
Child child2 = new Child("小狐");
child2.join();
count++;
Child child3 = new Child("小风");
child3.join();
count++;
System.out.println("共有" + count + "个小孩加入了游戏");
}
}
class Child {
private String name;
public Child(String name) {
this.name = name;
}
public void join() {
System.out.println(name + " 加入了游戏");
}
}
如上问题我们解决了一个加入游戏的问题:每加入一个小孩我们就使变量count加1,但是这样有个问题,是没用用到面向对象编程,而且假如这是一个项目,我们修改这个变量就会不简单。
2.类变量的引入
让我们来改进ChildGame.java 使用类变量来解决
public class ChildGame {
public static void main(String[] args) {
Child child1 = new Child("小白");
child1.join();
child1.count++;
Child child2 = new Child("小狐");
child2.join();
child2.count++;
Child child3 = new Child("小风");
child3.join();
child3.count++;
//类变量, 可以通过类名来访问
System.out.println("共有" + Child.count/*随便用哪个对象child1、2、3 都是正确的*/ + "个小孩加入了游戏");
}
}
class Child {
private String name;
//定义一个变量 count,是一个类变量(静态变量) static 静态
//该变量最大的特点就是会被所有创建的对象共享
public static int count = 0;
public Child(String name) {
this.name = name;
}
public void join() {
System.out.println(name + " 加入了游戏");
}
}
通过对类变量的引用,解决了这个问题,可能你会觉得麻烦,后面会解决这个问题。
2.类变量详解
1. 什么是类变量
前面我已经描述过什么是类变量,现在我再具体描述一下,类变量也叫静态变量/静态属性,是该类的对象去访问他时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。
2. 如何定义类变量
定义语法:
访问修饰符 static 数据类型 变量名;
static 访问修饰福 数据类型 变量名;
3. 如何访问类变量
类变量.类变量名
或者 对象名.类变量名(静态变量的访问修饰符的访问权限和范围 和 普通属性都是一样的)
推荐使用 类名.变量名;
public class VisitStatic {
public static void main(String[] args) {
//类名.类变量
//说明:类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问
System.out.println(A.name);
A a = new A();
//通过对象名.类变量名
System.out.println("a.name" + a.name);
}
}
class A {
//类变量的访问:必须遵守 相关的访问权限
public static String name = "yzj";
}
3.类变量使用注意事项和细节
1. 什么时候需要用类变量
- 当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量): 比如:定义学生类,统计所有学生共交多少钱.Student(name, fee)
- 类变量与实例变量(普通属性的区别)
类变量是该类的所有对象共享的,而实例变量时每个对象独享的. - 加上static称为类变量或者静态变量,其他类称为实例变量/普通变量/非静态变量
- 类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,但是推荐使用类名.类变量名。**前提:**满足访问修饰符的访问权限
- 实例变量不能通过 类变量.类变量名 方式访问.
- 类变量是在类加载的时候就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了
- 类变量的生命周期是随类的加载开始,随着类的消亡而销毁.
public class StaticDetail {
public static void main(String[] args) {
B b = new B();
// System.out.println(B.n1);//非静态,不能直接 用B.n1 访问
System.out.println(B.n2);
//类变量是在类加载的时候就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了
System.out.println(C.address);
}
}
class B {
public int n1 = 100;
public static int n2 = 200;
}
class C {
public static String address = "天津";
}
4.类方法
1. 类方法基本介绍
类方法也叫静态方法
形式如下:
访问修饰符 static 数据返回类型 方法名() { }(推荐)
static 访问修饰符 数据返回类型 方法名() { }
2. 类方法的调用
使用方式:类名.类方法名 或者 对象名.类方法名
3. 类方法案例
/**
* 类方法
**/
public class StaticMethod {
public static void main(String[] args) {
//测试:创建两个对象
Student tom = new Student("tom");
tom.payFee(100);
Student marry = new Student("marry");
marry.payFee(200);
//输出当前收到的总学费
Student.showFee();
}
}
class Student {
private String name;//普通属性
//定义一个静态变量,来累计学费
private static double fee = 0;
public Student(String name) {
this.name = name;
}
//说明:
//1. 当方法使用了static修饰后,该方法就是静态方法
//2. 静态方法就可以访问静态变量
public static void payFee(double fee) {
Student.fee += fee;
}
public static void showFee() {
System.out.println("总学费有: " + Student.fee);
}
}
4. 类方法的经典的使用场景
当方法中不涉及到任何和对象相关的成员,则可以设计成静态方法,提高设计效率。
比如:工具类中的方法 utils
Math类、Arrays类、Collections集合类
假如我们要创建自己的工具类 举例:
class myTools {
//求出两个数的和
public static double calSum(double n1, double n2) {
return n1 + n2;
}
}
5. 类方法的使用注意事项和细节讨论
- 类方法和普通方法都是通过类的加载而加载,将结构信息存储在方法区:
类方法中无this的参数
普通方法中隐含着this的参数 - 类方法可以通过类名调用,也可以通过对象名调用
- 普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。
- 类方法中不允许使用和对象有关的关键字,比如this和super。普通方法可以(成员方法)可以。
- 类方法(静态方法)中 只能访问静态变量 或静态方法。
- 普通成员方法,既可以访问 普通变量(方法),也可以访问静态变量(方法)
案例:
/**
* 类方法的细节
**/
public class StaticMethodDetail {
public static void main(String[] args) {
D.hi();
//非静态方法,不能通过类名调用
//D.say; 错误的调用 需要创建对象 然后调用
D d = new D();
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();
//say();//错误
}
//普通成员方法,既可以访问 非静态成员,也可以访问静态成员
public void ok() {
//非静态成员
System.out.println(n1);
say();
//静态成员
System.out.println(n2);
hi();
}
}