Java中的内部类详细总结
2015-06-09 20:48
567 查看
非静态内部类
例1.
运行结果: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.
运行结果:
局部变量:14
内部类变量:13
外部类变量:12
非静态内部类的变量访问形式
在非静态内部类的方法内访问某个变量时,优先在该方法内查找是否存在该名字的局部变量;
若无,到该方法所在的内部类中查找是否存在该名字的成员变量;
若无,到该内部类所在的外部类中查找是否存在该名字的成员变量;
if 外部类的成员变量,内部类的成员变量,内部类方法里的局部变量同名:
访问外部类的成员变量 Out.this.属性名
访问内部类的成员变量 this.属性名
访问内部类方法里的局部变量 属性名
例3.
不允许在外部类的静态成员中直接使用非静态内部类。
非静态内部类里不能有静态方法,静态成员变量,静态初始化块。
静态内部类
例4.
如果用static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性(静态成员不能访问非静态成员)
创建静态内部类对象的一般形式为: 外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()
例5.
外部类不能直接访问静态内部类的成员
可以使用静态内部类的类名作为调用者来访问静态内部类的类成员 如 In.a
可以使用静态内部类对象作为调用者来访问静态内部类的实例成员 如 new In().b
运行结果:购买了一个AGP花掉了567.8
例7.
购买了电子示波器价格是67.8
匿名内部类的初始化块
购买了键盘价格是56.2
匿名内部类必须继承一个父类或实现一个接口,但最多只能两者选其一
定义匿名内部类的格式如下:
new 实现接口(){
}
或
new 父类构造器(实参){
}
例8.
参考资料/article/5043667.html
疯狂Java讲义
例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讲义
相关文章推荐
- java可变参数
- Java for LeetCode 214 Shortest Palindrome
- Java 的通信编程,用 JAVA SOCKET 编程,读服务器几个 字符,再写入本地显示?
- java多线程之生产消费问题
- 2015届华为校园招聘机试题 java实现(2)
- java多线程 ThreadPoolExecutor 策略的坑
- SpringMVC+MyBatis项目总结(四)
- Spring4+Hibernate4+junit4环境搭建
- Spring学习笔记之Spring事务及事务测试
- Java for LeetCode 213 House Robber II
- maven搭建SpringMvc Hibernate Spring的pom.xml
- Java中的import static
- Java知多少(87)选择框和单选按钮
- Struts2 重点总结 (1)
- Java枚举
- 如何在Java 8中愉快地处理日期和时间
- java 中间件学习4-CountDownLatch、CyclicBarrier、Future和FutureTask
- Java for LeetCode 212 Word Search II
- 【2015/6/9】快速排序的java简单实现
- JDK环境变量配置(相对路径)