java中的内部类
概述将一个类定义在另一个类的里面,里面的那个类就称为内部类(内置类,嵌套类) 分析事物A时,发现该事物A描述中还有事物B,而且这个事物B还在访问被描述事物A的内容,将事物B定义成内部类来描述。 特点
举例: package innerdemo; public class InnerDemo1 { public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); // 直接访问内部类的方法 in.show(); Outer o = new Outer();// o.method(); } } class Outer{ private int num = 3; // 内部类 class Inner{ void show(){ num = 100; System.out.println("内部类run..."+num); } } public void method(){ Inner in = new Inner(); //外部类要访问内部类,必须建立内部类的对象; in.show(); } } 修饰符
细节package java_demo_2; public class InnerClassDemo { public static void main(String[] args) { new Outer().method(); } class Outer{ int num = 3; // 内部类 class Inner{ int num = 4; void show(){ int num = 5; System.out.println(num); // num 5 System.out.println(this.num); // 4 局部和成员变量重名 System.out.println(Outer.this.num); // 3 } } void method(){ new Inner().show(); } } 为什么内部类能直接访问外部类中成员呢? 那是因为内部类持有了外部类的引用。外部类名.this 局部内部类内部类可以存放在局部位置上,可以放在方法中,放在代码块中。 class Outer1{ int num = 3; void method(){ // 内部类在方法中 class Inner{ void show(){ System.out.println("方法中的内部类:"+num); } } // 创建对象 Inner in = new Inner(); in.show(); } { // 内部类在代码块中 class Inner2{ void show(){ System.out.println("代码块中的内部类:" + num); } } Inner2 in2 = new Inner2(); in2.show(); } } 内部类在局部位置上只能访问局部中被final修饰的局部变量; class Outer{ int num = 3; void method(){ final int x = 9; // 这个好像都行 int x = 9 不报错; class Inner{ void show(){ System.out.println("show..."+x); // 内部类在局部位置上只能访问局部中被final修饰的局部变量; } } // 创建对象 Inner in = new Inner(); in.show(); } } 匿名内部类概述内部类的简写格式。要简写,必须和外部类有关系。必须有前提:内部类必须继承或者实现一个外部类或者接口。 格式: new 父类or接口(){子类内容}; 匿名内部类,其实就是一个匿名子类对象;这个对象比较胖。 按道理要先继承父类,重构方法,再创建对象调用方法如: class Inner extends InnerDemo{ void show() { System.out.println("内部类run..." + num); } } public void method() { new Inner().show(); } 现在直接在方法里,进行new 父类(){重构方法;} new InnerDemo(){ // 匿名内部类,new 他爹(){把方法重写;} void show(){ System.out.println("show..."+num); } } 具体代码如下: public class InnerClassDemo { public static void main(String[] args) { new Outer().method(); } } // 抽象类 abstract class InnerDemo{ abstract void show(); } class Outer { private int num = 3; // 内部类 // class Inner { // void show() { // System.out.println("内部类run..." + num); // } // // } public void method() { // new Inner().show(); new InnerDemo(){ // 匿名内部类,new 他爹(){把方法重写;} void show(){ System.out.println("show..."+num); } }.show(); } } 应用注释部分:普通内部类继承外部接口时代码: interface Inter{ void show1(); void show2(); } class Outer { private int num = 3; // 内部类 /* class Inner implements Inter { public void show1(){ } public void show2(){ } } */ public void method(){ // Inner in = new Inner(); // in.show1(); // in.show2(); Inter in = new Inter(){ public void show1(){ } public void show2(){ } }; in.show1(); in.show2(); } } 通常的使用场景之一:当函数参数是接口类型时,而且接口中的方法不超过三个,可以用匿名内部类作为实际参数进行传递。 // 正常写 public class InnerClassDemo { public static void main(String[] args) { show(new InterImpl()); } public static void show(Inter in){ in.show1(); in.show2(); } } interface Inter{ void show1(); void show2(); } class InterImpl implements Inter{ public void show1(){} public void show2(){} } // 简写,将匿名内作为实际参数传递 public class InnerClassDemo { public static void main(String[] args) { show(new Inter(){ public void show1(){} public void show2(){} }); } public static void show(Inter in){ in.show1(); in.show2(); } } //接口 interface Inter{ void show1(); void show2(); } 分类
成员内部类
package innerdemo; /** * @ClassName: InnerClassDemo * @author: benjamin * @version: 1.0 * @description: TODO * @createTime: 2019/06/11/10:11 */ public class InnerClassDemo { public static void main(String[] args) { // 创建静态内部类的对象 Person.Dog d = new Person.Dog();// 直接通过外部类调用静态内部类的构造器 //创建非静态内部类的对象 // Person.Bird b = new Person().new Bird(); Person p = new Person(); Person.Bird b = p.new Bird();// 通过外部类的对象调用内部类的构造器 b.info(); } } class Person{ String name; int age; // 非静态成员内部类 class Bird{ String name; int id; public Bird(){ } public void setName(String name){ this.name = name; } public void info(){ show(); } } // 静态成员内部类 static class Dog{ String name; int id; public Dog(){ } public void setName(String name){ this.name = name; } public void info(){ } } // 外部类的成员方法 public void show(){ System.out.println("我是外部类的show()方法"); } } 局部内部类:常常使用一个方法,使其返回值为某个类或接口的对象,而这个类或接口在方法内部创建。举例: 匿名内部类: 举例: class OuterJu{ // 局部内部类的使用 public Comparable getComparable(){ //1.创建一个实现Comparable接口的类:局部内部类 class MyComparable implements Comparable{ @Override public int compareTo(Object o) { return 0; } } // 2. 返回一个实现类的对象 return new MyComparable(); } // 匿名内部类的使用 public Comparable getComparable1(){ //返回一个实现Comparable接口的匿名内部类的对象 return new Comparable() { @Override public int compareTo(Object o) { return 0; } }; } } 细节细节1 主函数会报错,因为无法访问非静态类,而且由于是静态不能采用this.new Inner() 方法:需要将Inner定义成静态类; package java_demo_2; /** * @ClassName: InnerClassDemo5 * @author: benjamin * @version: 1.0 * @description: TODO * @createTime: 2019/04/13/22:28 */ public class InnerClassDemo5 { class Inner{// 如果不定义成静态,主函数会报错; } public static void main(String[] args) { new Inner(); //无法从静态上下文中引用非静态 变量 this // 因为主函数是静态的; } public void method(){ new Inner(); // 正确 } public static void show(Inter in){ in.show1(); in.show2(); } } interface Inter{ void show1(); void show2(); } 细节2: // 正确的 package java_demo_2; public class InnerClassDemo6 { public static void main(String[] args) { new Outer6().method(); } } class Outer6{ // 创建的匿名内部类相当于 // class Inner6 extends Object{ // public void show(){ // System.out.println("show run"); // } // } // new Inner6.show(); void method(){ new Object(){ public void show(){ System.out.println("show run"); } }.show(); } } 编译看左边 package java_demo_2; public class InnerClassDemo6 { public static void main(String[] args) { new Outer6().method(); } } class Outer6{ void method(){ Object obj = new Object(){ public void show(){ System.out.println("show run"); } }; obj.show(); // Error:(35,13) java: 找不到符号 // 因为匿名内部类这个子类对象被向上转型为Object类型, // 这样就不再使用子类特有的方法了; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |