1.内部类定义:如果在类Outer的内部再定义一个Inter类,此时称Inter是内部类,Outer是外部类,
类的定义是可以多层嵌套的,且最外层的类叫做顶级类,也称顶层类;
2.内部类的分类:
根据所处位置的不同,内部类可分为局部内部类和成员内部类。局部内部类是之定义在外部类的
方法体里面的类,而成员内部类是指定义在外部类方法体外的内部类;成员内部类还可分两类,
即静态内部类和实例内部类,两者最大的区别是,实例内部类的对象实例,必须在有定义它的外
部类的对象实例存在的条件下才能创建(就是先创建外层的实例,再创建里面的实例);但是静
态内部类的实例创建不受此限制。且实例内部类不能创建静态成员但是静态内部类可以创造各种
类型的成员。
3.使用内部类的原因:
一:内部类对象可以访问其所在的外部类的所有属性,包括private的,因为内部类被当做外部类
的成员,同一个类中的成员可以互相访问。但是外部类不能访问内部类的实现细节;
二:内部类提供了更好的封装,可以隐藏在外部类之中,不被同一个包中的其他成员所见;
三:匿名内部类还可以方便定义运行时回调和用于仅用一次的类;
四:用内部类编写事件驱动程序的时候比较方便;
(注:内部类的不足之处就是有些复杂!);
4.内部类的使用:
public class Outer{
private String str = "Java";
public class Inter{
public void add(int x,int y){
System.out.println(x + "+" + y + "=" +(x+y));
}
public void getStr(){
System.out.println(str);
}
}
public void getInfo(){
new Inter().getStr(); //此处用的是现场创建的匿名Inter类,而且只有外部类可以这样访问,其他类要用实例对象;
}
}
public class InterDemo1{
public static void main(String[] args){
Outer out = new Outer();
out.getInfo();
Outer.Inter oin = new Outer().new Inter();
oin.add(4,5);
oin.getStr();
}
}
5.实例内部类:
实例内部类是指在外部内里面的无static修饰的成员内部类;
一:外部类的静态方法和非外部类的类访问实例内部类都需要通过外部类创建内部类的实例来访问:
class Outer{
public class Inter{
public void add(int x,int y){
System.out.println(x + "+" y + "=" + (x+y));
}
public void mul(int x,int y){
System.out.println(x + "*" + y "=" + (x*y));
}
}
public void getAdd(){
Inter in = new Inter();
in.add(3,3);
in.mul(6,6);
}
public static void getMul(){
Inter staticin = new Outer().new Inter();
staticin.add(7,7);
staticin.mul(8,8);
}
}
public class InterDemo2{
public static void main(String[] args){
Outer out = new Outer();
out.getAdd();
out.getMul();
Outer.Inter oin = new Outer().new Inter();
oin.add(10,10);
oin.mul(10,10);
}
}
二:实例内部类可以访问外部类的所有成员,包括private,若是多层嵌套就可以访问所有外部类的所有成员,但是外部类想访问
实例内部类成员就需要创建实例内部类的实例;
三:实例内部类里面不能定义static成员;
四:多层嵌套中,Outer包含Inter,Inter包含Inter2,
class Outer{
public class Inter{
public class Inter2{
public void add(int x,int y){
System.out.println(x + "+" y + "=" + (x+y));
}
}
}
public void getAdd(){
Inter.Inter2 in = new Inter().new Inter2();
in.add(5,5);
}
}
五:若果在外部类Outer和内部类Inter里面都有同名成员变量i,则在Inter里面i,this.i,Inter.this.i都表示
Inter的成员i,只有Outer.this,i表示外部类的成员变量i;
6.静态内部类:
是在外部类中,static修饰了的成员内部类,与实例内部类不同的是,实例内部类只能定义非静态成员,但是
静态内部类静态成员和非静态成员都可以定义;
class Outer{
private int a=4;
private static int b=5;
public static class Inter{
private int x=5;
private static int y=6;
public void add(){
int temp=new Outer().a;
System.out.println(temp+"+"+x"="+(temp+x));
}
public static void mul(){
System.out.println(b+"*"+y+"="+(b*y));
}
}
public void getInfo(){
new Inter().add();
Inter.mul();
}
}
public class InterDemo3{
public static void main(String[] args){
Outer out=new Outer();
out.getInfo();
Outer.Inter in=new Outer.Inter();
in.add();
in.mul();
}
}
静态内部类的特点:
一:静态内部类创建实例的时候并不需要外部类的实例;
二:静态内部类可以定义非静态成员和静态成员;
三:外部类之外的其他类,要通过完整的类名访问静态内部类的静态成员,而访问其实力成员就要实例了;
四:静态内部类可以直接访问外部类的静态成员,若要访问外部类的非静态成员就需要外部类的实例;
7.局部内部类:
局部内部类是定义在方法体里面的类,仅仅在该方法内部有效,因此,局部内部类不能被外部类以及外部类之外的
其他类访问,也正因此,局部内部类不需要访问控制符课static修饰符;
class Outer{
public void fun(){
class Inter{ //此处没有public、private、protected、static等东西;
public int i=10;
}
Inter in=new Inter();
System.out.println(in.i);
}
}
public class InterDemo4{
public static void main(String[] args){
Outer out=new Outer();
out.fun();
}
}
局部类不能定义static成员,不能被外部类或其他类访问,用其他类或者外部类创建其实例进行访问也是不可以的!
局部内部类可以访问外部类的所有成员,包括private的;若局部类定义在静态方法体里面的时候,不能直接访问外
部内的非静态成员,但是可以访问外部类的静态成员,若要调用外部类的非静态成员就需要通过外部类的实例;局
部内部类还只能访问所在方法的final类型的参数和变量;
8.匿名内部类:
匿名内部类是指在定义是没有名称的内部类,必须在声明的时候使用new语句声明类;匿名内部类一般只使用一次
是一种特殊的内部类;虽然匿名内部类没有类名,但是他必须扩展一个基类或实现一个接口,而且不能写出extends
或者是implements关键字,如果匿名内部类实现接口或者继承抽象类的时候要实现父类或接口里面的所有抽象方法,
有名自的类若不指明父类,系统自行默认他继承的是Object类,但是匿名类不默认,所以必须写清楚!匿名内部类只
在所属代码块中执行一次,所以无法有构造函数,他总是用父类的构造方法来创建实例,如果匿名内部类实现的是
接口那么他的构造方法就是Object();
abstract class AbstrClass{
public abstract void getInfo();
}
class Inter{
public void print(){
show(new AbstrClass(){
public void getInfo(){
System.out.println("Java");
}
});
}
public void show(Abstract a){
a.getInfo();
}
}
public class InterDemo4{
public static void main(String[] args){
new Inter().print();
}
}
//以上为实现抽象类的代码;实现接口代码如下:
interface Inter{
public abstract void getInfo();
}
class InterClass{
public void print(){
show(new Inter(){
public void getInfo(){
System.out.println("Java");
}
});
}
public void show(Inter i){
i.getInfo();
}
}
public class InterDemo5{
public static void main(String[] args){
new InterClass().print();
}
}
注:匿名内部类没有构造方法,要用父类的;且可以访问外部类的所有成员,但若是包含在方法中的时候
只能访问方法中的final类型参数和局部变量;匿名内部类允许非静态代码块对成员进行初始化;