前言
之前有很多人遇到了关于内部类的问题【主要在android的学习之中会大量的使用到】,内部类是什么,内部类怎么定义,内部类的分类,内部类的好处,内部类如何访问,这里我们来结合代码简单的理解一下
1.内部类是什么?
当一个类的定义是在另一个类的内部,那么我们就把这个定义在类的内部的类为内部类.
上代码:
public class Outer{ class Inner{ public void show(){ System.out.println("我是内部类");
} } }
这段代码中Outer类相对Inner是外部类,其中Inner是一个类,它定义在Outer类内部,那它就是内部类.
2.内部类的分类?
内部类主要通过类在外部类中的位置来区分
1.成员内部类{成员级别的类}
位置:类中方法外定义的类
顾名思义这个类是定义在外部类的成员中
上代码:
public class Outer{ private String aa ; class Inner{ public void show(){ System.out.println("我是成员内部类"); } } public void show(){ System.out.println("Inner类没有定义在我这方法中"); } }
可以看到,Inner类是与成员aa是一个级别的都是定义在类中方法外的级别,他们统一是成员级别的,像这种情况下定义的类,我们就叫他成员内部类,成员内部类重点就是定义在类中方法外部
2.方法内部类[局部内部类]
位置:类中方法内定义的类.
这个类的定义是在类的内部方法的内部
上代码:
public class Outer{ private String str; public void show(){ System.out.println("我是show方法"); class Inner{ public void InnerMethod(){ System.out.prinltn("我是局部内部类"); } } } }
我们可以看到代码中内部类的定义位置在类中方法内,这样的类我们称之为局部内部类,有的地方也叫方法内部类
3.匿名内部类
特点:是局部内部类的简化形式
前提:存在一个借口或者类
格式: new 类名或者接口名称(){
//要重写接口或者类的方法
};
代码:
提供一个类或者接口,这里我们提供一个接口MyInter:
public interfact MyInter{ public void show(); }
提供一个类Outer来体现匿名内部类:
public class Outer{ public void show(){ MyInter m = new MyInter(){ public void show(){ System.out.println("我是匿名内部类"); } }; } }
3.内部类的访问和好处
1.成员内部类的访问和好处
(1)访问规则
成员内部类可以访问外部类的资源,包括私有,外部类想要访问内部类成员必须创建对象
基本语法是 外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
public class Outer{ private String s ; class Inner{ private String s ; public void show(){ System.out.println("你好"); System.out.println(s); //访问外部类的成员 } } public static void main(String[] args){ Outer.Inner inner = new Outer().new Inner();//这是统一的访问方式 inner.s ="2" ; //外部类访问内部类资源 } }
2.静态内部类的访问规则
语法:外部类名.内部类名 对象名 = new 外部类名.内部类名();
public class Outer{ static class Inner{ public void show(){ System.out.println("你好"); } } public static void main(String [] args){ Outer.Inner inner = new Outer.Inner(); //静态内部类的访问方法 inner.show(); } }
3.根据访问修饰符还可以有private,protected修饰的类
外部类不能被private,protected修饰,但是内部类可以
public class Outer{ private class Ts{ } protected class Ta{ } }
-----------注意:使用private修饰的类为了数据的安全,使用static修饰的类访问更方便--------------
4.局部内部类的好处和访问语法
好处:保护数据的安全
代码:
public class Outer{ public void show(){ private final int a ; class Inner{//成员内部类不能被private,public,protected修饰 public void meth(){ System.out.println("我是局部内部类"); System.out.println("访问show方法变量a"+a+",这个变量必须加final"); } } //方法中才能访问Inner Inner i = new Inner(); i.meth(); } }
注意:局部内部类访问的局部变量必须加final修饰,局部内部类的访问只能在方法内部new
好处是:可以随着方法的调用完毕而销毁
5.匿名内部类的使用和好处[Android中常见的调用方法]
1)先看一个例子,简单的多态
定义一个接口MyInter
public interface MyInter{ public void show(); }
2)此时我们想实现这个接口,调用方法,所以我们可以定义一个类实现MyInterImpl1接口
public class MyInterImpl1 implements Myinter{ public void show(){ System.out.println("我是实现接口一"); } }
3)定义测试类MainTest
public class MainTest{ public static void main(String[] args){ MyInter i = new MyInterImpl1(); //根据多态原则我们调用 i.show(); ///输出我是实现接口一 } }
4)问题来了:我还想要一个实现类或者说我的某个方法中需要一个MyInter的实现类,根据多态原则,我们需要一个与MyInterImpl1不一样的实现类
简单,我们在定义一个
public class MyInterImpl2 implements Myinter{ public void show(){ System.out.println("我是实现接口二"); } }
5)同样调用
public class MainTest{ public static void main(String[] args){ MyInter i = new MyInterImpl2(); //根据多态原则我们调用 i.show(); ///输出我是实现接口二 } }
6)但是此时我们有问题了,我们可能有很多的需要实现的地方,当时有的时候这些实现的类可能仅仅只是使用一次,我们就可能不会在调用,
难道我们都要给他们专门写一个类来描述吗?假设现在MyInterImpl3这个类实现了MyInter,方法描述中提供了一个添加的算法
public class MyInterImpl2 implements Myinter{ public void show(){ System.out.println(1+2); } }
上面的代码我们可能只执行一次,我们只调用一次,这个时候怎么办,java提供了一个概念,匿名内部类
改变MainTest中的代码:
public class MainTest{ public static void main(String[] args){ //下面我们使用匿名内部类的语法 MyInter i = new MyInter(){ public void show(){ System.out.println("你好,我是匿名内部类”); } }; i.show(); } }
上面的代码中,我们可以看到,类名或者接口名 对象名 = new 类名或者接口名(){
//实现代码
};这样的语法
这样的好处第一个可以体现出来,我们可以看到,无需再新建一个类来实现MyInter接口,只需要提供一个匿名内部类,他就像直接实现了MyInter接口一样,
实现里面的方法,实例化接口,调用接口的方法,根据多态,实则调用实例化类的方法,这就是匿名内部类的第一个好处;
我们再来看看
public class MainTest{ public static void main(String[] args){ mainShow(?????);//这里我们可以怎么用到匿名内部类呢? } static void mainShow(MyInter i){ i.show(); } }
代码改写:
public class MainTest{ public static void main(String[] args){ mainShow(new MyInter(){ public void show(){ System.out.println("我是匿名内部类"); } }); } static void mainShow(MyInter i){ i.show(); } }
代码改变后,可以看到,匿名内部类作为参数传递,那么可以大胆的想到参数是随着方法调用完毕由虚拟机回收的,那么匿名内部类作为参数传递,我们可以认为匿名内部类可以减少资源的消耗
以上是我对内部类的一些理解,如果有什么建议,希望大家一起讨论