一、类属性
-
类属性
- 当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性
- 当一个属性被声明成类属性,那么所有的对象,都共享一个值
- 与对象属性(对象属性:又叫实例属性,非静态属性)对比:
- 不同对象的 对象属性 的值都可能不一样。
- 比如盖伦的hp 和 提莫的hp 是不一样的。
- 但是所有对象的类属性的值,都是一样的
-
例子:
- 给英雄设置一个类属性叫做“版权" (copyright), 无论有多少个具体的英雄,所有的英雄的版权都属于 Riot Games公司。
访问类属性有两种方式
- 对象.类属性(通过 对象 修改类属性)
gaRen.copyright
- 类.类属性(通过 类 修改类属性)
Hero1.copyright
- 这两种方式都可以访问类属性,访问即修改和获取,但是建议使用第二种 类.类属性 的方式进行,这样更符合语义上的理解
public class Hero1 {//英雄类 private String name;//实例属性,对象属性,非静态属性 public int hp; public static String copyright;//static静态属性,类属性 //main()方法 public static void main(String[] args) { Hero1 gaRen = new Hero1(); gaRen.name = "盖伦"; Hero1 teeMo = new Hero1(); teeMo.name = "提莫"; Hero1.copyright = "版权由Riot Games公司所有";//通过 类 修改类属性;下面输出的都为"版权由Riot Games公司所有" System.out.println(gaRen.name);//盖伦 System.out.println(gaRen.copyright);//版权由Riot Games公司所有 System.out.println(teeMo.name);//提莫 System.out.println(teeMo.copyright);//版权由Riot Games公司所有 gaRen.copyright = "英雄的版权属于 Riot Games公司";//通过 对象 修改类属性;下面输出的都为"英雄的版权属于 Riot Games公司" System.out.println(gaRen.name);//盖伦 System.out.println(gaRen.copyright);//英雄的版权属于 Riot Games公司 System.out.println(teeMo.name);//提莫 System.out.println(teeMo.copyright);//英雄的版权属于 Riot Games公司 //类属性又叫静态属性,在方法区和类一起加载,所有的对象都可以调用并共享一个值,只要修改了类属性,所有对象的此类属性都修改 } }
- 对象.类属性(通过 对象 修改类属性)
- 给英雄设置一个类属性叫做“版权" (copyright), 无论有多少个具体的英雄,所有的英雄的版权都属于 Riot Games公司。
-
什么时候使用对象属性,什么时候使用类属性
- 如果一个属性,每个英雄都不一样,比如name,这样的属性就应该设计为对象属性,因为它是跟着对象走的,每个对象的name都是不同的
- 如果一个属性,所有的英雄都共享,都是一样的,那么就应该设计为类属性。比如血量上限、版权等;所有的英雄的血量上限都是 9999,不会因为英雄不同,而取不同的值;所有英雄的版权属于 Riot Games公司。 这样的属性,就适合设计为类属性
二、类方法
-
类方法
- 类方法: 又叫做静态方法(访问 类方法,不需要对象的存在,直接就访问)
- 对象方法: 又叫实例方法,非静态方法(访问一个 对象方法,必须建立在有一个对象的前提的基础上)
-
例子:
- 测试类方法和对象方法
调用类方法有两种方式
- 对象.类方法
geRen.battleWin(geRen);
- 类.类方法
Hero1.battleWin(geRen);
- 这两种方式都可以调用类方法,但是建议使用第二种 类.类方法 的方式进行,这样更符合语义上的理解。
- 并且在很多时候,并没有实例,比如在前面练习的时候用到的随机数的获取办法
Math.random() //random()就是一个类方法,直接通过类Math进行调用,并没有一个Math的实例存在。
public class Hero1 {//英雄类 public String name; protected int hp; //实例方法(对象方法),非静态方法 //必须有对象才能调用 public void die(Hero1 hero1){//英雄死亡,hp为0 this.hp = 1; } //类方法,静态方法 //通过类就可以直接调用 public static void battleWin(Hero1 hero1){ System.out.println(hero1.name+"战斗胜利"); } //main()方法 public static void main(String[] args) { Hero1 geRen = new Hero1(); geRen.name = "盖伦"; //必须有一个对象才能调用die,因为是对象方法 geRen.die(geRen); System.out.println(geRen.name);//盖伦 System.out.println(geRen.hp);//1 //无需对象,直接通过类调用,因为是类方法 Hero1.battleWin(geRen);//盖伦战斗胜利 //==================================================================== //下面同理 Hero1 teMoo = new Hero1(); teMoo.name = "提莫"; teMoo.die(teMoo); System.out.println(teMoo.name);//提莫 System.out.println(teMoo.hp);//1 Hero1.battleWin(teMoo);//提莫战斗胜利 } }
- 对象.类方法
- 测试类方法和对象方法
-
什么时候设计对象方法,什么时候设计类方法
- 如果在某一个方法里,调用了对象属性,比如:
name属性是对象属性,只有存在一个具体对象的时候,name才有意义。 如果方法里访问了对象属性,那么这个方法,就必须设计为对象方法public String getName(){ return name; }
- 如果一个方法,没有调用任何对象属性,那么就可以考虑设计为类方法,比如:
printGameDuration 打印当前玩了多长时间了,不和某一个具体的英雄关联起来,所有的英雄都是一样的。 这样的方法,更带有功能性色彩public static void printGameDuration(){ System.out.println("已经玩了10分50秒"); }
——就像取随机数一样,random()是一个功能用途的方法
- 如果在某一个方法里,调用了对象属性,比如:
注意点
- 在一个类方法中,直接调用一个对象方法,比如在battleWin中调用die(),能否直接调用? 为什么?
- 不能调用。静态方法、静态属性都是跟着类加载就已经加载了,此时还没有创建对象,所以静态方法里不能调用非静态方法。但是反过来对象方法是随着对象的出生而出生的,所以它比静态方法出生的要晚,因此对象方法中可以调用静态方法。
- 通俗的话来讲就是 早出生的不能知道晚出生的性别,晚出生的可以知道早出生的性别。就好比你还没出生的时候,你爸不一定知道你是男是女,但是你一定知道你爸是男是女。