内部类
2015-11-07 15:11
330 查看
1.内部类的定义:把一个类定义到另外一个类的内部的这种类的定义形式,称其被定义在类的内部的类叫做内部类
比如:
2.如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体的指明这个对象的类型:外部类类名.内部类类名的方式
3.当生成一个内部类的对象的时候,此对象与制造它的外部对象之间就有了一种联系,因此内部类可以访问它的外部类的对象的所有成员,不需要任何的特殊条件,此外,内部类还拥有外部类的所有元素的访问权限。
4.内部类的对象只能在与其外围类的对象相关的情况下才可以被创建,构建内部类对象的时候,需要 有一个指向其外部类对象的引用,如果编译器访问不到这个引用的话,编译器就会报错。
5.如果需要生成外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。这样产生的引用自动具有正确的类型,这点在编译期就被知晓并受到了检查,因此没有任何运行时开销。
7.要想创建一个内部类的对象,必须使用外部类的对象来创建该内部类的对象。但是如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象引用。
例如:
9.在方法和作用域中的内部类
1)定义在方法中的类
2)定义在作用域中的类,此作用域在方法的内部。
3)一个实现了接口的匿名类。
4)一个匿名类,它扩展了有非默认构造器的类。
5)一个匿名类,执行它字段的初始化
6)一个匿名类,他通过实例初始化实现构造(匿名类不可能有构造器)
10.匿名内部类
1)匿名内部类通过new表达式返回的引用被自动向上转型为其的引用。
2)在匿名内部类的末尾的分号,并不是用来标记此内部类结束的。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了匿名内部类。
3)如果定义一个匿名内部类,并且希望它使用一个再其外部定义的对象,那么编译器会要求其参数引用是final的,如果忘记写final的话,在编译器编译的时候回收到一条编译时的错误信息。
4)在匿名内部类中是不可能有命名构造器的,但是可以通过实例进行初始化。
5)对于匿名类而言,实力初始化的实际效果就是构造器,当然他收到了限制,你不能重载实例初始化的方法,所以你仅有这样一个构造器
6)匿名内部类和正规的继承相比较是受到限制的,因为匿名内部类既可以扩展类,也可以实现接口,但是两个不能同时兼备,如果是实现接口,也只能实现一个接口。
11.嵌套类
1)定义:如果不需要内部类和外围类的对象之间再有联系,那么可以将内部类声明为static,这种形式的类就叫做嵌套类。
2)要创建嵌套类的对象,并不需要外围类的对象
3)不能从嵌套类的对象中访问非静态的外围类对象
4)普通内部类的字段和方法只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含static字段和static数据。
5)一个普通的(非static)的内部类中,通过一个特殊的this引用可以链接到其外部类的对象。嵌套类就没有这个特殊的this引用,这使得他类似于一个static方法。
12.接口内部的类
1)正常情况下,不能再接口内部放置任何的代码,但是嵌套类可以作为接口的一部分,你放入其中的任何类都自动的是public和static的,因为类是static的,只是将嵌套类置于接口的命名空间内,这并不违反接口的原则。而且可以在内部类中实现其外部类的接口。
2)如果要创建某些公共的代码,使得他们可以被某个接口的所有不同的实现所共用,此时选择接口内部的嵌套类是很方便的。
12.不管一个内部类被嵌套了多少层,他能够透明的访问所有它所嵌入的外围类的所有成员
例如:
1)一般说是内部类继承自某个类或者实现某个接口,内部类的代码操作创建它的外部类的对象,所以可以认为内部类提供了某种进入外部类的窗口。
2)每个内部类都能独立的继承自一个(接口的)实现,所以无论外部类是否已经继承了某个(接口)的实现,对于内部类都没有影响。
3)内部类允许继承多个非接口类型
4)如果拥有的是抽象的类或者具体的类,而不是接口,那就只能使用内部类才能实现多重继承。
14.内部类的一些特性:
1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外部类的对象的信息相互独立。
2)在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
3)创建内部类对象的时刻并不依赖于外部类对象的创建。
4)内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。
15.一些知识点
1)内部类的继承:因为内部类的构造器必须连接到指向其外部类对象的引用,所以在继承内部类的时候,事情会变得有些复杂。
2)内部类可以覆盖,但是没有什么大的作用
3)局部内部类:典型的方式就是在一个方法体里面创建。局部内部类不能有访问说明符,因为它不是外部类的一部分,但是它可以访问当前代码块的常量一级外部类的所有成员。
4)局部内部类的名字在方法外是不可见的,那么为什么我们还要使用局部内部类而不是匿名类?
我们需要一个以命名的构造器或者需要重载构造器,而匿名内部类只能用于实例初始化。
使用局部内部类而不使用匿名内部类的另一个理由就是,需要不止一个该内部类的对象。
5)内部类的标识符:内部类也必须生成一个.class文件以包含他们的Class信息,这些文件的命名有严格的规则,外部类的名字加上$再加上内部类的名字。如果内部类是嵌套在其他的内部类之中,只需要将他们的名字加在其外部类标识符与"$"的后面。
比如:
<span style="font-size:14px;">public class InnerClass { class Content{ } } </span>上述代码中的Content为InnerClass的内部类,而InnerClass为Content的外部类。
2.如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体的指明这个对象的类型:外部类类名.内部类类名的方式
3.当生成一个内部类的对象的时候,此对象与制造它的外部对象之间就有了一种联系,因此内部类可以访问它的外部类的对象的所有成员,不需要任何的特殊条件,此外,内部类还拥有外部类的所有元素的访问权限。
4.内部类的对象只能在与其外围类的对象相关的情况下才可以被创建,构建内部类对象的时候,需要 有一个指向其外部类对象的引用,如果编译器访问不到这个引用的话,编译器就会报错。
5.如果需要生成外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。这样产生的引用自动具有正确的类型,这点在编译期就被知晓并受到了检查,因此没有任何运行时开销。
<span style="font-size:14px;">public class A { void a(){ System.out.println("a"); } //创建内部类 public class Inner{ //返回A类型的值 public A aa(){ //生成对外部类对象的引用 return A.this; } } public Inner inner(){ return new Inner(); } public static void main(String[] args) { A aaa = new A(); A.Inner ai = aaa.inner(); ai.aa().a(); } } </span>6.有时候需要告知某些其他的对象,去创建其某个内部类的对象。要实现此目的,必须在new表达式中提供对其他外部类对象的引用,这是需要使用.new语法。
7.要想创建一个内部类的对象,必须使用外部类的对象来创建该内部类的对象。但是如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象引用。
例如:
<span style="font-size:14px;">public class OutClass { public class Inner{ } public static void main(String[] args) { OutClass outClass = new OutClass(); //创建内部类的对象 OutClass.Inner inner = outClass.new Inner(); } } </span>8.内部类与向上转型:内部类向上转型只是指向基类或接口的引用,所以能够很方便的隐藏实现的细节。
9.在方法和作用域中的内部类
1)定义在方法中的类
2)定义在作用域中的类,此作用域在方法的内部。
3)一个实现了接口的匿名类。
4)一个匿名类,它扩展了有非默认构造器的类。
5)一个匿名类,执行它字段的初始化
6)一个匿名类,他通过实例初始化实现构造(匿名类不可能有构造器)
10.匿名内部类
1)匿名内部类通过new表达式返回的引用被自动向上转型为其的引用。
2)在匿名内部类的末尾的分号,并不是用来标记此内部类结束的。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了匿名内部类。
3)如果定义一个匿名内部类,并且希望它使用一个再其外部定义的对象,那么编译器会要求其参数引用是final的,如果忘记写final的话,在编译器编译的时候回收到一条编译时的错误信息。
4)在匿名内部类中是不可能有命名构造器的,但是可以通过实例进行初始化。
5)对于匿名类而言,实力初始化的实际效果就是构造器,当然他收到了限制,你不能重载实例初始化的方法,所以你仅有这样一个构造器
6)匿名内部类和正规的继承相比较是受到限制的,因为匿名内部类既可以扩展类,也可以实现接口,但是两个不能同时兼备,如果是实现接口,也只能实现一个接口。
11.嵌套类
1)定义:如果不需要内部类和外围类的对象之间再有联系,那么可以将内部类声明为static,这种形式的类就叫做嵌套类。
2)要创建嵌套类的对象,并不需要外围类的对象
3)不能从嵌套类的对象中访问非静态的外围类对象
4)普通内部类的字段和方法只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含static字段和static数据。
5)一个普通的(非static)的内部类中,通过一个特殊的this引用可以链接到其外部类的对象。嵌套类就没有这个特殊的this引用,这使得他类似于一个static方法。
12.接口内部的类
1)正常情况下,不能再接口内部放置任何的代码,但是嵌套类可以作为接口的一部分,你放入其中的任何类都自动的是public和static的,因为类是static的,只是将嵌套类置于接口的命名空间内,这并不违反接口的原则。而且可以在内部类中实现其外部类的接口。
2)如果要创建某些公共的代码,使得他们可以被某个接口的所有不同的实现所共用,此时选择接口内部的嵌套类是很方便的。
<span style="font-size:14px;">public class Test { public void a(){ System.out.println("a"); } public static class Tester{ public static void main(String[] args) { Test t = new Test(); t.a(); } } } </span>此时生成了一个独立的类Test$Tester.
12.不管一个内部类被嵌套了多少层,他能够透明的访问所有它所嵌入的外围类的所有成员
例如:
<span style="font-size:14px;">class AA { private void f(){} class B{ private void g(){} public class C{ void h(){ g(); f(); } } } } public class A{ public static void main(String[] args) { AA aa = new AA(); AA.B b = aa.new B(); AA.B.C c = b.new C(); c.h(); } }</span>13.为什么需要内部类?
1)一般说是内部类继承自某个类或者实现某个接口,内部类的代码操作创建它的外部类的对象,所以可以认为内部类提供了某种进入外部类的窗口。
2)每个内部类都能独立的继承自一个(接口的)实现,所以无论外部类是否已经继承了某个(接口)的实现,对于内部类都没有影响。
3)内部类允许继承多个非接口类型
4)如果拥有的是抽象的类或者具体的类,而不是接口,那就只能使用内部类才能实现多重继承。
14.内部类的一些特性:
1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外部类的对象的信息相互独立。
2)在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
3)创建内部类对象的时刻并不依赖于外部类对象的创建。
4)内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。
15.一些知识点
1)内部类的继承:因为内部类的构造器必须连接到指向其外部类对象的引用,所以在继承内部类的时候,事情会变得有些复杂。
2)内部类可以覆盖,但是没有什么大的作用
3)局部内部类:典型的方式就是在一个方法体里面创建。局部内部类不能有访问说明符,因为它不是外部类的一部分,但是它可以访问当前代码块的常量一级外部类的所有成员。
4)局部内部类的名字在方法外是不可见的,那么为什么我们还要使用局部内部类而不是匿名类?
我们需要一个以命名的构造器或者需要重载构造器,而匿名内部类只能用于实例初始化。
使用局部内部类而不使用匿名内部类的另一个理由就是,需要不止一个该内部类的对象。
5)内部类的标识符:内部类也必须生成一个.class文件以包含他们的Class信息,这些文件的命名有严格的规则,外部类的名字加上$再加上内部类的名字。如果内部类是嵌套在其他的内部类之中,只需要将他们的名字加在其外部类标识符与"$"的后面。
相关文章推荐
- OFFSET & FETCH
- Cookie / Session / URL重写
- Codeforces 558C Amr and Chemistry
- 泰秘丽人会,女性最放心的丰胸品牌
- Input:Key Logs
- NOIP2015游记
- Jstl标签库/Filter过滤器
- how to do a mass update in Laravel5 ( 在Laravel 5里面怎么做大量数据更新 )
- Error deploying web application directory D:\apache-tomcat-8.0.26\webapps\servlet
- 系统级I/O
- 一些DNS地址
- 第一次写博客
- Linux rpm 命令参数使用详解[介绍和应用]
- mysql中的关键字
- maven依赖
- QqFriendList.java
- Ascii表
- [置顶] 增量会话对象——DeltaSession
- 高三,是与信息再见,还是新的旅程?
- oc-字符串NSString,NSMutablesString基本使用方法