类中的一个普通成员
定义在方法中、代码块中、构造器等执行体中
一种特殊的局部内部类,不需要为这个类声明名字
特点
作用
//使用匿名内部类
public class Tets {
public static void main(String[] args) {
// 匿名内部类
//匿名内部类的本质是继承类或者实现接口
//下面的代码会定义一个继承了Fu类的匿名内部类并且创建该子类对象
Fu f = new Fu(){
@Override
public void show() {
System.out.println("Son show");
}
};
f.show();
}
}
class Fu{
public void show(){
System.out.println("Fu show");
}
}
/*
result:
Son show
*/
常见应用场景
通常作为一个参数传输给方法
//简单应用
public class Test {
public static void main(String[] args) {
//下面两个代码把匿名内部类直接作为参数传入
//等价于创建两个类实现Fly接口并分别创建对象,并将对象作为参数传入
showFly(new Fly() {
@Override
public void fly() {
System.out.println("鸟飞了");
}
});
showFly(new Fly() {
@Override
public void fly() {
System.out.println("我飞了");
}
});
}
public static void showFly(Fly f) {
f.fly();
}
}
interface Fly {
void fly();
}
枚举是一种特殊类
特点
public enum A {
// 枚举对象,必须放在第一行,表示A类的三个实例对象的名字,都为常量,使用public static final修饰
X,Y,Z;
public static String name;
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public void say(){
System.out.println("成员方法");
}
}
public class Test {
public static void main(String[] args) {
A.name = "静态类变量";
System.out.println(A.name);//输出类变量
//X,Y,Z都是A类的实例对象,都是常量,使用public static final修饰
A a1 = A.X;
System.out.println(a1);//输出a1所指向的枚举类中的对应对象
A a2 = A.Y;
System.out.println(a2);//输出a1所指向的枚举类中的对应对象
// 枚举类型的构造器私有,无法对外创建对象,默认使用private修饰
// A a2 = new A();
//枚举类包含的额外的API
A[] as = A.values();//获取枚举类中的所有对象
System.out.println(Arrays.toString(as));
for (A a : as) {
System.out.print(a + " ");
}//输出枚举类中的所有对象
System.out.println();
A a3 = A.valueOf("Z");
System.out.println(a3.name());//输出a3所指向的枚举类中的对应对象的名字
System.out.println(a3.ordinal());//输出a3所指向的枚举类中的对应对象的序号
a3.setA(10);
System.out.println(a3.getA());//输出a3所指向的枚举类中的对应对象的成员变量a的值
a3.say();//输出a3所指向的枚举类中的对应对象的成员方法
}
}
/*
result:
静态类变量
X
Y
[X, Y, Z]
X Y Z
Z
2
10
成员方法
*/
枚举类中有抽象方法,此时只有每个对象都重写抽象方法后才不会报错
public enum B {
//CAT是一个对象,并且重写枚举类B中抽象方法,使用无参构造
CAT(){
@Override
public void say() {
System.out.println(getName() + "喵喵喵");
//因为这是个对象,所以不能直接用name调用
}
},DOG("小狗"){
@Override
public void say() {
System.out.println(getName() + "汪汪汪");
}
};//DOG也是一个对象,并且重写枚举类B中抽象方法,使用有参构造
B() {
}
B(String name) {
this.name = name;
}
public abstract void say();//抽象方法
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test1 {
public static void main(String[] args) {
B.CAT.setName("小猫");
B.CAT.say();//因为CAT是枚举类中常量对象,所以两次的B.CAT都是同一个对象
B.DOG.say();
}
}
/*
result:
小猫喵喵喵
小狗汪汪汪
*/
定义类,接口,方法时,声明一个或多个类型变量,成为泛型类,泛型接口和泛型方法,统称为泛型
泛型提供了在编译阶段 约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常,保证所操作的数据类型的统一。
将具体的数据类型作为参数传给泛型变量,也就是操作阶段不需要知道具体数据类型,只需要操作泛型编写,最后通过传入的具体的数据类型来替换泛型变量,自动操作
通过定义泛型类使泛型类中的成员可以通过传入的不同的泛型执行相同的操作
格式:
修饰符 class 类名<类型变量,类型变量, ...>{
}
类型变量常用大写的英文字母,常用的有:E、T、K、V等
泛型接口和泛型类 类似,也可以同样可以单泛型,多泛型与继承泛型
格式:
修饰符<类型变量,类型变量,...> 返回值类型 方法名(形参){
}
//这是泛型方法
public void test(E e){
}
例子:
public class People {
}
public class Teacher extends People{
}
public class Student extends People{
}
public class Test {
public static void main(String[] args) {
test1("单泛型方法");
test2("多泛型方法", "方法");
//只要是People的子类或者People类都可以传入
test3(new People());
test3(new Student());
test3(new Teacher());
}
public static void test1(T t) {
System.out.println(t);
}
public static void test2(T t,E e) {
System.out.print(t);
System.out.println(e);
}
public static void test3(T t) {
System.out.println("=======上限泛型方法======");
System.out.println(t);
}
}
/*
result:
单泛型方法
多泛型方法方法
=======泛型方法上限======
com.LMH.Fanxingmethod.People@1b6d3586
=======泛型方法上限======
com.LMH.Fanxingmethod.Student@4554617c
=======泛型方法上限======
com.LMH.Fanxingmethod.Teacher@74a14482
*/
public class Test3 {
public static void main(String[] args) {
// ArrayList list1 = new ArrayList<>();
// 会报错,因为泛型只能是引用类型,不能是基本类型
ArrayList list2 = new ArrayList<>();
}
}