假如我们希望在方法中创建一个类解决当前问题,但又不想这个类被公用,此时可以考虑在方法中定义内部类,方法中的内部类无法在方法之外的作用域被访问。
一、在方法中定义内部类
如同正常声明类一样,可以方法中的任意位置定义内部类,内部类和正常类一样可以继承或者实现接口。
public interface Destination {
String readLabel();
}
public class Parcel {
public Destination destination() {
class DestinationIml implements Destination {
private String label;
public DestinationIml(String label) {
this.label = label;
}
@Override
public String readLabel() {
return label;
}
}
return new DestinationIml("长沙");
}
public static void main(String[] args) {
Parcel parcel = new Parcel();
System.out.println(parcel.destination().readLabel());
}
}
长沙
二、在方法中定义匿名内部类
public interface Contents {
int value();
}
public class Parcel2 {
public Contents contents() {
return new Contents() {
private int i = 11;
@Override
public int value() {
return i;
}
};
}
public static void main(String[] args) {
Parcel2 parcel2= new Parcel2();
Contents contents = parcel2.contents();
System.out.println(contents.value());
}
}
11
初看这个例子时,可能有点犯迷糊,在返回实现接口对象的同时定义内部类。上面其实是一种简便写法,我们将其还原一下,大家就很好理解:
public class Parcel2 {
public class myContents implements Contents {
private int i = 11;
@Override
public int value() {
return i;
}
}
public Contents contents() {
return new myContents();
}
}
通过简写形式定义出的内部类被称为匿名内部类,匿名内部类可以继承基类,也可以实现接口(最多实现一个),但两者无法同时兼备。
三、匿名内部类不能定义构造方法
匿名类未指向一个具体的类,故无法定义构造方法,但还是可以通过 super 调用基类中的方法。
public class Wrapping {
private int value;
public Wrapping(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public class Parcel3 {
public Wrapping wrapping(int value) {
return new Wrapping(value) {
@Override
public int getValue() {
return super.getValue() * 10;
}
};
}
public static void main(String[] args) {
Parcel3 parcel3 = new Parcel3();
Wrapping wrapping = parcel3.wrapping(10);
System.out.println(wrapping.getValue());
}
}
100
4.匿名内部类引用外部类的参数
匿名内部类若引用外部类的参数,则该参数必须为 final,否则会引起编译错误 (在使用 idea 编码过程中,会自动为内部类引用的外部参数加上 final )。
public interface Destination {
String readLabel();
}
public class Parcel4 {
public Destination destination(final String dest) {
return new Destination() {
private String label = dest;
public String readLabel() {
return label;
}
};
}
public static void main(String[] args) {
Parcel4 parcel4 = new Parcel4();
System.out.println(parcel4.destination("北京").readLabel());
}
}
北京
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!