您的位置:首页 > 编程语言 > Java开发

Java 内部类

2016-09-16 16:03 225 查看
Java 内部类
可以将一类定义在另一个类的内部,这就叫内部类

一、内部类和组合不同,它可以把逻辑相关的类组织在一起并且控制类的可视性。总之它了解外围类并且可以与之通信

public class OuterClass {
private int i = 6;
public InnerClass getInnerClass()
{
return new InnerClass();
}
class InnerClass{
OuterClass getOuterClass()
{
i++;
System.out.println(i);
return OuterClass.this;

}
}
}

public class Client {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.getInnerClass();
OuterClass.InnerClass innerClass2 = outerClass.getInnerClass();
innerClass.getOuterClass();
innerClass.getOuterClass();
if(innerClass.equals(innerClass2))
{
System.out.println("innerClass 和 innerClass2 两个一样");
}
if(outerClass.equals(innerClass.getOuterClass()))
{
System.out.println("outerClass 和 innerClass2.getOuterClass() 两个一样");
}
if(outerClass.equals(innerClass2.getOuterClass()))
{
System.out.println("outerClass 和 两个一样");
}

}
}

下面是运行结果
7

8

9

outerClass 和 innerClass2.getOuterClass() 两个一样

10

outerClass 和 两个一样

那么我们可与得出这样的结论:


1、外围类创建某个内部类对象时,内部类会获取外围路的引用这里根据
outerClass 和 内部类的getOuterClass 指向同一个对象可以发现 当外围类创建对象的引用在它创建内部类对象时又会传给内部类对象获取。
2、内部类可以完全访问外围类即使是private 的属性 和方法
3、也说明在没有外部类的对象之前不肯创建内部类的对象

二、内部类和接口以及向上转型
对上面的例子进行改写

public class OuterClass {
public Contents getContents()
{
return new InnerClass();//向上转型
}
private class InnerClass implements Contents{
OuterClass getOuterClass() { return OuterClass.this; } @Override public void print() { System.out.println("from inner"); } }}
public class Client {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
runing(outerClass.getContents());
}
public static void runing(Contents contents)
{
contents.print();
}
}

这样InnerClass是private 的也就是说除了OuterClass 内没有人能够访问它这样InnerClass 就完全隐藏了实现细节,从Client来看不能访问Contents接口以外的方法。

三、在方法里和作用域里面的内部类

1、定义在方法中的内部类
将改刚刚的改写成

public class OuterClass {
public Contents getContents()
{
final int i = 0;
//定義在方法體內
class InnerClass implements Contents{
@Override
public void print() {
System.out.println("from innerClass "+i);
}
}
return new InnerClass();//向上转型
}
}

如果我们只想返回对Contents接口的实现的话这样更加简洁
2、匿名内部类

public class OuterClass {
public Contents getContents()
{
final int i = 0;
//定義在方法體內
return new Contents() {
@Override
public void print() {
System.out.println("from InnerClass "+ i);
}
};//向上转型
}
}

这个类是匿名的没有名字也是对上一个例子的简化
但是这里还有一个问题匿名内部类没有名字那么如果我们想要构造器来初始我们要创建的对象改怎么办
将Content 改写为抽象类

public abstract class Contents {
int i ;
Contents(int i)
{
this.i = i;
System.out.println("初始化。。。i = "+i);
}
abstract void print();
}

public class OuterClass {
public Contents getContents()
{
final int i = 0;
//定義在方法體內匿名內部類
return new Contents(i) {
@Override
public void print() {
System.out.println("from InnerClass "+ i);
}
};//向上转型
}
}

四、嵌套类 (static 声明的内部类)
内部类的对象和外围内的对象没有任何联系
那么:
  要创建嵌套类的对象就不依赖外部类的对象
  不能从嵌套类对对象访问外部类的非static域
和普通内部类不同的是:
  普通的内部类的字段和方法只能放在类外部的层次之上,所以普通的内部类不能有static域和static字段,也不能包含嵌套类。但是嵌套类可以包含这些东西
五、接口的内部类

public interface ClassInInterface {
void fun();
class Test implements ClassInInterface
{

@Override
public void fun() {
System.out.println("this is test");
}

public static void main(String[] args) {
new Test().fun();
}
}

}

如果你想创建某些公用代码使得它们可以被接口的所有实现所公用啊,那么接口内部嵌套类就可以实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: