目录
引言
在一个类内部所定义的类就是内部类(也叫嵌套类),包含内部类的类被称为外部类(也叫宿主类)。
Java中的内部类分为以下几种:
- 成员内部类
- 局部内部类
- 静态内部类
- 匿名内部类(常用)
这么多类,接下来就让我来给大家一一介绍吧!
1、成员内部类
成员内部类:顾名思义就是充当类中的一个成员的内部类,与成员变量和成员方法同级,创建格式如下:
格式:外部类名.内部类名 对象名 = new 外部类名(). new 内部类名();
范例:Outer . Inner in = new Outer() . new Inner();
在成员访问上的注意事项:
- 在成员内部类中可以直接访问外部类的成员,包括私有成员
- 在外部类中不可以直接访问内部类成员,需要创建一个内部类对象,然后通过该对象进行访问
- 一个常考内部类面试题:请观察如下代码,写出恰当的代码对应其注释要求输出的结果:
public class Outer {
private int num = 188;
class Inner{
private int num = 66;
public void show(){
int num = 33;
System.out.println("??");//188
System.out.println("??");//66
System.out.println("??");//33
}
}
}
答案如下:
System.out.println(num); //188
System.out.println(this.num); //66
System.out.println(Outer.this.num); //33
当内部类成员方法中的局部变量、内部类成员变量和外部类成员变量,都同名时;若想访问外部类的成员变量,则必须用:外部类名.this.变量名
2、静态内部类(很少用到)
静态内部类:就是有static关键字修饰的成员内部类,创建格式如下:
格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
范例:Outer . Inner in = new Outer . Inner();
代码演示:
public class OuterClass {
//创建一个静态内部类
static class InnerClass{
//创建一个普通方法
public void show01(){
System.out.println("我是静态内部类中的非静态方法show01...");
}
//创建一个静态方法
public static void show02(){
System.out.println("我是静态内部类中的静态方法show02...");
}
}
public static void main(String[] args) {
OuterClass.InnerClass in = new OuterClass.InnerClass(); //创建一个静态内部类的对象
in.show01(); //通过对象调用静态内部类中的非静态方法
OuterClass.InnerClass.show02(); //直接调用静态内部类中的静态方法
}
}
注意事项:
- 静态内部类只能访问外部类的静态成员
- 若想要访问外部类的非静态成员,需在静态内部类中创建一个外部类的对象,然后通过对象进行访问
- 示例:
public class OuterClass { static int a = 10; //静态 int b = 20; //非静态 //创建一个静态内部类 static class InnerClass{ public void show(){ //可以直接访问静态成员a System.out.println(a); //创建一个外部类的对象,必须通过对象来访问非静态成员b OuterClass oc = new OuterClass(); System.out.println(oc.b); } }
3、局部内部类(了解即可)
局部内部累:定义在方法、代码快、构造器等执行体中的内部类(平时很少用到,做了解即可)
示例代码:
public class OuterClass {
//创建一个成员方法show()
public void show(){
//在该方法中创建一个局部内部类
class inInner{
//在局部内部类inInner中又创建一个方法func()
public void func(){
System.out.println("我是func方法中的局部内部类...");
}
}
}
}
注意事项:
- 局部内部类只能在其所在的区域(如方法体、代码快)内被访问或被创建对象
- 外部类无法访问局部内部类,就像外部类无法访问到局部变量一样
4、匿名内部类(重要、常会用到)
概述:通常作为某个方法的参数,在定义类的时候就对其进行实例化;是java的一种语法糖,使得代码更具有简洁性。
前提:已存在一个接口或类;匿名内部类默认实现了这个接口 或 继承了这个类。
创建格式:
new 类名 / 接口名(){
......
}
-------------------------------------------------------------------------------------------------------------------------
- new 类名( ) {...} : 表示该匿名内部类继承了这个类
- new 接口名( ) {...} : 表示该匿名内部类实现了这个接口
说到这里,小伙伴们可能还是不理解,匿名局部类到底有什么作用,应用在什么场景呢?下面我将为大家讲解。
首先我们看这样一个问题:当某个方法的形参是一个接口类型,使用该方法时我们该传入怎么样的实参呢?答案是:传入该接口实现类的对象
如果没有匿名内部类:首先我们要创建一个类——>然后实现这个接口——>再创建实现类的对象——>最后作为实参传入函数
示例代码如下:
//第一步:创建一个接口
interface Inter{
void show();//抽象方法
}
//第二步:创建一个类去实现该接口
class InterImpl implements Inter{
public void show(){
System.out.println("我被InterImpl类实现了");
}
}
public class OuterClass {
//如果有一个方法,该方法的形参列表是一个接口,那么如何调用该方法呢?
public static void method(Inter in){
in.show();
}
//第三步:创建一个上述接口的实现类的对象,作为参数传入给方法
public static void main(String[] args) {
Inter in = new InterImpl();
method(in);
}
}
如果用匿名内部类后:
//如果有一个方法,该方法的形参列表是一个接口,那么如何调用该方法呢?
public static void method(Inter in){
in.show();
}
直接在调用method时创建一个匿名内部类,作为参数传入给该方法
public static void main(String[] args) {
method(new Inter() {
@Override
public void show() {
System.out.println("我在匿名内部类中被实现了....");
}
});
}
}
匿名内部类的应用场景
如果需要一次性的对象,匿名内部类就更加合适,因为它的定义相比定义一个独立的类更加简洁。
但需要注意的是:但如果接口中需要实现的方法过多,就不要用匿名内部类了,这样会显得代码很臃肿。
以上便是所有对Java中内部类介绍的内容了,如果有哪里不对,欢迎大家指正批评,喜欢的话就点个赞吧。