面向过程:强调的是功能行为(比如,打球,就是专注于打球的动作) 面向对象:打球的动作归属于谁?人,所以就会有一个人的对象。人的对象包含了一个打球的动作 面向对象的三大特性:封装,继承,多态。
一个类型由其包含的属性以及改类型可以进行的操作组成,属性又可以分为是类型本身具有的属性,还是一个具体实例有的属性,同样,操作也可以分为类型本身可以进行的操作,还是一个具体实例可以进行的操作。 这样:一个数据类型就就主要由四个部分组成(实例也成为对象):
类型本身具有的属性,通过类变量体现类型本身具有的操作,通过类方法体现类型实例具有的属性,通过实例变量体现类型实例具有的属性,通过实例方法体现 类变量和实例变量 类变量(也叫静态变量或静态成员变量)实例变量修饰以static修饰不以static修饰定义定义在类中,在整个类中都可以被访问定义在类中,在整个类中都可以被访问访问`类名.类变量`或者`实例引用.类变量`,所有对象公用一个变量 只能被用**static修饰的类调用** 只能通过`实例引用.变量` 给英雄设置一个类属性叫做“版权" (copyright), 无论有多少个具体的英雄,所有的英雄的版权都属于 Riot Games公司。 ```java package charactor; public class Hero { public String name; //实例属性,对象属性,非静态属性 protected float hp; static String copyright;//类属性,静态属性 public static void main(String[] args) { Hero garen = new Hero(); garen.name = "盖伦"; Hero.copyright = "版权由Riot Games公司所有"; System.out.println(garen.name); System.out.println(garen.copyright); Hero teemo = new Hero(); teemo.name = "提莫"; System.out.println(teemo.name); System.out.println(teemo.copyright); } }补充: 这两种方式都可以访问类属性,访问即修改和获取,但是建议使用第二种 类.类属性 的方式进行,这样更符合语义上的理解 如果teemo.copyright = “Fan”,那么所有对象的copyright属性都会被改变
对象属性对比: 不同对象的 对象属性 的值都可能不一样。比如盖伦的hp 和 提莫的hp 是不一样的。 但是所有对象的类属性的值,都是一样的
访问类属性
一、对象.类属性 teemo.copyright 二、类.类属性 Hero.copyright成员变量(属性)和局部变量的区别? ●成员变量: ➢成员变量定义在类中,在整个类中都可以被访问。 ➢成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存 中。 ➢成员变量有默认初始化值。 ➢成员变量的权限修饰符可以根据需要,选择任意-一个 ●局部变量: ➢局部变量只定义在局部范围内,如:方法内,代码块内等。 ➢局部变量存在于栈内存中。 ➢作用的范围结束,变量空间会自动释放。 ➢局部变量没有默认初始化值,每次必须显式初始化。 ➢局部变量声明时不指定权限修饰符
类方法和实例方法 类方法实例方法,又叫对象方法、非静态方法修饰以static修饰不以static修饰定义定义在类中定义在类中访问访问类方法,不需要对象的存在,直接就访问访问 对象.类方法(是错误的,只能通过类名.类方法) 访问一个对象方法,必须建立在有一个对象的前提的基础上声明类方法:
public static void battleWin(){ System.out.println("battle win"); }声明实例方法:
public void die(){ hp = 0; } '访问类方法可以没有对象' Hero garen = new Hero(); Hero.battleWin(); "访问实例方法必须要有对象" garen.name = "盖伦"; //必须有一个对象才能调用 garen.die();什么时候设计对象方法,什么时候设计类方法 如果访问了对象属性,那么这个方法,就必须设计为对象方法;如果一个方法,没有调用任何对象属性,那么就可以考虑设计为类方法 总结:
类方法只能访问类变量,不能访问实例变量,可以调用其他类方法,不能调用实例方法(也就是说以static 修饰的方法,只能调用用static修饰的变量或者方法)实例方法既可以访问实例变量又可以访问类变量,既可以调用实例方法,也可以调用类方法(也就是说在实例方法中使用变量和方法没有限制)如果一个变量的类型是 类类型,而非基本类型,那么该变量又叫做引用。
new Hero();是创建了一个Hero对象,但是无法访问它。 要访问这个对象,必须使用引用来代表这个对象
Hero h = new Hero();h这个变量就是Hero类型的,又叫做引用,也成为引用类型的变量。=的意思指的h这个引用指向右侧创建的对象 注意: 这个变量和数组变量是 类似的,都有两块内存:一块存放实际内容(在堆中),一块存放实际的内容的位置(地址)(在栈中)。 多个引用,一个对象
//使用一个引用来指向这个对象 Hero h1 = new Hero(); Hero h2 = h1; //h2指向h1所指向的对象 Hero h3 = h2; //h1,h2,h3五个引用,都指向同一个对象一个引用,多个对象 引用garen指向新创建的对象(对象1) 同一个引用garen指向新创建的对象(对象2) 这个时候,对象1,就没有任何引用指向了
Hero garen = new Hero();//对象1 garen = new Hero();//对象2例子:其中h4,h3,h1都指向一个对象。h2单独指向一个对象
package charactor; public class Hero { public String name; protected float hp; public static void main(String[] args) { Hero h1 = new Hero(); Hero h2 = new Hero(); Hero h3; Hero h4; h3 = h1; h4 = h3; } }所有的引用类型都会分配一个默认值,与创建数组时候类似:
数值类型初始值是0; booblean是false; char是"/u0000"; 引用类型变量都是null,表示不指向任何对象。当然可以以通过初始化修改这些默认值–>:
对象属性初始化: 对象属性初始化有3种
声明该属性的时候初始化构造方法中初始化初始化块 public String name = "some hero"; //声明该属性的时候初始化 protected float hp; float maxHP; { maxHP = 200; //初始化块 } public Hero(){ hp = 100; //构造方法中初始化 }类属性初始化
声明该属性的时候初始化静态初始化块 public static int itemCapacity=8; //声明的时候 初始化 static{ itemCapacity = 6;//静态初始化块 初始化 }在LOL中,武器是物品的一种,也是有名称和价格的 所以在设计类的时候,可以让武器继承物品,从而继承名称和价格属性 继承格式:
public class Weapon extends Item{ int damage; //攻击力 public static void main(String[] args) { Weapon infinityEdge = new Weapon(); infinityEdge.damage = 65; //damage属性在类Weapon中新设计的 infinityEdge.name = "无尽之刃";//name属性,是从Item中继承来的,就不需要重复设计了 infinityEdge.price = 3600; } }继承的说明: 1)●作用: ➢继承的出现提高了代码的复用性。 ➢继承的出现让类与类之间产生了关系,提供了多态的前提。 ➢不要仅为了获取其他类中某个功能而去继承| 继承是要有逻辑关系在里面的,不要随意继承 2) ●说明: ➢子类继承了父类,就继承了父类的方法和属性。 ➢在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。 ➢在Java中, 继承的关键字用的是“extends",即子类不是父类的子集,而是对父类的 “扩展” 3)●关于继承的规则: ➢子类不能直接访问父类中私有的(private)的成员变量和方法。 ➢一个类只能继承一个父类,java不支持多重继承
对不能让调用者随意使用的属性做封装和隐藏: 如:
private int age;//私有化,将其保护起来,不让其他只允许类内部使用 public int getAge(){ return age; } public void setAge(int s){//提供设置年龄的方法,自己类内可以访问私有的属性,以形成封装 if(s>150 && s>=0) age = a; else{ System.out.print(""输入年龄不合法) } }这样其他类里面访问的时候,就只能通过setAge设置年龄,并对其进行检查。
方法重写: ●定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法(只能重写非private 方法)。 ●要求: 子类重写父类的方法,只是重写编写方法体的代码 如果父类的方法是public的, 子类重写的时候就不能使用缺省以下 ➢重写方法必须和被重写方法具有相同的方法名称、寥数列表和返回值类型。 ➢重写方法不能使用比被重写方法更严格的访问权限。 ➢重写和被重写的方法须同时为static的,或同时为非static的 ➢子类方法抛出的异常不能大于父类被重写方法的异常
方法的重载指的是方法名一样,但是参数类型不一样 有一种英雄,叫做物理攻击英雄 ADHero 为ADHero 提供三种方法
方法名是一样的,但是参数类型不一样 在调用方法attack的时候,会根据传递的参数类型以及数量,自动调用对应的方法
package j2se; public class ADHero extends Hero{ public void attack(){ System.out.println(name+"进行了一次攻击 ,但是不确定打中谁了"); } public void attack(Hero h1){ System.out.println(name+"对"+h1.name+"进行了一次攻击"); } public void attack(Hero h1,Hero h2){ System.out.println(name + "同时对" + h1.name + "和" + h2.name + "进行了攻击 "); } public static void main(String[] args){ ADHero bh = new ADHero(); bh.name="寒冰"; bh.hp = 1500; Hero h1 = new Hero(); h1.name = "盖伦"; Hero h2 = new Hero(); h2.name = "提莫"; bh.attack(); bh.attack(h1); bh.attack(h1,h2); } } '结果:' 寒冰进行了一次攻击 ,但是不确定打中谁了 寒冰对盖伦进行了一次攻击 寒冰同时对盖伦和提莫进行了攻击如果要攻击更多的英雄,就需要设计更多的方法,这样类会显得很累赘,参数过多。 这时,可以采用可变数量的参数 只需要设计一个方法
public void attack(Hero ...heros)其他数据类型时: 体会可变个数的形参: //下面采用数组形参来定义方法
public static void test(int a ,tring[] books);//以可变个数形参来定义方法
public static void test(int a ,tring..books);说明: 1.可变参数:方法参数部分指定类型的参数个数是可变多个 2.声明方式:方法名(参数的类型名…参数名) 3.可变参数方法的使用与方法参数部分使用数组是一致的 4.方法的参数部分有可变形参,需要放在形参声明的最后
'数组方式:' public void test(String[] args){ for(String each: args){ System.out.println(each) } } String[] t = new String[]{"1","2","3"} test(t) 'java特有的...方式传递可变参数,使用方式和数组相同:' public void test(String... args){ for(String each: args){ System.out.println(each) } } String[] t = new String[]{"1","2","3"} test(t) '或者' test("3","2","6","5") '有多个参数时,可变参数要放在最后 ' public void test(int i,float... y){}即可代表上述所有的方法了 在方法里,使用操作数组的方式处理参数heros即可
public class ADHero extends Hero { public void attack() { System.out.println(name + " 进行了一次攻击 ,但是不确定打中谁了"); } // 可变数量的参数 public void attack(Hero... heros) { for (int i = 0; i < heros.length; i++) { System.out.println(name + " 攻击了 " + heros[i].name); } } public static void main(String[] args) { ADHero bh = new ADHero(); bh.name = "赏金猎人"; Hero h1 = new Hero(); h1.name = "盖伦"; Hero h2 = new Hero(); h2.name = "提莫"; bh.attack(h1); bh.attack(h1, h2); } }当有多个重名函数的时候,在决定要调用哪个函数的过程中,首先是按照参数类型进行匹配的,换句话说,寻找在所有重载版本中最匹配的(在父类中也寻找),然后才看变量的动态类型,进行动态绑定(父类引用a指向子类对象,然后用a.调用子类重写过得实例方法的过程叫做动态绑定)。
构造器 (new对象实际上就是调用类的构造方法) ●根据参数不同,构造器可以分为如下两类: ➢隐式无参构造器(系统默认提供) ➢显式定义一个或多个构造器(无参、有参) ●注意: ➢Java语言中,每个类都至少有一-个构造器 ➢默认构造器的修饰符与所属类的修饰符–致 ➢旦显式定义了构造器,则系统不再提供默认构造器 ➢一个类可以创建多个重载的构造器 ➢父类的构造器不可被子类继承
通过一个类创建一个对象,这个过程叫做实例化 实例化是通过调用构造方法(又叫做构造器)实现的。 相当于在实例化的时候赋值。相当于python中s = Std("Fan",26).
定义: 1、方法名和类名一样(包括大小写) 2、没有返回类型,也不能有返回值。(构造方法隐含的返回值就是实例本身) 实例化一个对象的时候,必然调用构造方法 默认的构造方法前面有没有访问修饰符,和定义的类有关,类是pulic,默认的构造方法就是public,默认的类是缺省的。默认的构造方法就是缺省的。
public class Hero { String name; // 方法名和类名一样(包括大小写) // 没有返回类型 public Hero() { System.out.println("实例化一个对象的时候,必然调用构造方法"); } public static void main(String[] args) { //实例化一个对象的时候,必然调用构造方法 Hero h = new Hero(); } } '实例化时就会输出:' 实例化一个对象的时候,必然调用构造方法隐式的构造方法
public Hero(){ }无参的构造方法,如果不写,就会默认提供一个
一旦提供了一个有参的构造方法 同时又没有显式的提供一个无参的构造方法 那么默认的无参的构造方法,就没有了
public class Hero { String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 //有参的构造方法 //默认的无参的构造方法就失效了 public Hero(String heroname){ name = heroname; } public static void main(String[] args) { Hero garen = new Hero("盖伦"); Hero teemo = new Hero(); //无参的构造方法“木有了” } }和普通方法一样,构造方法也可以重载
public class Hero { String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 //带一个参数的构造方法 public Hero(String heroname){ name = heroname; } //带两个参数的构造方法 public Hero(String heroname,float herohp){ name = heroname; hp = herohp; } public static void main(String[] args) { Hero garen = new Hero("盖伦"); Hero teemo = new Hero("提莫",383); } }含多个参数
package test; public class Hero { String name; float hp; float armor; int moveSpeed; public Hero(String heroname,float heroHP,float heroArmor,int heroMoveSpeed) { name=heroname; hp=heroHP; armor=heroArmor; moveSpeed=heroMoveSpeed; } public static void main(String[] args) { // TODO 自动生成的方法存根 Hero h = new Hero("盖伦",616.28f,27.536f,350); System.out.println("name:"+h.name); System.out.println("hp:"+h.hp); System.out.println("armor:"+h.armor); System.out.println("moveSpeed:"+h.moveSpeed); } }对于成员变量来说: 属性是在编译时确定的 对方法来说: 面方法是在运行时确定的,在运行方法是会动态的进栈出栈, new Person()放在堆中,其引用 Person e是在栈中存放的
子类中可以重写父类中非private的方法,当调用的时候,会动态绑定,执行子类的方法。 问题一、【如果子类中与父类中的实例变量、静态方法和静态变量同名(没有实例方法,实例方法重名,若参数相同就是重写),访问的时候会访问哪一个?】 重名后,实际上有两个变量和方法。 【 对于private变量和方法】,只能在类内访问,访问的永远是当前类,即在子类中访问子类的,父类中访问父类的,他们还是名字相同,,没有任何关系。 【 对于public变量和方法】,则要看如何访问。在类内访问的是当前类的,但是子类可以通过super.明确访问父类的。在类外,则要看访问变量的静态类型:静态类型是父类,则访问 父类的变量和方法;静态类型时子类,则看子类的变量和方法。 例如: 父类:
package lianxi; public class Base { public static String s="Static-Base"; public String m = "base"; public static void staticTest(){ System.out.println("base_static:"+s); } }子类:
package lianxi; import java.nio.charset.Charset; public class Child extends Base{ public static String s="Static-Child"; public String m = "child"; public static void staticTest(){ System.out.println("child_static:"+s); } public static void main(String[] args) { Child c = new Child(); Base b= c; System.out.println(b.s); System.out.println(b.m); b.staticTest(); System.out.println(c.s); System.out.println(c.m); c.staticTest(); } }执行结果为:
Static-Base base base_static:Static-Base Static-Child child child_static:Static-Child总结: 当通过b(静态类型是Base)访问,访问的是Base的变量和方法,当通过c(静态类型时Child)访问,访问的是Child的变量和方法,这称之为静态绑定。即访问绑定到变量上的静态类型。静态绑定是在程序编译阶段即可决定,而动态绑定则要等到程序运行时。实例变量、静态变量、静态方法、private方法,都是静态绑定的。
this这个关键字,相当于普通话里的“我” 小明说 “我吃了” 这个时候,“我” 代表小明,"我"代表当前人物 this即代表当前对象
和构造方法不同,构造方法实在实例化工程中实现的,即可以当作设置属性。而下面–
public void setName1(String name){ name = name; }–>上面,并没赋予属性name值。方法体中,因为分不清name是参数name,还是成员变量的name属性,就能访问到参数name,而没有访问类成员变量的name,从而不能赋予属性name
package j2se; public class Hero { String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 //参数名和属性名一样 //在方法体中,只能访问到参数name public void setName1(String name){ name = name; } //为了避免setName1中的问题,参数名不得不使用其他变量名 public void setName2(String heroName){ name = heroName; } //通过this访问属性 public void setName3(String name){ //name代表的是参数name //this.name代表的是属性name this.name = name; } public static void main(String[] args) { Hero h =new Hero(); h.setName1("teemo"); System.out.println(h.name); h.setName2("garen"); System.out.println(h.name); h.setName3("死歌"); System.out.println(h.name); } } '输出:' null//不能访问到对象的属性 garen//设置不同的变量名 死歌//this.name直接给本对象的属性赋值通过this调用其他的构造方法 如果要在一个构造方法中,调用另一个构造方法,可以使用this()
package j2se; public class Hero { String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 public Hero(float hp){ this.hp = hp; } //带一个参数的构造方法 public Hero(String name){ System.out.println("一个参数的构造方法"); this(255.36);//调用hp的方法 this.name = name; } //带两个参数的构造方法 public Hero(String name,float hp){ this(name); System.out.println("两个参数的构造方法"); this.hp = hp; } public static void main(String[] args) { Hero teemo = new Hero("提莫",383); System.out.println(teemo.name); } } 输出结果: 一个参数的构造方法 两个参数的构造方法 提莫4.4关键字super 使用spuer, 子类可以调用子类 ●在Java类中使用super来调用父类中的指定操作: ➢super可用于访问父类中定义的属性 ➢super可用于调用父类中定义的成员方法 ➢super可用于在子类构造方法中调用父类的构造器 ●注意: ➢尤其当子父类出现同名成员时,可以用superi进行区分 ➢super的追测不仅限于直接父类
调用父类的构造器 ●子类中所有的构造器默认都会访问父类中空参数的构造器 ●当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一-行 ●如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错
;//=就是把h引用指向Hero类类型传参 类类型又叫引用 上面就是说明,用引用可以改变参数的值,相当于指针。
第24行的引用 teemo与 第17行的引用hero,是不同的引用 第17行相当于新建了一个Hero 通过调用garen.attack(teemo, 100); 使得这两个引用都指向了同一个对象 所以在第18行hero.hp = hero.hp - damage; 就使得该对象的hp值,发生了变化
把比较接近的类,规划在同一个包下
Hero,ADHero 规划在一个包,叫做charactor(角色) Item,Weapon规划在另一个包下,叫做 property(道具)在最开始的地方声明该类所处于的包名。 使用其他包下的类,必须import 使用同一个包下的其他类,直接使用即可(比如,可以直接继承) 但是要使用其他包下的类,必须import
import property.Weapon;包下可以有包和文件
成员变量有四种修饰符 private 私有的 package/friendly/default 不写 protected 受保护的 public 公共的 public 表示公共的:
public String name;而maxHP 没有修饰符即代表package/friendly/default
float maxHP以Hero为例 自身:指的是Hero自己 同包子类:ADHero这个类是Hero的子类,并且和Hero处于同一个包下 不同包子类:Support这个类是Hero的子类,但是在另一个包下 同包类: GiantDragon 这个类和Hero是同一个包,但是彼此没有继承关系 其他类:Item这个类,在不同包,也没有继承关系的类 绿色访问:即可以直接访问。 绿色继承:只能通过继承访问。
那么什么情况该用什么修饰符呢? 从作用域来看,public能够使用所有的情况。 但是大家在工作的时候,又不会真正全部都使用public,那么到底什么情况该用什么修饰符呢?
属性通常使用private封装起来方法一般使用public用于被调用会被子类继承的方法,通常使用protectedpackage用的不多,一般新手会用package,因为还不知道有修饰符这个东西再就是作用范围最小原则 简单说,能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来了
一个类里面还可以定义其他的类,但是不能用修饰符修饰,只能是缺省的,且不能被其他类调用
LOL里有一个怪叫大龙GiantDragon,只有一只,所以该类,只能被实例化一次 单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在。 饿汉式单例模式: GiantDragon,通过私有化其构造方法,使得外部无法通过new 得到新的实例。然后GiantDragon提供public static的getInstance方法
package charactor; public class GiantDragon { //私有化构造方法使得该类无法在外部通过new 进行实例化 private GiantDragon(){ } //准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个 private static GiantDragon instance = new GiantDragon(); //public static 方法,提供给调用者获取12行定义的对象 public static GiantDragon getInstance(){ return instance; } } package charactor; public class TestGiantDragon { public static void main(String[] args) { //通过new实例化会报错 // GiantDragon g = new GiantDragon(); //只能通过getInstance得到对象 GiantDragon g1 = GiantDragon.getInstance(); GiantDragon g2 = GiantDragon.getInstance(); GiantDragon g3 = GiantDragon.getInstance(); //都是同一个对象 System.out.println(g1==g2); System.out.println(g1==g3); } }懒汉式单例模式 懒汉式单例模式与饿汉式单例模式不同,只有在调用getInstance的时候,才会创建实例
package charactor; public class GiantDragon { //私有化构造方法使得该类无法在外部通过new 进行实例化 private GiantDragon(){ } //准备一个类属性,用于指向一个实例化对象,但是暂时指向null private static GiantDragon instance; //public static 方法,返回实例对象 public static GiantDragon getInstance(){ //第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象 if(null==instance){ instance = new GiantDragon(); } //返回 instance指向的对象 return instance; } } package charactor; public class TestGiantDragon { public static void main(String[] args) { //通过new实例化会报错 // GiantDragon g = new GiantDragon(); //只能通过getInstance得到对象 GiantDragon g1 = GiantDragon.getInstance(); GiantDragon g2 = GiantDragon.getInstance(); GiantDragon g3 = GiantDragon.getInstance(); //都是同一个对象 System.out.println(g1==g2); System.out.println(g1==g3); } }饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。 如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。 懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量(鉴于同学们学习的进度,暂时不对线程的章节做展开)。 使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。 看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式
面试的时候经常会考的点,面试题通常的问法是: 什么是单例模式? 回答的时候,要答到三元素
构造方法私有化静态属性指向实例public static的 getInstance方法,返回第二步的静态属性预先定义的常量: 枚举enum是一种特殊的类(还是类),使用枚举可以很方便的定义常量 比如设计一个枚举类型 季节,里面有4种常量
public enum Season { SPRING,SUMMER,AUTUMN,WINTER }一个常用的场合就是switch语句中,使用枚举来进行判断 注:因为是常量,所以一般都是全大写
public class HelloWorld { public static void main(String[] args) { Season season = Season.SPRING; switch (season) { case SPRING: System.out.println("春天"); break; case SUMMER: System.out.println("夏天"); break; case AUTUMN: System.out.println("秋天"); break; case WINTER: System.out.println("冬天"); break; } } }枚举好处 假设在使用switch的时候,不是使用枚举,而是使用int,而int的取值范围就不只是1-4,有可能取一个超出1-4之间的值,这样判断结果就似是而非了。(因为只有4个季节) 但是使用枚举,就能把范围死死的限定在这四个当中 遍历枚举:
public class HelloWorld { public static void main(String[] args) { for (Season s : Season.values()) { System.out.println(s); } } }练习:
package charactor; public enum HeroType { TANK,WIZARD,ASSASSIN,ASSIST,WARRIOR,RANGED,PUSH,FARMING } public class HelloWorld { public static void main(String []args){ for(HeroType HT:HeroType.values()){ switch(HT){ case TANK : System.out.println("坦克"); break; case WIZARD : System.out.println("法师"); break; case ASSASSIN : System.out.println("刺客"); break; case ASSIST : System.out.println("辅助"); break; case WARRIOR : System.out.println("近战"); break; case RANGED : System.out.println("远程"); break; case PUSH : System.out.println("推进"); break; case FARMING : System.out.println("打野"); break; } } } }