------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
内部类
1,什么叫内部类?
顾名思义,内部类就是定义在一个类中的类。
2,为什么会有内部类?怎么来的?
当我们进行java开发时,有时需要实现一个仅包含1-2个方法的接口。
例 :
顾名思义,内部类就是定义在一个类中的类。
2,为什么会有内部类?怎么来的?
当我们进行java开发时,有时需要实现一个仅包含1-2个方法的接口。
例 :
在学习集合框架的时候,有一个迭代器(Iterator接口),它里面就有一个方法iterator(),是专门用来给Colleaction集合进行迭代的,查看其底层发现它是嵌入在集合接口内部的。
例 :
例 :
在我们学习GUI时,当一个display组件需要一个事件回调方法时,如:一个按钮的ActionListener时,也是用到了内部类。
那么,以上两个例子要说明什么呢?
通过上面两个例子,我们会发现,如果我们不用内部类的方式来完成,而是使用普通类来实现这些操作,最终会得到很多仅在单个位置上使用的小型类,仅仅是为类一个小小的功能,就要创建一个类,是不是有点浪费呢? 所以为了解决这个问题就出现了内部类这个看上去很难懂的类。
当然,内部类还有很多理由值得我们来用,
理由(1)内部类可以直接访问外部类中的成员,包括私有。
理由(2)内部类可以对同一个包中的其它类隐藏起来。
理由(3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较方便。
3,内部类的访问规则
(1)内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类引用,格式:外部类名.this。
(2)外部类要访问内部类,必须要建立内部类对象。
通过上面两个例子,我们会发现,如果我们不用内部类的方式来完成,而是使用普通类来实现这些操作,最终会得到很多仅在单个位置上使用的小型类,仅仅是为类一个小小的功能,就要创建一个类,是不是有点浪费呢? 所以为了解决这个问题就出现了内部类这个看上去很难懂的类。
当然,内部类还有很多理由值得我们来用,
理由(1)内部类可以直接访问外部类中的成员,包括私有。
理由(2)内部类可以对同一个包中的其它类隐藏起来。
理由(3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较方便。
3,内部类的访问规则
(1)内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类引用,格式:外部类名.this。
(2)外部类要访问内部类,必须要建立内部类对象。
代码:
//外部类
class Outer {
//外部类私有成员变量
private int x = 3;//Outer.this.x
//内部类
class Inner {
//内部类成员
int x = 4;//this.x
//内部类成员方法
void function() {
//内部类局部变量
int x = 6;//x
System.out.println("Inner :" + x);//6
System.out.println("Inner :" + this.x);//4
//内部类可以直接访问外部类成员,包括私有
System.out.println("Inner :" +Outer.this. x);//3
}
}
//外部类成员方法
void method() {
//创建内部类成员变量
Inner in = new Inner();//外部类要访问内部类必须要创建内部类对象。
//调用内部类成员方法
in.function();
}
}
//测试类
public class InnerDemo {
public static void main(String[] args) {
//创建外部类对象
Outer out = new Outer();
//调用外部类成员方法。
out.method();
//直接访问内部类中的成员方法
Outer.Inner outin = new Outer().new Inner();
outin.function();
}
}
4,当内部类在成员位置上,并且被修饰符所修饰。
比如:private:将内部类在外部类中进行封装。
static:内部类具备静态的特性。 当内部类被static修饰后,只能直接访问外部类的static成员。出现了访问权限。
代码:
//外部类
class Outer1
{
//私有静态成员变量
private static int x= 3;
//静态内部类1
static class Inner1{
//静态内部类中的静态成员变量
static int x = 4;
//静态内部类中的静态成员方法
static void function(){
//非静态访问了静态
int x = 5;
//打印静态成员方法中的非静态变量
System.out.println(x);
//打印静态内部类中静态成员变量
System.out.println(Inner1.x);
//打印外部类的静态成员变量
System.out.println(Outer1.x);
}
}
//静态内部类2
static class Inner2{
//静态内部类的非静态成员方法
void function(){
//静态内部类访问外部类的静态成员变量
System.out.println(Outer1.x);
}
}
}
//测试类
public class InnerDemo2 {
public static void main(String[] args) {
//外部类访问静态内部类的静态方法
Outer1.Inner1.function();
//外部类访问静态内部类的非静态方法
new Outer1.Inner2().function();
}
}
注意:当内部类中定义了静态成员,该内部类必须是静态的。(因为静态只能访问静态)
当外部类的静态方法访问内部类时,内部类必须是静态的(同上)
5,什么时候使用内部类?
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部类事物在使用外部类事物的内容。
6,当内部类定义在局部时
(1)不可以被成员修饰符修饰。
(2)可以直接访问外部类中的成员,因为还持有外部类的引用。但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。
代码:
//外部类
class Outer2{
int x = 3;//Outer2.this.x
void method(final int a){
final int y = 4;
//局部内部类
class Inner{
void function(){
//局部内部类访问局部变量时,该变量必须是final常量。
System.out.println(y);
System.out.println(a);
System.out.println(x);//还持有外部类的引用
}
}
//外部类成员方法访问局部内部类的成员方法。
new Inner().function();
}
}
//测试类
public class InnerDemo3 {
public static void main(String[] args) {
//调用方法
new Outer2().method(7);
}
}
7,匿名内部类
(1)匿名内部类其实就是内部类的简写格式。
(2)定义匿名内部类前提:内部类必须是继承一个类或者实现接口。
(3)匿名内部类的格式:new 父类或者接口(){定义子类的内容}
(4)匿名内部类是一个匿名子类对象,可以理解为带内容的对象。
(5)匿名内部类中定义的方法最好不要超过三个。
代码:
//抽象类
abstract class AbsDemo{
//抽象方法
abstract void show();
}
//外部类
class Outer3{
int x = 3;
public void function(){
//创建匿名内部类的对象
AbsDemo d= new AbsDemo(){//父类引用指向子类对象
void show(){
System.out.println(x);
}
};
//实现接口的子类对象调用复写父类的方法。
d.show();
//-------------------------------------------------------------------
//通过匿名内部类的匿名子类对象来调用复写父类的方法。
new AbsDemo(){//父类引用指向子类对象
void show(){
System.out.println(x);
}
}.show();
}
}
//测试类
public class InnerDemo4 {
public static void main(String[] args) {
//通过外部类匿名对象调用方法
new Outer3().function();
}