java 内部类

内部类

将类定义在另一个类的内部,叫做内部类。

|--由来:
分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述的内容,"还有的事物"就用内部类来描述。

|-- 内部类可以访问所在外部类的私有成员。
|-- 内部类加上接口 可以很好的实现多继承的效果。
|-- 内部类一个主要的用途,GUI用户图形界面设计的事件处理。
|-- main方法所在的内部类 不能在main方法中创建对象,main方法是静态的,内部类作 为成员是非静态的,在静态方法main中不能用非静态的内部类。
|-- .class文件
┗━编译之后,内部类也会产生.class 文件,名称形式:Outer$Inner.class中间用$符号分隔开,表示所属关系。
--内部类之所以可以访问外部类的所有成员,内部类和外部类对象有 
this reference 关系。在内部类当中有隐式的Outer.this引用,所以可以直接用,相当于有外部类对象一样,可以直接使用外部类成员。
--如果在局部有同名成员,那么就近原则,若想访问自身的,就用this.引用,若想访 问外部的就用Outer.this.去引用其成员变量。若要在main方法中使用inner类成员。
┗━理解:内部类 相当于是所属外部类的成员,所以要先有外部类对象再去调用成员,所以要现有new Outer.先创建所属外部类对象。
可以:Outer out=new Outer();
Inner in=out.new Inner();//分布写
一个式子:Outer.Inner inner = new Outer().new Inner();


--所属外部类、内部类、内部类局部 三种变量访问:
--局部:直接访问名字
--内部类:this.+变量名,访问内部类成员变量,Inner.this.+变量名 结果也是内部类的成员变量。
--所属外部类:同理:Outer.this.+变量名,得到的是所属外部类的成员变量。


--如果内部类在局部位置上
--内部类 访问局部变量: 内部类只能访问被 final 修饰的局部变量。
final为常量,生命周期长。不然,变量随着进栈用完后就出栈了,在用内部类对象去调用该变量就调用失败了。比如,在方法中的内部类,在方法中创建了一个内部类对象并return这个对象,用Object objmain中接收(多态),用过之后,再用obj调用局部变量时,就找不到该变量了,因为已经出栈了。
|--简单说就是局部变量 和 对象的生存周期不同。


--内部类可以声明在方法中,也可以放到 if 语句当中,还可以把内部类的定义放到 语句块 中。不管内部类 嵌套的层次多深,都可以访问所在外部类的成员。


--内部类可以被声明为 private ,和修饰方法一样。内部类 也可以是 抽象 的。可以 是静态的static 。也可以是final。也可以是protected

--非静态 内部类 中不能有 静态成员的声明。****内部类中有静态成员时,内部类必 须是静态的。

--静态内部类 :static修饰就变成了顶层类,外部类一加载也跟着加载,创建内部类 
对象:new Outer.Inner();// 相当于外部类类名直接调用静态成员。
-- 创建内部类对象格式:Outer.Inner Inter = new Outer.Inner();
-- 同样,静态内部类只能访问静态成员。
-- 静态内部类,有静态方法,调用:Outer.Inner.function();

--内部类被继承:被继承后,其子类需要调用它的构造方法,而内部类的构造方法的调 用需要先产生所在外部类的 对象,再产生内部类的对象,从而建立起引用关系。

内部类的特点:内部类可以直接访问外部类中的成员,而外部类要访问内部类的成员必须要建立内部类的对象.

内部类在不同的位置上具有不同的特性:内部类定义在成员位置上可以被private static修饰,被static修饰的内部类只能访问外部类中的静态成员;内部类定义在局部位置上,也可以直接访问外部类中的成员,同时也可以访问局部变量,但变量必须被final修饰.

 

public class Test1 {
 
        class InnerBBB {
 
                int b=100;
 
        }
 

        public static void main(String[] args) {
 
                Test1 test1 = new Test1();
 
                AAA innerAAA = test1.method();//如果innerBBB不声明为final,方法执行完innerBBB出栈,就无法访问成员变量b的值
 
                innerAAA.run();
 
        }
 

        public AAA method() {
 
                final InnerBBB innerBBB = new InnerBBB();//声明为final
 
                class InnerAAA implements AAA {
 
                        @Override
 
                        public void run() {
 
                                System.out.println("访问内部类InnerBBB的成员变量b的值是"+innerBBB.b);
 
                        }
 
                }
 
                InnerAAA innerAAA = new InnerAAA();
 
                // innerAAA.run();
 
                return innerAAA;
 

        }
 
}
 

interface AAA {
 
        void run();
 
}


 

 

子类建立对象时 需要调用 父类(内部类)的构造方法,而内部类的构造方法被调用需要通过所在外部类的的对象,也就是需要建立关系。

匿名内部类 

格式:new 父类或接口(){子类要覆盖的方法},使用前提:内部类必须是继承一个类或者实现接口,匿名内部类其实就是建立一个建立一个带内容的外部类或者接口的子类匿名对象.

实质:是一个类或接口的 匿名内部子类的对象,用法是这样。
匿名内部类是内部类的简写形式。
使用前提:
内部类必须继承 或者 实现一个外部类或者接口。不然创建对象没名字就出错。
想继承 或者 实现谁,创建匿名内部类就用那个父类 或者 父接口。

就是用父类 或 接口区创建一个子类或子接口,必须要先存在一个类或接口,再用这个类或者接口去创建子类或子接口。

比如,一个抽象类,里面有抽象方法,
格式:new 抽象类(){实现抽象方法(子类内容)}.实现的方法(); 
就是子类对象调用实现的方法。这就是匿名内部类。

没有名字 可以用父类 或 父接口创建的对象引用 接收:
Outer outer = new Outer()
匿名子类内容; }
这样就可以用了。利用的多态。


万能匿名内部类:new Object()
子类内容 }.子类方法();


匿名内部类.class 文件:Outer$1.class....Outer$2.class 用阿拉伯数字按顺序生成。

匿名内部类在图形界面设计中比较常用,添加一个组件,可以直接用匿名内部类的形式添加。注册一个事件,可以也能够匿名内部类的形式简化书写,因为,只需要用到一个方法。集合里面的比较器,也可以用匿名内部类的形式,把匿名内部类当做参数传递给需要用比较器的集合构造方法。使用非常方便,也非常灵活。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值