------- android培训、java培训、期待与您交流! ----------
内部类
将一个类定义在另一个类的里边,里边的那个类就是内部类
例如:
class Outer { int x = 3; class Inner//内部类 { void funciton() { System.out.println("inner"); } } void method() { System.out.println(x); } }
定义内部类的好处
将Inner定义在外部,当Inner想要调用Outer类中的成员时候,
就得在类中定义一个Outer对象后,才能调用。
但是当定义成内部类的时候,要想访问Outer中的成员的时候,就不用创建Outer了,可以直接访问,包括私有数据。(也就是一个类中定义的成员,可以在本类中任何一定地方被访问,包括在内部类中)
class Outer { int x = 3; class Inner//内部类 { void funciton() { System.out.println(x);//直接访问外部类的x } } }
但是外部类访问内部类的时候,必须建立内部类对象。(互访方式)
如下:
void method() { new Inner().funciton(); }
现在能不能直接访问内部类的成员呢?
不能这样在主函数中创建。
Inner in = new Inner(); In.function();
原因是当其它内部类中也有一个inner内部类的时候,并不知道创建了哪个,所以必须要有一个标识去定义内部类。
Outer.Inner inner = new Outer().new Inner();
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
就是这种格式。一般不这样去创建一个内部类。
为什么内部类中能直接访问外部类中的成员?
class Outer { private int x = 3; class Inner//内部类 { int x = 4; void funciton() { int x = 6; System.out.println(x);//打印出了6 System.out.println(this.x);//打印出来4 System.out.println(Outer.this.x);//打印出来3,也就是外部类的成员 } } }
这也就说明了在内部类中如果直接调用外部类的成员时候,系统默认的写了Outer.this
也就是持有了一个外部类的引用。
当内部类在成员位置上,就可以被成员修饰符所修饰。比如
Private:将内部类在外部类中进行封装。
Static :内部类就具备了静态的特性
当内部类被静态修饰后,只能直接访问外部类中的静态成员了。出现了访问局限。
在外部其他类中,如何直接访问静态内部类?
Outer.Inner inner = new Outer.Inner(); inner.function();
也就是用外部类直接调用内部类之后再创建内部类、
这里为什么要创建Inner()对象呢,因为要访问Inner中的非静态方法,也就是带有this的方法。。
如果要只访问inner中的静态方法
则通过这种方式即可
Outer.Inner.funtion1();
注意:当内部类中的定义了静态成员,则该内部类必须是static的。
当外部类中的静态方法访问内部类时候,内部类也必须是静态的。否则
当外部类的静态方法加载时候,内部类还没有加载。
static class Inner2 { void show() { System.out.println("inner2 show"); } } public static void method() { new Inner2().show(); }
当描述事物时候,事物的内部还有事物,该事物用内部类来描述,因为内部事务在使用外部事物中的内容。(变量和方法)
只有当内部类作为外部类的成员时候,才能使用修饰符,如static和private
什么时候使用内部类:当描述事物的时候,事物的内部还有事物,该事物用内部类来描述,因为内部事物还在使用外部事物的内容。
当作为外部类方法的成员时候,内部类不能被修饰,不能成为静态。由于它本身不能成为静态,故内部类其中的方法和变量也不能定义成静态(规定其类必须为静态)。
内部类定义在局部的时候
1.不可以被成员修饰符修饰。
2.可以直接访问外部类中的成员,因为还持有外部类中的引用。Outer.this
但是不可以访问它所在的局部中(也就是在方法中)的变量。只能访问被final修饰的局部变量。
如下所示:
class Outer3 { private int a = 33; public void funtion() { final int bb=90; class Inner3 { void ff() { System.out.println(a); System.out.println(bb); } } } }
匿名内部类:(其实就是定义在局部中的一个特殊的类,与一般定义在局部中的类具有相同的规则)
1. 匿名内部类其实就是定义在局部中的内部类的简写格式。
2. 匿名内部类也就是没有名字的内部类。
3. 定义匿名内部类的前提:内部类必须继承一个类或者实现接口。
4. 也就是当你想创建的一个内部类是一个实现了某个接口的内部类,则可以用匿名的方式去创建这个内部类并调用其中的方法。
5. 定义一个匿名内部类主要的作用是为了实现其接口中特定的方法并实现(由于这个内部类可以方便得到外部类中的成员属性),然后在某个外部类中的成员方法中去调用这个方法去完成某些功能。
如下:
interface Demo { void show(); } class Outer { int x = 3 ; public void function() { new Demo(){ public void show() { // TODO Auto-generated method stub System.out.println(x); } public void cctv() { System.out.println("vvv"); } }.cctv(); } }
6. 匿名内部类的格式:new父类或者接口(){定义子类的内容并实现父类或接口的抽象方法}.想调用的方法
7. 其实匿名内部类就是一个匿名子类对象。 也把定义类和创建对象封装为一体的形式。而且这个对象比较臃肿。
8. 匿名内部类不能同时调用其中的两个方法。当要调用多个方法时候,必须创建多个匿名对象。
9.匿名内部类中要定义的方法一定要少,否则太臃肿。
匿名内部类的常见使用方式。
当你要调用的方法参数为一个接口时候,而这个方法中使用这个接口调用了其中的方法。则可以在传递参数的时候传递一个匿名内部类。
如刚刚学到的TreeSet <Stirng> ts =new TreeSet<String>();
//当想传入一个比较器的时候,就可以使用匿名内部类的形式。
TreeSet<String> ts = new TreeSet<String>(new Comparator<String>(){ public int compare(String s,String s1) { return s.length()-s1.length(); } });
比较常见的方式。