内部类的了解
作为类的五大成员之一—-内部类,我们先来简单认识:
我们通常是把不同的类创建在不同的包里面,对于同一个包里的类来说,它们都是同一层次的。但其实还有另一种情况,有些类可以被定义在另一个类的内部,我们把在一个类里面定义的类称为内部类(InnerClass)或嵌套类,把外面定义的类称为外部类(OutClass)或。 不难看出,内部类的存在,是与它的外部类紧密相连的。
内部类的格式写法
public class 外部类名{
class 内部类名{
}
}
一般的,我们将外部类叫做Outer,内部类叫做Inter,在这种情况下,内部类可以很好的隐藏其内部的属性和,拥有较强的私密性。那么我们该如何正确的进行安全访问呢?这就要提到我们成员的访问特点了。
内部类访问特点
内部类的访问特点:
*内部类可以直接访问外部类的成员,包括私有
* 外部类要访问内部类的成员,需要new对象
但在不同具体的内部类中,其访问特点又有所不同。所以我们先来了解其具体的内部类分类:
内部类的分类
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类
成员内部类
成员内部类:写在成员位置,属于外部类的成员
* 成员内部类可以被private 默认 public static修饰
* 在JDK16之前,在成员内部类中,不能定义静态变量,后面可以
访问格式: Out.Inter.oi =new Out().new Inter(); 成员内部类
第一种方式 Outer outer=new Outer();
Outer.Inner inner=outer.new Inner();第二种方式 Outer.Inner inner1=outer.getInnerInstance();
在外部类提供一个方法,返回一个内部类对象
**注意:**当成员内部类的成员和外部类的成员拥有重复名字时,会发生隐藏想象,此时访问时,遵循就近原则。
例子如下
public class Outer {//成员内部类
private int a=10;
class Inter{
int a=20;
public void show(){
int a=30;
//Outer.this 获取了外部类的对象
System.out.println(Outer.this.a);//10
System.out.println(this.a);//20
System.out.println(a);//30
}
}
}
在测试中调用时,
静态内部类
使用static修饰的内部类叫做静态内部类
* 静态内部类:{
* 只能访问外部类中的静态方法和静态对象,
* 若要访问非静态的,需要创建方法(static)
* 静态内部类也是成员内部类的一种。
* 调用静态方法的格式:外部类.内部类.方法名():
* 创造静态内部类的对象:只有是静态的东西,都能直接用类名点获取(外部类点一下--内部类点两下)
* Outer.Inter oi=new Outer.Inter();
* }
我们来研究一下静态内部类的一些特点:
创造Outer外部类
public class Outer {
int a=10;
static int b=20;
//静态内部类
static class Inter{
public void show1(){
//报错——访问了非静态方法
// System.out.println(a);
Outer O=new Outer(); //所以要先创造对象
System.out.println(O.a);
System.out.println(b);//b为静态变量,直接访问
System.out.println("非静态的方法执行了" );
}
static void show2(){
Outer O=new Outer();
System.out.println(O.a);
System.out.println(b);
System.out.println("静态的方法执行了");
}
}
}
我们便能看出以下几个特点
- 实例化:静态内部类的实例化不依赖于外部类的实例化,即可以直接创建静态内部类实例。
- 访问外部类的变量和方法:静态内部类可以访问外部类的静态变量和静态方法,但不可以访问外部类的非静态变量和非静态方法。
- 声明内部类的变量和方法:静态内部类可以声明非静态的和静态的变量和方法。
匿名内部类
顾名思义:匿名,即隐藏了名字的内部类,可以写在局部位置,也可以写在成员位置
格式:new 类名/接口名(){重写方法}; ** 匿名内部类--}后面有分号**
上图解释
这里创建一个匿名内部类
匿名内部类的特点:
* 细节:包含了继承或者实现,方法的重写,创建对象。
* 整体就是一个类的子类或一个接口的实现对象
* 好处:只需要增添一段代码的量,就可以少创建一个子类去测试类中实现,在使用单次方法的时候,可以直接通过匿名内部类实现
* 使用场景:当方法的参数列表是接口或者类时,使用匿名内部类直接传递子类对象和实现类对象。
* 如果实现类只是使用一次,可以用匿名内部类简化代码