七:内部类
7.1: 定义:
在一个类中的另外一个类。
eg:
.java —> 小区
public class A{} —> A栋
class B{} —> B栋
class C{} —> C栋
内部类:
.java —> 小区
public classAA{} —> AA栋
class AA_home -> AA栋内部的home
class BB{} —> BB栋
class BB_home-> BB栋内部的home
class CC{} —> CC栋
class AA_home class BB_home 就是内部类。
7.2:内部类的分类
7.2.1:成员内部类.
7.2.2:静态内部类.
7.2.3:局部内部类.
7.2.4:匿名内部类.
7.3, 成员内部类:
声明:在类中成员变量/成员方法位置编写。public class AA_home{};
注:在内部类中可以有成员方法,成员属性。
7.3.1:在内部类的方法中使用
7.3.1.1:成员内部类中属性编写: 普通属性。静态属性需要被定义为final
7.3.1.2:成员内部类中方法编写: 普通方法
7.3.1.3:成员内部类中方法调用内部类属性:直接调用/this.属性名
7.3.1.4:成员内部类中方法调用内部类方法:直接调用/this.方法名()
7.3.1.5:成员内部类中方法调用外部类属性:外部类名.this.属性名
7.3.1.6:成员内部类中方法调用外部类方法:外部类名.this.方法名()
7.3.2:在外部类的方法调用成员内部类的属性方法
前提: 创建内部类对象 AA_home aw = new AA_home();
7.3.2.1:外部类方法调用内部类属性: aw.属性
7.3.2.2:外部类方法调用内部类方法: aw.方法名();
7.3.3:在main方法中使用内部类:
前提:先要获得外部类对象 MemberInner mi = new MemberInner();
7.3.3.1: 获得内部类对象: aw
7.3.1.1: AA_home aw = mi.new AA_home();
7.3.1.2: MemberInner.AA_home aw = mi.new AA_home();
7.3.3.2:调用内部类属性:aw.属性名;
7.3.3.3:调用内部类方法:aw.方法名();
7.4, 静态内部类:
即: 静态的成员内部类
声明:在类中静态成员变量/静态成员方法位置编写。public static class AA_home{};
静态内部类中可以声明静态成员和静态方法.
7.4.1:在内部类的方法中使用
7.4.1.1:静态内部类中属性编写: 可以定义静态属性和非静态属性
7.4.1.2:静态内部类中方法编写: 可以有静态方法和非静态方法
7.4.1.3:静态内部类中方法调用内部类普通属性:直接调用/this.属性名
7.4.1.3:静态内部类中方法调用内部类静态属性:直接调用/this.属性名。会有警告。静态的属性应该用静态的方式类调用
7.4.1.4:静态内部类中方法调用内部类普通方法:直接调用/this.方法名()
7.4.1.5:静态内部类中方法调用内部类静态方法:直接调用/this.方法名()
7.4.1.6:静态内部类中方法调用外部类普通属性: 不可以访问
7.4.1.7:静态内部类中方法调用外部类静态属性: 外部类名.属性
7.4.1.8:静态内部类中方法调用外部类普通方法: 不可以访问
7.4.1.9:静态内部类中方法调用外部类静态方法: 外部类名.方法名
总结:静态内部类,内部方法只能访问外部类的静态属性/方法。
7.4.2:在外部类的方法调用静态内部类的属性方法
普通属性方法:
前提: 创建内部类对象 AA_home aw = new AA_home();
7.4.2.1:外部类方法调用内部类属性: aw.属性
7.4.2.2:外部类方法调用内部类方法: aw.方法名();
静态属性方法:
7.4.2.1:外部类方法调用内部类属性: 静态内部类.属性
7.4.2.2:外部类方法调用内部类方法: 静态内部类.方法
7.4.3:在main方法中使用静态内部类:
原则:如果调用静态资源需要用类名直接调用,非静态的需要new对象。
AA_home aw = new AA_home()
aw.方法();
7.5, 局部内部类:
在局部代码块内部。
声明:在局部代码块中声明 class CC_home{};
局部内部类中只能有非静态方法,非静态属性(如果有静态属性需要被定义为final)
7.5.1:在局部内部类的方法中使用
7.5.1.1:局部内部类中属性编写: (静态+非静态)属性必须被定义final
7.5.1.2:局部内部类中方法编写: 普通方法
7.5.1.3:局部内部类中方法调用内部类属性:直接调用/this.属性名
7.5.1.4:局部内部类中方法调用内部类方法:直接调用/this.方法名()
7.5.1.5:局部内部类中方法调用外部类属性:外部类名.this.属性名
7.5.1.6:局部内部类中方法调用外部类方法:外部类名.this.方法名()
7.5.2:在外部类的方法调用局部内部类的属性方法
注意:这个是不可能被访问到的。
7.5.3:在main方法中使用内部类:
注意:这个是不可能被访问到的。
为什么外部类访问不到局部内部类的属性方法?
7.6, 匿名内部类:
没有构造器的类(不能手动写,系统会默认给)
一般用匿名内部类来实现某接口(使用不多,不需要写一个类实现该接口,可以使用匿名内部类)
匿名内部类一般就是用来实现接口:
所以: 重写接口(抽象类)中的方法。
可以在匿名内部类中写属性。
声明:
interface A{
public void show();
}
eg: A a = new A(){
public void show A(){
}
};
使用情景:面向接口编程,有时候写代码需要写一个类实现某个接口去完成某个功能,
eg:集合中的比较器。
但这个功能只用一次,没有必要写一个类那么久,可以使用匿名内部类来实现这个接口完成这个功能。
abstract class B{
public void showB(){}
public abstract void shohome();
}
eg:
B b = new B(){
//可以重写showB 可以不重写
public void shohome(){}//抽象方法一定要实现
};
解释:这里并不是new了接口, 而是多态, new的是接口的实现类,这个实现类就是匿名内部类充当了。
八:== 和 equals()区别
8.1: == 定义:
比较内存地址是否相同。
8.2: equals()定义:
Object类中的方法,Object中的equals()是比较内存地址是否相同。
注意:equals(Obj)是一个方法,所以只能是对象调用。equals是一个方法,所以可能被重写。
8.3: String类重写了equals()方法,所以在String对象调用equals时是比较值。
补充:
toString():当system输出对象的时候,其实是输出对象.toString();可以重写。
getClass():返回当前的真实对象,不可以重写。
String类的使用 :
字符串,【创建以后不能改变】,每一次拼接都会产生新的字符串。
构造方法:
new String(byte[],start,len);
new String("");
常用方法:
char = charAt(int index);
返回下标的字符
int = compareTo(String anotherString);
比较两个字符串
返回 字符串 相差
s11.compareTo(s12);
正数 s11 > s12
负数 s11 < s12
0 s11 == s12
boolean = equals(Object anObject)
比较两个字符串值是否相同
byte[] = getBytes();
返回字符串的字节表现形式
* int = indexOf("");
判断某个字符串在当前字符串中出现的位置
int : 第一次出现的下标 0 开始
找不到 返回 -1
int = lastIndexOf("");
从后往前找
int : 第一次出现的下标 0 开始
找不到 返回 -1
int = length();
获取字符串的长度
-
boolean = matches(String regex);
“hello”.matches(“规则”);
使用hello字符串和规则进行匹配
如果匹配成功(字符串符合定义的规则) 返回true-
String = replace(oldChar,newChar);
替换 :
String = replaceAll(String regex,String replacement); -
String[] = split(String regex);
分隔,打断 -
String = subString(beginIndex);
取子串
从beginIndex位置获取到最后 -
String = subString(beginIndex,endIndex);
取子串
从beginIndex位置获取到endIndex -
String = toLowerCase();
返回小写
-
String = toUpperCase();
返回大写 -
String = trim();
去除字符串 左右 两端的空格 -
StringBuffer使用 :
使用缓冲区解决每次拼接都产生新字符串的问题。
-
九:基本数据类型与包装器类型
注意:包装器类型都重写了equals方法
9.1:
boolean Boolean
byte Byte
short Short
char Character
int Integer
long Long
float Float
double Double
9.2:自动装箱和自动拆箱
在jdk1.5以后 基本数据类型和其包装器类型之间有自动装箱和拆箱过程。
注:是发生在编译阶段。
9.2.1:自动装箱: Integer i1 = 128; ----> Integer i1 = Integer.valueOf(128);
Integer i2 = 127; ----> Integer i2 = Integer.valueOf(127);
9.2.2:自动拆箱: int a1 = i1; ----> int a1 = i1.intValue();
int a2 = i2; ----> int a2 = i2.intValue();
9.2.3:valueOf():
源码:
IntegerCache.low = -128
IntegerCache.high = 127
cache 缓存
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i +(-IntegerCache.low)];
return new Integer(i);
}
结论:自动装箱的时候,如果这个数字在[-128~127]之间那么就是从缓存中获取数据。
如果这个数字不在范围内,那么就是利用new关键字创建Integer对象()
问题一:Integer a = 128 , Integer b = 128;a == b ?—>true/false
Integer a = 127 , Integer b = 127;a == b ?—>true/false
9.2.4:intValue(): 以 int 类型返回该 Integer 的值。即返回的是栈中 字面量同的地址。
结论:自动拆箱的时候,返回的是栈中字面量同的地址。即: int n;
9.2.5:什么时候回发生自动装箱/拆箱问题。
9.2.5.1:当int 和 Integer互相转换的时候回发生。
eg: int a = new Integer(“12”);
eg: Integer b = 10;
9.3:Integer.parseInt(“全数字字符串”);
把全数字的字符串转为int类型数据
eg:int a = Integer.parseInt(“123”);—> int : 123;
9.4:Integer.MAX_VALUE : 它表示 int 类型能够表示的最大值。
9.5:Integer.MIN_VALUE : 它表示 int 类型能够表示的最小值。
9.6:Integer.SIZE : 用来以二进制补码形式表示 int 值的比特位数。
9.7:10进制和2进制进行转换:
String s1 = "100011";
int parseInt = Integer.parseInt(s1,2);//该字符串是多少进制的数,然后转化为10进制的数
System.out.println(parseInt);
String string = Integer.toString(parseInt,16);//转化为16进制
System.out.println(string);
十:集合
10.1:数组的升级版.
集合 = 数组/其他内存结构 + 可变长度 + 一堆方法 + 简单操作。
10.2:集合位于java.util包中
注意:集合只能存放引用数据类型的数据。
10.3:集合分类
10.3.1: Set : 无序,并且放进集合中的对象不能重复。
10.3.2: List: 有序(放入的先后的次序), 放进集合中的对象可以重复。
10.3.3: Map : 集合中的每一个元素包含一对键对象和值对象,集合中没有重复的键对象,值对象可以重复。(Key - Value)
10.4:集合的从属关系
_________________________________________________________________________________ | | | 父接口 子接口 实现类 |
|| | | | |------>HashSet |
| |------>Set-----|------>TreeSet |
| | |------>LinkedHashSet 自己了解 | | | |
| Collection------| |------>ArrayList |
| |------>List----|------>Vector 自己了解 |
| |------>LinkedList 自己了解 |
|| | | | |------>HashMap |
| Map--------------------->Map----|------>TreeMap |
| |------>Hashtable 自己了解 | | |
|_______________________________________________________________________________|
10.5:涉及集合的基本操作
10.5.1 : 向集合中添加数据.
10.5.2 : 从集合中取数据
10.5.3 : 获得集合长度
10.5.4 : 遍历集合
10.5.5 : 清空集合
10.5.6 : 删除集合中某一个数据
10.6 : Collection接口
Collection接口 声明了 Set接口 和List接口 的通用方法.
10.6.1 : boolean add(Object o) 向集合中添加数据
10.6.2 : Iterator iterator(); 获取集合的迭代器(迭代器用来遍历集合);
10.6.3 : int size(); 返回集合中元素的数目;
10.6.4 : void clear() 删除集合中的所有对象引用,即不再持有这些对象的引用;
10.6.5 : contains(Obj) 判断在集合中是否持有特定对象的引用;
10.6.6 : isEmpty() 判断集合是否为空;
10.6.7 : remove(Obj) 从集合中删除一个对象的引用;
10.6.8 : Object[] toArray() 返回一个数组,该数组包含集合中的所有元素;
10.7 : Iterator接口
(用于遍历Collection集合):迭代器。
主要方法:
hasNext() 是否有下一个元素
next() 获取下一个元素
remove() 删除当前元素
10.8 : Set :
集合中的对象无序、不能重复;—>注意:是通过equals方法比较对象是否相同。
10.8.1 : HashSet:按照哈希算法来存取集合中的对象,存取速度比较快;
10.8.2 : TreeSet:实现SortedSet接口,具有排序功能;
10.8.3 : LinkedHashSet:HashSet子类,不仅实现Hash算法,还实现链表数据结构,链表数据结构能提高插入和删除元素的性能;
10.8.4 : 集合操作实例
Set set = new HashSet();
set.add(“小明”);
set.add(“小红”);
set.add(“小红”);
set.add(“小红1”);
set.remove(“小红”);
set.size();
Interator it = set.iterator();
while(it.hasNext()){
String name = (String)(it.next());//小明 小红
}
10.8.5 : HashSet : 先 hashCode() && 后 equals() 同时满足这两个才被hashSet认为是同一个对象。
按照哈希算法来存取集合中的对象,存取速度比较快。当向集合中加入一个对象时,HashSet会调用对象的hashCode()方法来获得哈希码,然后根据这个哈希码进一步计算出对象在集合中的存放位置。
—> 两个对象的值相同(equals()比较相同) ,那么这两个对象的hashCode一定相同。
—> 两个对象的hashCode相同,那么这两个对象的值不一定相同。
10.8.6 : TreeSet 可以按照规定排序的集合
10.8.6.1 : 自然排序(默认) : 实现了Comparable接口 ,重写 compareTo(Object o);
使用情景: 1,treeSet要排序的是类对象
2,这个类必须要实现Comparable, 重写compareTo(Object o)方法。
效果 :在使用treeSet 添加该类对象的时候 就会自动调用compareTo()方法进行排序
treeSet总是把compareTo()比较得出较小的 放到集合前端。
JDK类库中实现了Comparable接口的一些类的排序方式:
Byte, Short, Integer, Long, Double, Float : 按数字大小排序;
Character : 按字符的Unicode值的数字大小排序;
String : 按字符串中字符的Unicode值排序;
10.8.6.2 : 客户端排序:创建比较器—>实现java.util.Comparator接口,重写compare(Object x, Object y)方法。
使用:
1,写一个比较器(类),实现Comparator接口,重写compart()方法。
2,创建该比较器的实例对象。
3,将比较器的对象 通过TreeSet的构造器交给TreeSet使用 : eg: new TreeSet(comparator);
效果:
1,利用比较器创建的TreeSet集合在使用add方法添加数据的时候就会调用compart方法排序.
2,treeSet 将compart()返回较小的放到前面。
测试练习:Student类对象在TreeSet集合中按年纪大小排序。
1,创建Student类,name属性,age属性
2,写Test.java 写main方法, 在main方法中创建TreeSet集合。
3,TreeSet集合添加4个Student对象
4,输出,需要按照年纪大小排序, 大---->小
5,再写一个TreeSet排序,按照年纪小大排序, 小---->大
注意:1234,使用自然排序, 5,使用客户端(比较器)排序。
10.9List :
线性方式(数组)存储.
10.9.1:ArrayList : 代表长度可变的数组。允许对元素进行快速的随机访问,但是向ArrayList中插入与删除元素的速度较慢;
10.9.2:LinkedList: 在实现中采用链表结构。对顺序访问进行了优化,向List中插入和删除元素的速度较快,随机访问速度则相对较慢。
10.9.3:Vector : 是线程安全的集合
10.9.4:集合操作实例
注意:在使用List接口的时候注意导包.需要导入的是java.util.List包。
List list =new ArrayList();
list.add(“小明”);
list.add(“小红”);
list.add(“小明”);
list.add(“小红”);
list.size();
list.remove(index);
list.remove(object);
Iterator it = list.iterator();
while(it.hashNext()){
String name = (String)(it.next());
}
list.get(index);
for(int i = 0;i<list.size();i++){
String name = list.get(i);
}
10.10: forEach
遍历 Collection集合–> 加强for循环
for(String s : set){
syso(s);
}
10.11:Map :
1,把键对象和值对象进行映射的集合,它的每一个元素都包含一对键对象和值对象。
2,向Map集合中加入元素时,必须提供一对键对象和值对象. map.put(key,value);
3,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。value = map.get(key);
4,Map集合中的键对象不允许重复,如果有多个相同的key那么上一次的值会被覆盖。
10.11.1: HashMap :是线程不安全的集合。
10.11.2: HashTable:是线程安全的集合。
10.11.3: TreeMap :可以进行排序(对key进行排序)
10.11.4: HashMap : 判断key是否相同是通过 hashCode && equals方法来判断。
10.11.5: TreeMap : 实现了SortedMap接口,能对 键对象(key) 进行排序。
10.11.5.1 : 自然排序(默认) : 实现了Comparable接口 ,重写 compareTo(Object o);
10.11.5.2 : 客户端排序 : 创建比较器—>实现java.util.Comparator接口,重写compare(Object x, Object y)方法。构造器传入TreeMap Eg:new TreeMap(比较器);
10.11.6:map的遍历
1,map.entrySet()+forEach版本
Set entrySet = map.entrySet();
for(Entry a: entrySet){
System.out.println(a.getKey()+"--------"+a.getValue());
}
2, keySet() + 迭代器
Set keySet = map.keySet();
Iterator itKey = keySet.iterator();
while(itKey.hasNext()){
Object key = itKey.next();
System.out.println(key + “—”+map.get(key));
}
3, keySet() + forEach
Set keySet = map.keySet();
for(Object key: keySet){
System.out.println(key+"----"+map.get(key));
}
十一:泛型 : 用于约束代码.用于灵活代码.
11.1: 集合加泛型:
约束该集合只能添加泛型类型的数据.编译时泛型
11.1.1 : List集合
语法:List list = new ArrayList();—>生成的.class文件中:List l = new ArrayList();
表示该集合list只能添加String类型的数据。发生在编译期间.
list.add(“abc”); √
list.add(123); ×
11.1.2 : Set集合
语法: Set books = new HashSet();
表示该set集合只能添加book类型的数据。不然编译通不过。
11.1.3 : Map集合
语法: Map<String,String> map = new HashMap<String,String>();
表示该map集合只能保持key为String,value为String的数据对。
注意 : 集合中泛型只能是类类型.
11.2: 类名后加泛型:
代码更加灵活.
11.2.1:语法:
public class TestBean {
public T show(T t){}
}
11.2.2:使用:
TestBean a = new TestBean();
Integer value = a.show(123);
TestBean a = new TestBean();
String value = a.show(“acb”);
11.2.3: 类名后加两/多个泛型
public class TestBean<T,K,V> {
Map<K,V> map = new HashMap<K,V>();
public V show(K key){
return map.get(key);
}
}
TestBean<Boolean,String,Integer> t = new TestBean<Boolean,String,Integer>();
Integer a = t.show(“tom”);
11.3:泛型解决的问题
11.3.1:泛型可以使类中的属性的类型可以由外部决定
11.3.2:不需要强制类型转换
11.3.3:泛型可以在编译期间进行类型检查
11.3.4:提供了类型安全的操作
附: K —— 键,比如映射的键。
V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。
E —— 异常类。
T —— 泛型。
十二: 反射
利用类加载时在堆中创建的java.lang.Class对象去获得该类加载以后在方法区中创建的类信息,方法信息,变量信息…
12.1 : Class c = Class.forName("[类全包名+类名]/[全限定名]");//通过类加载器加载全限定名所对应的类.—>类加载—>涉及到内存问题.回顾 2.5
//利用 该类的Class对象可以创建对象,访问属性,访问方法,访问构造器
12.2 : 创建对象: c.newInstance();
12.3 : 获得属性镜像: Field field = c.getField(“属性名”);
Field[] fields = c.getFields();
Field[] fields = c.getDeclaredFields();
12.4 : 获得方法镜像: Method method = c.getMethod(“方法名”,参数1.class,参数2.class…);
Method method = c.getDeclaredMethod(“方法名”,参数1.class,参数2.class…);
如果是私有属性需要设置可见性:method.setAccessible(true);
设置可见性: Method.setAccessible(methodarray, flag);
12.4.1:利用方法镜像调用目标对象的方法:
Object returnValue = method.invoke(obj, args…);
12.4.2:利用方法镜像获得方法的返回值类型
method.getGenericReturnType();
12.4.3:利用方法镜像获得方法的修饰符
method.getModifiers()
12.4.4:利用方法镜像获得方法名
method.getName();
12.4.5:利用方法镜像获得方法的参数列表
method.getGenericParameterTypes();
12.4.6:利用方法镜像获得方法的异常
method.getGenericExceptionTypes();
注意:method,是一个方法的镜像,只能对应一个方法。
12.5 : 获取构造器镜像:Constructor<?>[] constructors = c.getConstructors();
Constructor<?> constructor2 = c.getConstructor(参数1.class,参数1.class,…);
12.5.1:利用构造器镜像 创建对象
constructor.newInstance(参数,参数,…);//用有参构造器创建对象
注意:反射创建对象有两种方式:
1,直接用class.newInstance();//调用无参构造器创建对象
2,利用class获得有参构造器,然后调用newInstance(参数…);
12.6 : 获取注解镜像:getDeclaredAnnotations(); 或者 getAnnotations();
注:获取方法上的注解就使用 method.getAnnotations();或者 method.getDeclaredAnnotations();
获取属性上的注解就使用 field.getAnnotations();…
十三:可变参数 :
可以接受任意个同类型的数据。
13.1:语法: public void show(int… a);----> public void show(int[] a)
13.2:含义: 调用这个show方法的时候可以传入多个int数据
13.2.1: show(1); —> show(new int[]{1});
13.2.2: show(1,2,3); —> show(new int[]{1,2,3})
13.2.2: show(); —> show(nnew int[0])
13.3:取值 可变参数有length属性.获取数组长度。–>取值同数组.
show(1,2,3,4);---->a[0],a[1],a[2],a[3]…
注意:可变参数一定是放在方法参数的最后一个。
eg: public void show(int a,String b,double… c){}
十四:forEach循环
14.1:语法 for(数据类型 变量 : 被遍历的数据){}
14.2:解释 : 使用 数据类型的变量来接收每次被遍历出来的数据
十五:枚举类型 :
使用enum关键字 枚举和类一个级别。
1,实例:public enum Gender{
Man,WoMan;
}
表示:一个枚举类Gender,有两个对象Man和WoMan。
注: 其中每一个枚举元素都是该枚举类型的一个实例
2,获取枚举类型中的对象:
1, Gender gender = Gender.Man;
2, Gender gender = Gender.WoMan;
3, for(Gender g : Gender.values()){
syso(g);//Man,WoMan
}
3,Enum类和enum关键字的区别
1.使用enum关键字定义的枚举类型,实际上就相当于定义了一个类,此类继承了java.lang.Enum类
2.每一个枚举值都是一个枚举类型的实例,它们被预设为public static final
Enum类的只有一个受保护的构造方法
protectd Enum(String name,int ordinal)
ordinal: 枚举元素的编号
实际上对于每一个枚举元素一旦声明之后,就表示自动调用此构造方法,所有的编号采用自动编号的方式进行(编号从0开始);
JDK1.5增加了枚举类型,可以使用enum来定义
eg:
public enum Gender{
MALE,FEMALE;
}
其中每一个枚举元素都是该枚举类型的一个实例
使用
Gender gender = Gender.MALE;
遍历
for(Gender s : Gender.values()) {
}
Enum类和enum关键字的区别
1.使用enum关键字定义的枚举类型,实际上就相当于定义了一个类,此类继承了
java.lang.Enum类
2.每一个枚举值都是一个枚举类型的实例,它们被预设为public static final
Enum类的只有一个受保护的构造方法
protectd Enum(String name,int ordinal)
ordinal: 枚举元素的编号
实际上对于每一个枚举元素一旦声明之后,就表示自动调用此构造方法,所有
的编号采用自动编号的方式进行(编号从0开始);
使用valueOf()方法,通过枚举类可以找到枚举中一个指定的对象
public enum Color{
RED,BLUE;
}
获得枚举类型对象的俩种方式:
第一种方式:
String s = “RED”;
Color red = Color.valueOf(s);
第二种方式:
Color red = Color.RED;
第一种方式是通过一个字符串的值来获得对象的,只要我们改变字符串的值就随意改变要获得的对象.
第二种方式就是写死的代码,不管怎么执行都是拿到枚举类中 RED对象,永远都是这样。
枚举类型的属性和方法
枚举类型可以有属性和方法
规则如下:
属性和方法必须定义在元素列表声明之后
public enum Color{
RED,BLUE;
private String name;
public String getName(){
return this.name;
}
}
枚举类型中定义构造方法
1.枚举的构造方法只能定义在元素列表之后
2.枚举类型的构造方法只能是private的,不写默认也是private
3.元素如果需要调用有参构造方法,则在元素后面加上"(参数)"
解释:Color类型只有三个固定对象,分别为RED GREEN BLUE,并且这个三个对象在创建的时候分别调用了有参的和无参的构造器
eg:
public enum Color {
RED(“红色”),GREEN(“绿色”),BLUE;
private String name;
public String getName(){
return this.name;
}
//一个参数构造器
Color(String name){
this.name = name;
}
//无参构造器
private Color(){
}
}
main:
//拿到Color中的三个固定对象的其中一个
Color c = Color.RED;
//拿到RED对象中的name属性的值
//这个值打印出来会是 “红色”
//因为是RED这个对象才创建的时候
//通过一个参数的构造器传给属性name的
//在枚举类型中声明元素列表其实就是
//在创建这个枚举类型的固定对象
String name = c.getName();
枚举隐式继承于Enum因此,无法再继承其他类
枚举实现接口
枚举可以实现接口,有以下两种方式
1.与普通class类一样,在枚举类中实现接口一样
2.枚举中单独实现接口中的抽象方法或者各个枚举元素对象中分别实现这个接口中的抽象方法
public interface Sofa{
void sit();
}
第一种方式来实现接口
public enum Color implements Sofa{
RED(“红色”),GREEN(“绿色”),BLUE;
private String name;
public String getName(){
return this.name;
}
//一个参数构造器
Color(String name){
this.name = name;
}
//无参构造器
private Color(){
}
//枚举中单独实现,每一个枚举元素对象都可以调用到这个方法
public void sit(){
//…
}
}
第二种方式来实现接口
public enum Color implements Sofa{
//每一个枚举元素对象中单独实现这个接口中的抽象方法 将来每个枚举元素对象调用到的就是自己独立实现的这个sit方法
RED(“红色”){
public void sit(){
//…
}
},
GREEN(“绿色”){
public void sit(){
//…
}
},
BLUE{
public void sit(){
//…
}
};
private String name;
public String getName(){
return this.name;
}
//一个参数构造器
Color(String name){
this.name = name;
}
//无参构造器
private Color(){
}
}
枚举中定义抽象方法
在一个枚举中可以定义多个抽象方法,但枚举中的每个元素必须分别实现这
些抽象方法
eg:
public enum Color {
RED{
public String getInfo() {
return “红色”;
}
},
GREEN{
public String getInfo() {
return “绿色”;
}
},
BLUE{
public String getInfo() {
return “蓝色”;
}
};
public abstract String getInfo();
}