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

Java中的内部类详细总结

2015-06-09 20:48 567 查看
非静态内部类

例1.

//外部类
class Out {
private int age = 12;

//内部类
class In {
public void print() {
System.out.println(age);    //非静态内部类成员可以访问外部类的private成员</span>
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
//或者采用下种方式访问
/*
Out out = new Out();
Out.In in = out.new In();
in.print();
*/
}
}

运行结果:12

程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class

前者是外部类Out的class文件,后者是内部类In的class文件。

即成员内部类(静态内部类和非静态内部类)的class文件总是这种形式:OuterClass$InnerClass.class

创建非静态内部类对象的一般形式为: 外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名()

Out.In in = new Out().new In()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意

  1.开头的Out是为了标明需要生成的内部类对象在哪个外部类当中

  2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量

例2.

class Out {
private int age = 12;

class In {
private int age = 13;
public void print() {
int age = 14;
System.out.println("内部类方法里的局部变量:" + age);
System.out.println("内部类成员变量:" + this.age);
System.out.println("外部类成员变量:" + Out.this.age);
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
}
}


运行结果:

局部变量:14

内部类变量:13

外部类变量:12
非静态内部类的变量访问形式

在非静态内部类的方法内访问某个变量时,优先在该方法内查找是否存在该名字的局部变量;
若无,到该方法所在的内部类中查找是否存在该名字的成员变量;

若无,到该内部类所在的外部类中查找是否存在该名字的成员变量;

if 外部类的成员变量,内部类的成员变量,内部类方法里的局部变量同名:

访问外部类的成员变量 Out.this.属性名

访问内部类的成员变量 this.属性名

访问内部类方法里的局部变量 属性名

例3.

public class Out{

private class In{}

public static void main(String[] args){
new In();  //编译异常
}
}
运行结果:编译异常

不允许在外部类的静态成员中直接使用非静态内部类。

非静态内部类里不能有静态方法,静态成员变量,静态初始化块。

静态内部类

例4.

class Out {
private static int age = 12;

static class In {
public void print() {
System.out.println(age);
}
}
}

public class Demo {
public static void main(String[] args) {
Out.In in = new Out.In();
in.print();
}
}
运行结果:12

如果用static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性(静态成员不能访问非静态成员)

创建静态内部类对象的一般形式为: 外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()

例5.

public class Out {

static class In{
private static int a = 5;
private int b = 9;
}

public void acc(){
System.out.println(In.a);//通过类名访问静态内部类的类成员
System.out.println(new In().b);//通过实例访问静态内部类的实例成员
}
}

外部类不能直接访问静态内部类的成员

可以使用静态内部类的类名作为调用者来访问静态内部类的类成员 如 In.a

可以使用静态内部类对象作为调用者来访问静态内部类的实例成员 如 new In().b

匿名内部类

例6.

interface Product{
public double getPrice();
public String getName();
}

public class AnonymousTest {

public void test(Product p){
System.out.println("购买了一个" + p.getName() + "花掉了" + p.getPrice());
}

public static void main(String[] args){
AnonymousTest ta = new AnonymousTest();
ta.test(new Product(){
public double getPrice(){
return 567.8;
}
public String getName(){
return "AGP";
}
});
}
}


运行结果:购买了一个AGP花掉了567.8

例7.

abstract  class Device{
private String name;
public abstract double getPrice();
public Device(){}
public Device(String name){
this.name = name;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}
}
public class AnonymousInner {

public void test(Device d){
System.out.println("购买了" +d.getName() + "价格是" +d.getPrice());
}

public static void main(String [] args)
{

AnonymousInner ai = new AnonymousInner();
ai.test(new Device("电子示波器")
{
public double getPrice()
{
return 67.8;
}
});

Device d = new Device()
{

{

System.out.println("匿名内部类的初始化块");
}

public double getPrice()
{
return 56.2;
}

public String getName()
{
return "键盘";
}
};
ai.test(d);
}
}
运行结果:
购买了电子示波器价格是67.8

匿名内部类的初始化块

购买了键盘价格是56.2

匿名内部类必须继承一个父类或实现一个接口,但最多只能两者选其一
定义匿名内部类的格式如下:

new 实现接口(){

}


new 父类构造器(实参){

}

例8.

interface A{
void test();
}
public class ATest {

public static void main(String[] args){
int age = 8;
A a = new A(){
public void test(){
System.out.println(age);//从java8开始,匿名内部类,局部内部类允许访问非final的局部变量
}
};
a.test();
}
}
运行结果:8(java8下,8之前会出现编译错误)
<span style="font-size:14px;">从java8开始,匿名内部类,局部内部类允许访问非final的局部变量</span>


参考资料/article/5043667.html

疯狂Java讲义
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: