1、什么是内部类?
内部类就是在类里面定义的类,其和类里定义的其它成员在同一级别,由于其定义在内部,我们可以理解其为寄生类,寄生在外部类(我们在其里面定义内部类,于是就相对的叫其外部类,或者叫宿主类)里面,由于其寄生在外部类,我们就可以把外部类理解为宿主类。
2、内部类有哪些特点?
a、一般情况下类的上一级单位都是包,但是由于内部类是在类里定义的,其上一级单位是类,所以内部类可以使用,private(类访问权限)protected(包访问权限)static等修饰。
b、内部类分类:根据是否有static修饰可以分成非静态内部类(无static)和静态内部类。在方法里定义的叫方法内部类,还有一个叫匿名内部类。
3、如何定义非静态内部类?如何使用?使用该注意什么?
定义:在普通类的里面定义一个没有static修饰的内部类就是非静态内部类。
使用:a、可以直接访问外部类的成员,包括属性,方法,构造器等,即使有private修饰也可以访问。因为怎么访问都是在类里面使用。所以无关修饰符。
b、虽然内部类可以直接访问外部类的成员等,但是外部类并不能直接访问内部类的成员。
c、要使用内部类的成员,必须要有一个宿主供其寄生的地方,所以在使用内部类之前一定要先把外部类实例化,在把内部类实例化话,这样才能调用内部类里的成员。
如何使用:
【在外部类里】在外部类里使用时其就可以当成是外部类的普通成员变量,所以可以按照一般普通方法,实例化,然后调用其各个成员。
【在外部类的外面如何使用非静态内部类:】
下面的a、b、c就是建立一个内部类的变量:
a、声明变量:外部类.内部类 变量名【 OutClass.InnerClass varName;】这是定义了一个内部类的变量,但是并没有初始化。
b、初始化之前必须先创建外部类的实例(先得有宿主)【OutClass 外部类变量名 = new OutClass()】
c、初始化:变量名(内部类)= 变量名(外部类).new外部类()。
上面三部可以直接写成一步:OutClass.InnerClass varName = new OutClass.new InnerClass ()
OutClass.InnerClass varName:这是声明变量。
OutClassInstance:创建宿主。
OutClassInstance.new InnerClass ():创建内部类的实例。
d、建立实例之后就可以放心大胆的调用内部类的方法了。(因为谁的方法,谁的属性就该用谁调用)
非静态内部类派生子类:
a、非静态的内部类派生子类也就是被继承,其是父类。(OutClass.InnerClass是派生时候的父类)
b、子类总是会调用父类的构造器一次,但是如果派生的子类里没有宿主的话,内部类就无法产生实例调用内部类的构造器。所以派生的子类有构造器,那么构造器里面一定要用【宿主】.super()调用父类的构造器。
实例代码如下:
实例一:
<span style="font-size:18px;">//定义一个奶牛类
public class Cow
{
private static double weight ;
public Cow(double weight)//构造器
{
this.weight = weight;
}
//定义一样奶牛腿类,属于Cow这个类,是其Cow内的类,内部类,是Cow的一个成员
<strong> private class CowLeg</strong>
{
private double height;
public CowLeg(double height)//构造器
{
this.height=height;
}
public void info()//方法
{
//虽然weight是private修饰,只能是类里访问,但是在内部类里也能直接访问
System.out.println("腿高"+height +",重"+Cow.weight);
}
}
//定义一个test方法
public void test()
{
<span style="color:#000099;">System.out.println("我是一头牛");
//由于要调用info方法,所以先得穿件CowLeg实例
CowLeg cog = new CowLeg(45.9);
cog.info();
}</span>
public static void main(String [] args)
{
//创建实例
Cow cow = new Cow(58.8);
cow.test();
}
}</span>
实例二:
public class Outer
{
int count=20;
public class Inner
{
int count = 200;
public void info()
{
int count = 2000;
System.out.println("count:"+count);//2000
//this代表调用info方法的Inner的实例。
System.out.println("count:"+this.count);//200
//Outer.this代表Outer实例。
//Outer.this代表该内部类实例所寄生的“宿主”的实例,即是ou。
// System.out.println("count:"+Outer.this.count);//20,
}
}
class InnerSub extends Outer.Inner
{
public InnerSub()
{
// new Outer().super();
}
}
public void test()
{
System.out.println("别无选择");
//Inner是一个非静态的内部类,其必须寄生在外部类的实例里。
//此处利用利用ou调用test方法,所以inner的实例in就寄生在ou里。
Inner in = new Inner ();//inner属于外部类,可以直接调用创建实例 。
in.info();
}
public static void main(String [] args)
{
//不能在此处直接创建Inner的实例,因为创建的实例没有宿主不能存在
//所以不能用一般的创建实例的方法,必须要考虑先创建宿主
//如此在外部类外面创建非静态内部类的实例
Outer.Inner in1 = new Outer().new Inner();
//利用内部类的实例调用内部类的方法
in1.info();
}
}
4、如何定义静态内部类?如何使用?使用该注意什么?
定义:有static修饰的内部类就是静态内部类,其实类相关的,属于整个外部类,而不是外部类的实例。
使用: a、由于是直接寄生在外部类里面,外部类已加载其宿主就存在。所以可以直接声明和初始化。
b、可以直接派生子类。
c、静态外部类可以直接通过外部类来进行调用。
如何使用:
1、【在外部类里】在外部类里使用时其就可以当成是外部类的普通成员变量,所以可以按照一般普通方法,实例化,然后调用其各个成员。
【在外部类的外面如何使用静态内部类:】
a、创建实例是我语法:new OuterClass.InnerConstructor(),
声明变量:外部类.内部类 变量名【 OutClass.InnerClass varName;】
b、有这个实例之后就可以进行其它引用
程序实例:
<span style="font-size:18px;">public class Out
{
//非静态的到有对象才能存在,静态变量只要类一加载就存在
public static String name = "刘liu";
//定义一个静态的内部类,注意:其需要用static修饰,其实例寄生在外部类本身
static class In
{
public void info()
{
System.out.println("-------In的info方法-------");
System.out.println("name》:"+name);
}
}
public static void main(String [] args)
{
//执行到这儿(进入main里)的时候,Out已经被加载,In的对象可以寄生在Out类本身,可以In可以创建实例
//此时定义的是静态的方法,其是寄生在外部类本身 ,在外部类里创建内部类的实例
//无需等待其创建外部类的实例后,有宿主了才能创建
In in1 = new In ();//此时是静态的方法下面能引用非静态的
in1.info();
}
}</span>
【注意】:1、内部类还可以定义在接口里,由于默认接口有public static修饰,所以只能是静态内部类。
5、方法内部类:定义在方法里的就是方法内部类。
6、匿名类:只需要使用一次的类。