内部类的概念
将类定义在类的内部,那么该类就成为内部类
注意: 内部类是一个相对的概念,如果A类中有一个B类,那么A类相对于B类来说就是外部类,那么B类相对于A类来说就是内部类
内部的分类
1.成员内部类
2.局部内部类
3.静态内部类
4.匿名内部类
内部类的特点:
1.内部类可以直接访问外部类的所有成员
2.外部类如果需要访问内部类成员,必须创建内部类对象
3.内部类如果编译后生成2个字节码文件,格式如下
外部类(内部类.class
OuterClass)InnerClass.class
4.要访问内部类的成员非常麻烦,而且造成程序耦合性增高,可读性降低,所以内部类要慎用
成员内部类
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。
比如下面的例子,如果成员内部类OuterClass3用private修饰,则只能在外部类的内部访问。如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样。
外部类只能被public和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。
访问成员内部类格式:
外部类类名.内部类类名 对象名 = 外部类对象.内部类对象
当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
- 外部类.this.成员变量
- 外部类.this.成员方法
案例
public class InnerClassDemo03 {
public static void main(String[] args) {
OuterClass3.InnerClass oi = new OuterClass3().new InnerClass();
oi.show();
oi.setNum2(100);
System.out.println(oi.getNum2());
}
}
class OuterClass3{
// 成员位置
private int num = 10;
class InnerClass{
private int num2 = 20;
public void show() {
System.out.println(num);
System.out.println(num2);
}
public void setNum2(int num2) {
this.num2 = num2;
}
public int getNum2() {
return this.num2;
}
}
}
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
- 注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
案例
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
class Woman extends People{ //局部内部类
int age =0;
}
return new Woman();
}
}
静态内部类
成员内部类也可以使用static修饰
而且成员内部类还可以使用private的修饰
访问格式:
外部类类名.内部类类名 对象名 = new 外部类类名.内部类类名();
静态内部类主要成员是静态成员,可以方便调用,同时提高类的安全性
静态内部类可以有静态成员和非静态成员
案例
public class InnerClassDemo05 {
public static void main(String[] args) {
// OuterClass5.InnerClass oi = new OuterClass5.InnerClass();
// System.out.println(oi.num);
// oi.show();
// oi.show2();
System.out.println(OuterClass5.InnerClass.num2);
OuterClass5.InnerClass.show2();
}
}
class OuterClass5{
private int num = 5;
public static int num2 = 10;
public static class InnerClass{
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println("InnerClass.show()");
}
public static void show2() {
System.out.println("InnerClass.show2()");
}
}
public static void method() {
InnerClass innerClass = new InnerClass();
// System.out.println(num);
}
}
匿名内部类
概念:本质就是一个子类匿名对象
特点:
1.可能是一个子类、普通类、抽象类、接口
2.没有名字的子类
3.是一个对象
格式:
new 类或者父类/抽象类/接口(){
//重写方法;
}
- 匿名内部类的本质一个继承(父类)或者实现(接口)的子类匿名对象
案例
经典面试题
public class InnerClassDemo08 {
public static void main(String[] args) {
OuterClass8.Inner oi = new OuterClass8().new Inner();
oi.show();
}
}
class Fu{
public int num = 40;
public void show() {
int num = 50;
System.out.println(num);
}
}
class OuterClass8{
public int num = 10;
class Inner extends Fu{
public int num = 20;
public void show() {
int num = 30;
// 输出30
System.out.println(num);
// 输出20
System.out.println(this.num);
// 输出40
System.out.println(super.num);
// 输出50
super.show();
// 输出10
System.out.println(OuterClass8.this.num);
}
}
}