十章
- 类部类
- 枚举和注解
- 自定义实现枚举
- enum关键字实现枚举
- JDK内置的基本注解类型
- 元注解:对注解进行注解
补充:类的五大成员
-
属性
-
方法
-
构造器
-
代码块
-
内部类
内部类
定义:一个类的内部又完整的嵌套了另一个类结构。被牵头的类称为内部类,嵌套其他类的类称为外部类,内部类最大的特点就是可ui直接访问私有属性,并且可以体现类与类之间的包含关系
-
局部内部类(有类名)
-
基本语法
* class Outer{//外部类
class Inner{//内部类
}
}
class Other{ }
-
定义在外部类的局部位置,比如方法中,并且有类名
-
可以直接访问外部类的所有成员,包括私有的
-
不能添加修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是能使用final修饰,因为局部变量也可以用final
-
作用域:仅仅在定义他的方法或代码块中
-
局部内部类—访问---->外部类的成员【访问方式:直接访问】
-
外部类----访问---->局部内部类的成员【访问方式:创建对象,再访问(注意:必须在作用域内)】
-
外部其他类不能访问局部内部类(因为局部内部类的地位是一个局部变量)
-
如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,可以用(外部类.this.成员)
-
匿名内部类(没有类名,重点!!!)
-
本质是类
-
内部类
-
该类没有名字
-
同时还是一个对象
-
语法
-
new 类或接口(参数列表){
类体
};
//创建一个实例后,就不会再使用
//创建出来的实例,后面还能使用
//基于接口的内部类
public class data01{
public static void main(String[] args) {
new Dog().b();
}
}
interface A{
public void a();
}
class Dog{
int n = 10;
A a = new A(){
int n = 11;
@Override
public void a() {
System.out.println("好人是我");
System.out.println(Dog.this.n);
System.out.println(n);
}
};
public void b(){
a.a();
}
}
//注意创建一个内部类的运行类型是编译器给的//基于抽象类的内部类,必须去实现抽象方法//内部类的参数列表会传递给构造器
//匿名内部类的使用//两种方式
new A(){ ....重写的方法}.调用重写的方法();
A a = new A(){ ....重写的方法};
a.重写的方法();
当作实参直接传递,简洁高效(只使用一次,这里可以改变传进去的方法)
public class data01{
public static void main(String[] args) {
Phone.call(new Bell() {
@Override
public void ring() {
System.out.println("小猪起床了");
}
});
Phone.call(new Bell() {
@Override
public void ring() {
System.out.println("公主请起床");
}
});
}
}
interface Bell{
void ring();
}
class Phone{
public static void call(Bell bell){
bell.ring();
}
}
内部成员的三种创建方式
//第一种
//第二种方式在类中创建一个方法返回一个内部类
//第三种方式把第一种改进了一下
public class data01{
public static void main(String[] args) {
//第一种方式
Dog dog = new g();
dog.new Cat().say();
//第二种方式
Dog dog1 = new Dog();
Dog.Cat cat = dog1.new Cat();
cat.say();
//第三种方式
Dog.Cat cat1 = new Dog().new Cat();
cat1.say();
}
}
class Dog{
class Cat{
public void say(){
System.out.println("创建成功");
}
}
public Cat getCat(){
return new Cat();
}
}
-
静态内部类(放在成员位置)
-
只能访问外部类的静态成员
-
不能访问外部类的非静态成员
-
可以任意添加修饰符
-
作用域:同其他成员,为整个类体
-
访问方式
-
创建一个静态内部类
-
编写一个方法,返回静态内部类
-
默认准许就近原则(若要访问外部成员,外部类名.成员)
-
-
小结:
-
内部类有四种
-
局部内部类
-
匿名内部类(这个用的最多)
-
成员内部类
-
静态内部类
-
枚举(enumeration)
简称:enmu
理解:枚举是一组常量的集合,枚举属于一种特殊的类,里面包含一组有限的特定对象
-
将构造器私有化,目的是防止直接new
-
去掉setXxx方法,防止属性被修改
-
在Season内部,直接创建固定的对象
-
优化部分,可以再加入一个final修饰符
自定义类实现枚举
小结:
-
不需要提供setXxx方法,因为枚举对象值通常为只读
-
对枚举对象/属性使用final + static 共同修饰,实现底层优化
-
枚举对象名通常全部大写,常量的命名规范
-
枚举对象根据需要,也可以有多个属性
代码实现
public class data01 {
public static void main(String[] args) {
System.out.println(Season.AUTUMN);
}
}
class Season{
public String season;
public String weather;
private Season(String season, String weather){
this.season = season;
this.weather = weather;
}
public static final Season SPRING = new Season("春天","温暖");
public static final Season SUMMER = new Season("夏天","炎热");
public static final Season AUTUMN = new Season("秋天","凉爽");
public static final Season WINTER = new Season("冬天","寒冷");
public String getSeason() {
return season;
}
public String getWeather() {
return weather;
}
@Override
public String toString() {
return "Season{" +
"season='" + season + '\'' +
", weather='" + weather + '\'' +
'}';
}
}
使用关键字
-
使用 enmu 替代 class
-
将好长的创建对象改写成
- SPRING(“春天”,“温暖”);
-
如果有多个常量(对象)使用,间隔
-
如果使用enum来实现枚举,要求将定义常量对象写在前面
public class data01 {
public static void main(String[] args) {
System.out.println(Season.AUTUMN);
}
}
enum Season{
SPRING("春天","温暖"),SUMMER("夏天","炎热"),
AUTUMN("秋天","凉爽"),WINTER("冬天","寒冷");
private final String season;
private final String weather;
private Season(String season, String weather) {
this.season = season;
this.weather = weather;
}
public String getSeason() {
return season;
}
public String getWeather() {
return weather;
}
@Override
public String toString() {
return "Season{" +
"season='" + season + '\'' +
", weather='" + weather + '\'' +
'}';
}
}
注意事项
-
当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,这个类是一个final类
-
简化了传统的创建对象
-
如果使用无参构造器 创建枚举对象,则实参列表和小括号都可以省略
-
当有多个枚举对象时,使用,间隔,最后一个使用分号
-
枚举对象必须放在类的首行
-
枚举常量是静态对象
Enum类的方法
-
name (输出枚举对象的名称)
-
ordinal (输出该枚举对象的次序/编号,是从0开始编号的)
-
values (返回一个数组,枚举类型的数组)
-
增强for循环,是一种简便的遍历写法
-
for(数据类型,数组)
-
-
valueof(将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则异常)
- Season autumn = Season(“AUTUMN”);
-
compareTo(比较两个枚举常量,比较的就是位置号)
- 前面的编号减去后面的编号
public static void main(String[] args) {
//name ----> 获得名字
System.out.println(Season.AUTUMN.name());
//尝试Enum的方法
//name,ordinal,values,values of,compareTO
//ordinal ----> 获得位序
System.out.println(Season.SPRING.ordinal());
//values -----> 获得枚举常量数组
Season[] seasons = Season.values();
for(Season season : seasons)
System.out.println(season.name());
//value of -----> 赋值
Season season = Season.valueOf("SPRING");
//compareTo -------> 两个位序相减
System.out.println(Season.WINTER.compareTo(season));
}
enum实现接口
-
使用enum关键字后,就不能再继承其他类了,因为enum回隐式继承Enum类,java是单继承机制
-
枚举类和普通类一样,可以实现接口,如下形式
- enum 类名 implements 接口1,接口2{}
注解
理解:
-
注解(Annotation)也被称为元数据(Metadata),用于修饰解释包,类,方法,属性,构造器,局部变量等数据信息
-
和注释一样,注解部影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充知识
-
是JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替java EE 旧版中所遗留的繁冗代码和XML配置
基本的Annotation
使用Annotation是要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素
三个基本的Annotation
-
@Ovaerride : 限定某个方法,是重写父类方法,该注解自能用于方法
-
如果写了@Ovaerride注解,编译器就会去检查该方法是否重写父类方法,如果重写了,就编译通过,否则会报错(编译器进行语法的校验)
-
补充:@interface不是接口,表示一个注解类
-
补充:修饰注解的注解叫元注解 ,有@Target
-
-
@Deprecated:用于表示某个程序元素(类,方法)已过时
-
@Deprecated 修饰某个元素,表示该元素已经过时
-
不推荐使用,但是仍然可以使用
-
可以修饰方法,类,字段,包,参数…
-
可以做版本升级过度使用
-
-
@SuppressWarnings:抑制编译器警告
-
当我们不希望看到警告时,可以使用SuppressWarnings注解来抑制警告信息
-
在{“”} 中可以写入你希望抑制(不显示)警告的信息
-
all -----> 抑制所有
-
SuppressWarnings 作用范围是和写的位置有关
-
元注解
基本介绍:JDK的元Annotation 用于修饰其他 Annotation
种类
-
Retention //指定注解的作用范围
-
SOURCE
-
CLASS
-
RUNTIME
-
-
Target //指定注解可以在哪些地方使用
-
Documented //指定该注解是否会在javadoc体现
-
Inherited //子类会继承父类注解
写在后面的话
一个人呆久后,学习陷入一个糟糕的状态时,很容易陷入虚无主义。这时需要来自现实的一个寄托,来帮你从虚无感中解放出来。这个寄托可以是亲人的一个视频,可以是伴侣的陪伴,可以是任何东西,但必须要有一个。
这让我想到一句话,在这个快消费的时代,我们必须要有一个信仰,否则会迷失自己。
当然有人的信仰是金钱,哈哈哈哈哈!
因为金钱会给人带来安全感!