内部定义普通类、抽象类、接口的统称,是指一种嵌套的结构关系。
缺点:破坏了良好的程序结构。
优点:内部类定义在类的内部,可以方便访问外部类的的私有成员,并且和其它类进行隔离,每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
成员内部类是依托外部类而存在的,定义在类内部的非静态类,就是成员内部类。代码示例如下:
package neibu;
class Outer{
private int age ;
private int name ;
public Outer() {
super();
// TODO Auto-generated constructor stub
}
public Outer(int age) {
super();
this.age = age;
}
public Intter getInfo() {
Intter inter = new Intter("guoqun");
return inter ;
}
class Intter{
private String name ;
public Intter(String name) {
super();
this.name = name;
}
public void name() {
/*Intter类 像是Outer类的一个成员,Outer称为外部类。
成员内部类可以无条件访问外部类的所有成员属性和成员方法,
包括private成员和静态成员。*/
System.out.println(Outer.this.age + this.name);
}
}
}
Intter类是Outer类的一个内部类,Outer称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法,包括private成员和静态成员。
需要注意的是,虽然成员内部类可以无限制的访问外部类中成员或方法,但当成员内部类与外部类拥有同名成员变量或者方法时,会发生覆盖,即默认情况下访问的是成员内部类的成员,如上述代码示例的name成员变量。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量 ,如Outer.this.age
外部类.this.成员方法
外部类访问成员内部类的成员,需要先创建一个成员内部类的对象,再通过引用来访问内部类成员。
内部类可以直接被实例化,语法格式:
外部类.内部类 对象名称 = new 外部类().new 内部类();
代码示例如下:
public class Lian {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer.Intter inttera = new Outer(10).new Intter("guoqun");
inttera.name();
}
}
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。内部类私有化,可以使用 private、protected实现。如上面示例中,如果成员内部类Intter使用private进行修饰,那么只能在外部类的内部访问;如果用protected进行修饰,那么只能在同一个包下或继承外部类时访问;如果使用public进行修饰,那么在任何地方都能访问;如果是默认访问权限(default),则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public或default访问权限修饰。
package neibu;
interface Jiekou<T>{
public abstract void jie(T x);
// 内部接口
interface KouJie {
public abstract void fun();
}
class Jj<T> implements Jiekou<T>{
public void jie(T x) {
System.out.print(x);
}
class Abs implements KouJie {
public void fun() {
System.out.print("asdasda");
}
}
}
实例化内部类接口实例化对象前需要首先获取外部类实例化对象,代码示例如下:
public class Lian {
public static void main(String[] args) {
// 实例化外部类接口对象
neibu.Jiekou<Integer> Jie = new neibu.Jj<Integer> () ;
Jie.jie(10 );
// 实例化内部类接口实例化对象前需要首先获取外部类实例化对象
Jiekou.KouJie kou = ((Jj) Jie).new Abs();
kou.fun();
}
}
package neibu;
public class Lian {
public static void main(String[] args) {
FaceM.getFace().getInfo();
}
}
interface FaceM{
public abstract void getInfo();
class mm implements FaceM {
public void getInfo() {
System.out.println("接口子类定义为自身内部类");
}
}
public static FaceM getFace() {
return new mm();
}
}
使用static定义内部类,此时的内部类不再受外部类实例化对象的影响,所以等同于于一个“外部类”,内部类的名称为“外部类.内部类”,同时static定义的内部类只能调用外部类中static定义的结构,并且在进行内部类的实例化时也不再需要先获取外部类实例化对象,static内部类对象实例化格式如下:
外部类内部类内部类对象外部类内部类
package neibu;
public class Lian {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println();
Outer.Intter inttera = new Outer.Intter("guoqun");
inttera.name();
}
}
class Outer{
public Outer(int age) {
super();
this.age = age;
}
public Intter getInfo() {
Intter inter = new Intter("guoqun");
return inter ;
}
private int age ;
static class Intter{
private String name ;
public Intter(String name) {
super();
this.name = name;
}
public void name() {
System.out.println(this.name);
}
}
}
package neibu;
public class Lian {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println();
JieKou.Load load = new LoadFace();
JieKou.Compare compare = new CompareFace();
JieKou.getInfo(load, compare);
}
}
interface JieKou{
// 内部接口
static interface Load {
public abstract boolean loadData();
}
static interface Compare {
public abstract void compareData();
}
public static void getInfo(Load sLoad , Compare sCompare) {
if (sLoad.loadData()) {
Compare.compareData();
}
else {
System.out.println("加载失败");
}
}
}
class LoadFace implements JieKou.Load{
public boolean loadData() {
return true;
}
}
class CompareFace implements JieKou.Compare{
public void compareData() {
System.out.println("compareData");
}
}
package neibu;
public class Lian {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println();
Outer outer = new Outer(12);
outer.getInfo();
}
}
class Outer{
private int age ;
public Outer(int age ) {
this.age = age ;
}
public void getInfo() {
class Inter { // 内部类
public void interFun() {
System.out.println("interFun" + Outer.this.age) ;
}
}
new Inter().interFun() ;
}
}
如果一个类只在某个方法中使用,则可以考虑使用局部类。
匿名内部类使用广泛,如我们常用的绑定监听的时候。
package neibu;
public class Lian {
public static void main(String[] args) {
/*
接口对象无法直接实例化,使用匿名内部类后就可以利用对象的实例化格式获取接口实例
*/
Face face = new Face() { // 匿名内部类
@Override
public void name() {
// TODO Auto-generated method stub
System.out.println("sss");
}
};
}
}
@FunctionalInterface
interface Face {
public abstract void name();
}
package neibu;
public class Lian {
public static void main(String[] args) {
FaceN.getFace().name();
}
}
interface FaceN {
public abstract void name();
public static FaceN getFace() {
return new FaceN() {
@Override
public void name() {
System.out.println("在接口中利用匿名内部类实现接口");
}
};
}
}
适合于接口只有一个子类的时候,并且也可以对外部调用处隐含子类。