什么叫内部类呢?
简单来说将一个类定义到另一个类里面,里面那个类就称为是内部类
内部类的访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。外部类要访问内部类中的成员必须要建立内部类的对象才能访问。
内部类的用处:
内部类一般用于类的设计。分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。这个时候,这个事物中的事物就定义成内部类来描述。
内部类的修饰符:
由于内部类被定义在成员位置,所以内部类可以被成员修饰符修饰。
内部类可以在其他类中直接访问,例:
class Outer{
private int num=3;
class Inner{
void show(){
System.out.println("show run"+num);
}
}
public void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
//直接访问外部类中的内部类中的成员。
Outer.Inner in =new Outer().new Inner();
in.show();
}
}
如果内部类是静态的,其实相当于一个外部类。可以直接用外部类的对象调用内部类类名使用,例:
class Outer{
private static int num=3;
static class Inner{
void show(){
System.out.println("show run"+num);
}
}
public static void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
Outer.Inner in =new Outer.Inner();
in.show();
}
}
如果内部类中定义了静态的成员,该内部类也必须定义成静态的否则会编译失败,例:
class Outer{
private static int num=3;
class Inner{
void show(){
System.out.println("show run"+num);
}
public static void function(){
System.out.println("function 运行了");
}
}
public static void method(){
Inner in = new Inner();
in.show();
}
}
class InnerDemo{
public static void main(String[]args){
Outer.Inner.function();
}
}
结果为:
Compiling InnerDemo.java……
InnerDemo.java:63: 错误: 内部类Outer.Inner中的静态声明非法
public static void function(){
^
修饰符 ‘static’ 仅允许在常量变量声明中使用
InnerDemo.java:68: 错误: 无法从静态上下文中引用非静态 变量 this
Inner in = new Inner();
^
2 个错误
[Finished in 0.6s]
为什么内部类可以直接访问外部类的成员:
因为内部类被定义在外部类的成员位置,该内部类就持有了外部类的引用(外部类名.this)
内部类可以放在局部位置上 ,例:
public class InnerDemo2{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
int num=3;
void method(){
class Inner{
void show(){
System.out.println("show......"+num);
}
}
Inner in = new Inner();
in.show();
}
}
当内部类处于局部位置时,该内部类只能访问局部中被final修饰的局部变量。
public class InnerDemo2{
public static void main(String[]args){
Outer out = new Outer();
Object obj = out.method();
}
}
class Outer{
final int num=3;
Object method(){
int x = 9;
class Inner{
void show(){
System.out.println("show......"+x);
}
}
Object in = new Inner();
// in.show();
return in;
}
}
匿名内部类:
匿名内部类其实就是内部类的简写格式,是一个匿名 的子类对象,可以直接在类的结束部分加点调用。
简写的前提:内部类必须实现或者继承一个外部类或者接口
public class InnerDemo3{
public static void main(String []args){
new Outer().method();
}
}
abstract class Demo{
abstract void show();
}
class Outer{
int num=4;
public void method(){
new Demo(){
void show(){
System.out.println("show......"+num);
}
}.show();
}
}
匿名内部类的使用场景:
当函数参数是接口类型时,且接口中的方法不超过三个,这个时候就可以用匿名内部类作为实际参数进行传递。
使用匿名内部类的注意事项:
当在创建内部类对象的时候可以调用子类特有的方法,当创建对象的父类引用类型时,就不能引用子类特有的方法了,因为对象已经向上进行了转型。
例:1.在创建时调用
public class InnerDemo5{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
void method(){
new Object(){
public void show(){
System.out.println("show run");
}
}.show();
}
}
结果如下:
Compiling InnerDemo5.java……
——Output——
show run
[Finished in 0.6s]
2.创建子类对象的父类引用类型时,调用子类特有的方法
public class InnerDemo5{
public static void main(String[]args){
new Outer().method();
}
}
class Outer{
void method(){
Object obj = new Object(){
public void show(){
System.out.println("show run");
}
};
obj.show();
}
}
运行结果如下:
Compiling InnerDemo5.java……
InnerDemo5.java:14: 错误: 找不到符号
obj.show();
^
符号: 方法 show()
位置: 类型为Object的变量 obj
1 个错误
——Output——
[Finished in 0.6s]