类变量和类方法
问题是:有一群小孩在玩堆雪人,不时有新的小孩加入,这请问如何知道现在共有多少在玩?
使用我们现有的技术来解决这个问题,包名:com.haikang.static_.ChildGame.java
思路:
- 在
main
方法中定义一个变量count
- 当一个小孩加入了后
count++
,最后个count
就记录了有多少小孩玩游戏
package JAVA面向对象高级部分.static_;
public class ChildGame {
public static void main(String[] args) {
int count = 0;
PloyGame game = new PloyGame("白骨精");
game.join();
count++;
PloyGame game1 = new PloyGame("狐狸精");
game1.join();
count++;
System.out.println("总共有"+count+"个小孩加入了游戏!");
}
}
class PloyGame{
private String name;
public PloyGame(String name) {
this.name = name;
}
public void join(){
System.out.println(name+"加入了游戏!");
}
}
问题分析:
count
是一个独立于对象的变量,就是main
方法中的局部变量- 以后我们访问
count
很不方便,没有使用到OOP
- 因此,我们引出类变量(静态变量)
静态变量的快速入门
如果:设计了一个int count
表示总人数,我们在创建一个小孩时,就把count
加1,并且count
是所有对象共享的,我们使用类变量来解决ChildGame.java
改进
package JAVA面向对象高级部分.static_;
public class ChildGame {
public static void main(String[] args) {
//int count = 0;
PloyGame.count++;
PloyGame game = new PloyGame("白骨精");
game.join();
//count++;
PloyGame.count++;
PloyGame game1 = new PloyGame("狐狸精");
game1.join();
//count++;
PloyGame.count++;
System.out.println("总共有"+PloyGame.count+"个小孩加入了游戏!");
}
}
class PloyGame{
private String name;
//定义一个变量count,是一个类变量(静态变量)static
//该变量最大的特点是被PloyGame类所有的对象实例共享
public static int count = 0;
public PloyGame(String name) {
this.name = name;
}
public void join(){
System.out.println(name+"加入了游戏!");
}
}
静态变量(类变量)是在类加载时,就已经产生了
在JDK8
以前,静态变量是存在在方法区的静态域中,在JDK8
后,静态变量存在堆中
不管静态变量存在哪里都有以下两个结论:
static
变量是同一个类所有对象共享的static
静态变量,是在类加载时就生成了
静态变量是随着类的加载时,就创建一个class对象
在class对象中就有静态变量,静态变量作用域是对整个类
什么是类变量(记住)
类变量也叫静态变量或静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。
如何定义变量
定义语法:
访问修饰符 static 数据类型 变量名
【推荐】
static 访问修饰符 数据类型 变量名
如何访问类变量
类名.类变量名
或者对象名.类变量名
推荐使用: 类名.类变量名
【静态变量的访问修饰符的访问权限和范围和普通属性是一样的】
package JAVA面向对象高级部分.static_;
public class VisitStatic {
public static void main(String[] args) {
System.out.println(StaticVar.name);
}
}
class StaticVar{
//静态变量也要遵守访问修饰符
//静态变量是随着类加载而创建的
//类加载时对象还没有创建,所以可以通过类名.静态变量名直接调用,也可以通过对象名调用
public static String name = "海康";
}
小结:(1)静态变量也要遵守访问修饰符 (2)静态变量是随着类加载而创建的 (3)类加载时对象还没有创建,所以可以通过类名.静态变量名直接调用,也可以通过对象名调用
静态变量是随着类的加载时,就创建一个class对象
在class对象中就有静态变量,静态变量作用域是对整个类
**类变量使用注意事项和细节说明(必须记住)**七点
1.什么时候需要用类变量:当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义学生类,统计所有学生共交了多少钱。
2.类变量与实例变量(普通属性)区别
类变量是该类的所有对象共享的,而实例变量是每个对象独享的
3.加上static
称为类变量或静态变量,否则称为:实例变量,普通变量,非静态变量
4.类变量可以通过类名.类变量名 或 对象名.类变量名
来访问,但java
设计者推荐我们使用类名.类变量名方式访问
。
5.实例变量不能通过类名.类变量名
方式访问
6.类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了
7.类变量的生命周期是随着类的加载开始,随着类消亡而销毁
类方法基本介绍
类方法也叫静态方法
语法:
访问修饰符 static 数据返回类型 方法名(){}
【推荐】
static 访问修饰符 数据返回类型 方法名(){}
类方法的调用:
使用方式:类名.类方法名 或者 对象名.类方法名
【前提是:满足访问修饰符的访问权限和范围】
案例:静态方式统计学费总和
package JAVA面向对象高级部分.static_;
public class StaticDetailed {
public static void main(String[] args) {
Student student01 = new Student("海康",5168);
System.out.println(Student.fee);
}
}
class Student{
public static double fee = 0;//费用
private String name;
public Student() {
}
public Student(String name,double fee) {
this.name = name;
this.fee = fee;
}
public static double getFee() {
return fee;
}
public static void setFee(double fee) {
Student.fee = fee;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 1.当方法使用了static修饰后,该方法就是静态方法
* 2.静态方法就可以访问静态属性(静态变量)
*/
public void showFee(){
System.out.println("收到的总学费="+Student.fee);
}
}
类方法经典的使用场景
当方法中涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。
比如:工具类中的方法 utils
小结:在程序员实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用了,比如打印一维数组,冒泡排序,完成某个计算任务
案例:
package JAVA面向对象高级部分.static_;
public class StaticMethod {
public static void main(String[] args) {
//使用静态方法产生的工具类
int[] arr = {11,88,86,99,168,43,168};
MyStaticMethod.print(arr);
int[] sort = MyStaticMethod.sort(arr);
MyStaticMethod.print(sort);
System.out.println(MyStaticMethod.sum(43, 86, 168));
}
}
//开发自己的工具类时,可以将方法做成静态的,方便调用
class MyStaticMethod{
//打印一维数组
public static void print(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
System.out.println();
}
//冒泡排序
public static int[] sort(int[] arr){
int tmp = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if (arr[j]>=arr[j+1]){
tmp = arr[j] ;
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
return arr;
}
//计算某几个值的变量
public static int sum(int...n){
int sum = 0;
for (int i = 0; i < n.length; i++) {
sum += n[i];
}
return sum;
}
}
类方法使用注意事项和细节说明(记住)六点
1.类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区:类方法无this
的参数,普通方法中隐含着this
的参数
2.类方法可以通过类名调用,也可以通过对象名调用
3.普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数)
,不能通过类名调用
4.类方法中不允许使用和对象有关的关键字,比如this
和super
。普通方法(成员方法)可以
5.类方法(静态方法)中,只能访问静态方法或静态属性
6.普通成员方法,既可以访问,非静态成员(非静态方法和非静态属性),也可以访问静态成员(静态方法和静态成员)
小结:(1)类方法和普通方法是随着类的加载而加载的,将结构信息存储在方法区(2)静态方法,只能访问静态成员(静态属性和静态方法)(3)非静态方法,可以访问静态成员和非静态成员(必须遵守访问权限),类方法没有this
和super
关键字
练习题:
输出什么
public class Test{
static int count = 9;
public void count(){
System.out.println("count="+(count++));
}
public static void main(String args[]){
new Test().count();//9
new Test().count();//10
System.out.println(Test.count);//11
}
}
题目2:看看下面代码有没有错误,如果有错误,就修改,看看total等于多少
class Person {
private int id;
private static int total = 0;
public static int getTotalPerson(){
id ++;//报错,应该将ID属性修改成静态的,ID为1
return total;//0
}
public Person{
total++;
id = total;//id为1,后total为1
}
}
public class TestPerson{
public static void main(String[] args){
System.out.println("Number of total is"+Person.getTotalPerson());//0
Person p1 = new Person();
System.out.println("Number of total is"+Person.getTotalPerson());//1
}
}
题目3:看看下面代码有没有错误,如果有错误,就修改,看看total等于多少
class Person{
private int id;
private static int total = 0;
public static void setTotalPerson(int total){
this.total = total;//错误,静态方法中没有this关键字,将此行注释
Person.total = total;//3
}
public Person{
total++;//4
id = total;//4
}
}
public class TestPerson{
public static void main(String[] args){
Person.setTotalPerson(3);
new Person();
//所以最后total为4
}
}
小结:(1)静态方法,只能访问静态成员(成员方法和成员属性)(2)非静态方法,可以访问所有的成员(3)仍然要遵守访问权限规则