Java内部类.docx
- 文档编号:25560332
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:20
- 大小:383.24KB
Java内部类.docx
《Java内部类.docx》由会员分享,可在线阅读,更多相关《Java内部类.docx(20页珍藏版)》请在冰豆网上搜索。
Java内部类
Java内部类
转自
Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类。
内部类又分为:
常规内部类、局部内部类、匿名内部类和静态嵌套类四种。
我们内部类的知识在Android手机开发中经常用到。
一、常规内部类
所谓常规内部类,或者说内部类,指的就是除去后面三种之外的内部类(这算什么解释。
。
。
)
先写一个最简单的内部类的例子,大家感觉一下:
1
public class Outer{
2
public class Inner{
3
}
4
}
编译一下,我们看到目录中出现了两个class文件,其中有一个文件名叫做Outer$Inner.class,带了一个$符号,这个特点让我们很容易的认出来这是内部类编译后的class文件。
再写一个稍微复杂一点的内部类:
01
public class Outer{
02
03
private int x=1;
04
05
public Outer(){
06
System.out.println("Outerinitial");
07
}
08
09
public class Inner{
10
11
public Inner(){
12
System.out.println("Innerinitial");
13
}
14
15
private int x=2;
16
17
public void add(){
18
int x=3;
19
System.out.println(x);
20
System.out.println(this.x);
21
System.out.println(Outer.this.x);
22
}
23
24
}
25
26
public static void main(String[]args){
27
Innerinner= new Outer().new Inner();
28
inner.add();
29
}
30
}
我们编译以后,运行一下看看:
在上面的例子里我们可以清晰的看到:
1.内部类就像一个实例成员一样存在于外部类中。
2.内部类可以访问外部类的所有成员就想访问自己的成员一样没有限制。
3.内部类中的this指的是内部类的实例对象本身,如果要用外部类的实例对象就可以用类名.this的方式获得。
4.内部类对象中不能有静态成员,原因很简单,内部类的实例对象是外部类实例对象的一个成员。
下面我们再小结一下内部类的创建方法:
1.在外部类的内部,可以用Innerinner=newInner();方法直接创建
2.在外部类外部,必须先创建外部类实例,然后再创建内部类实例,除了上面Innerinner=newOuter().newInner()的写法以外,还有Outerouter=newOuter();Innerinner=outer.newInner();的写法
二、局部内部类
我们也可以把类定义在方法内部,这时候我们称这个类叫局部内部类。
我们再看一个例子:
01
public class Outer{
02
03
int x=1;
04
public void doSomething(){
05
final int y=2;
06
class Inner{
07
int x=3;
08
void print(){
09
int x=4;
10
System.out.println(x);
11
System.out.println(this.x);
12
System.out.println(Outer.this.x);
13
System.out.println(y);
14
}
15
}
16
Innerinner= new Inner();
17
inner.print();
18
}
19
20
public static void main(String[]args){
21
Outerouter= new Outer();
22
outer.doSomething();
23
}
24
}
运行程序,查看结果:
我们通过上面这里例子也可以看到下面几点:
1.局部内部类的地位和方法内的局部变量的位置类似,因此不能修饰局部变量的修饰符也不能修饰局部内部类,譬如public、private、protected、static、transient等
2.局部内部类只能在声明的方法内是可见的,因此定义局部内部类之后,想用的话就要在方法内直接实例化,记住这里顺序不能反了,一定是要先声明后使用,否则编译器会说找不到。
3.局部内部类不能访问定义它的方法内的局部变量,除非这个变量被定义为final。
是不是有点不好理解?
关于为什么用final修饰以后就可以用了,我打算专门在番外篇里专门写一篇博客给你讲清楚,先记住吧。
三、匿名内部类
当我们把内部类的定义和声明写到一起时,就不用给这个类起个类名而是直接使用了,这种形式的内部类根本就没有类名,因此我们叫它匿名内部类。
我们再看一个有趣的例子:
01
public class Dog{
02
03
public interface Pet{
04
05
public void beFriendly();
06
public void play();
07
08
}
09
10
public static void main(String[]args){
11
12
Petdog= new Pet(){
13
@Override
14
public void beFriendly(){
15
System.out.println("蹭蹭你^_^");
16
}
17
@Override
18
public void play(){
19
System.out.println("把飞盘叼给你,逼你把飞盘丢出去,然后它再捡回来让你继续扔,连续500次^_^");
20
}
21
};
22
23
dog.beFriendly();
24
dog.play();
25
26
}
27
}
编译和运行程序,查看结果:
竟然编译和运行都很正常,我们知道抽象类和接口肯定无法实例化的,因此刚才的例子肯定有点意思:
1.第一匿名内部类可以是个接口,这个没什么好奇怪的哈。
2.第12行到第21行是一个语句,就是定义了一个对象,因此21行大括号后面有个分号。
3.匿名内部类用newPet(){…}的方式把声明类的过程和创建类的实例的过程合二为一。
4.匿名内部类可以是某个类的继承子类也可以是某个接口的实现类。
好吧我们再看一个例子,方法参数内的匿名内部类:
01
public class Dog{
02
03
static abstract class Ball{
04
abstract StringgetName();
05
}
06
07
void play(Ballb){
08
System.out.println(b.getName());
09
}
10
11
public static void main(String[]args){
12
Dogdog= new Dog();
13
14
dog.play(new Ball(){
15
@Override
16
StringgetName(){
17
return "qiuqiu";
18
}});
19
}
20
}
编译和运行以后的截图我就不给你了,返回值就是“qiuqiu”。
从第14行到第18行是一句话,就是执行一个play方法,而这个方法的参数就由一个匿名内部类的实例来提供。
四、静态嵌套类
为了让你感觉舒服一些,我们也把最简单的内部类放在最后讲。
当一个内部类前面用static修饰时,我们称之为静态嵌套类或者说静态内部类。
上面的例子里其实我们已经看到过静态嵌套类了,下面我们再举一个例子:
01
public class Outer{
02
03
static int x=1;
04
05
static class Nest{
06
07
void print(){
08
System.out.println("Nest"+x);
09
}
10
}
11
12
public static void main(String[]args){
13
Outer.Nestnest= new Outer.Nest();
14
nest.print();
15
}
16
}
因为静态嵌套类和其他静态方法一样只能访问其它静态的成员,而不能访问实例成员。
因此静态嵌套类和外部类(封装类)之间的联系就很少了,他们之间可能也就是命名空间上的一些关联。
上面例子中你需要注意的就是静态嵌套类的声明方法newOuter.Nest()连续写了两个类名,以至于我们都怀疑前面的Outer是个包名了,好在包名一般都小写的,要不还真分不清……
再强调一遍,内部类在Android中应用的非常多,理解和使用好显得蛮重要。
好了,本讲就到这里。
如何应用Java的静态内部类
在上一小节我们讨论了内部类,即在一个类中包含有另外一个或者多个类(见本书12.3.3小节)。
与内部类相似,静态内部类指在一个类的内部包含有另外一个或者多个静态类。
例如:
publicclassOuterClass{
...
staticclassStaticInnerClass1{ //内部静态类
//只可以访问OuterClass的静态成员
...
} //StaticInnerClass结束
...
staticclassStaticInnerClassN{ //更多静态内部类
//只可以访问OuterClass的静态成员
...
} //StaticInnerClassN结束
} //OuterClass结束
与一般内部类不同,在静态代码中不能够使用this操作,所以在静态内部类中只可以访问外部类的静态变量和静态方法。
使用静态内部类的目的和使用内部类相同。
如果一个内部类不依赖于其外部类的实例变量,或与实例变量无关,则选择应用静态内部类。
如下例子演示怎样使用静态内部类:
///完整程序存在本书配套资源目录Ch12名为StaticInnerClassTest.java
publicclassStaticInnerClassTest{
publicstaticvoidmain(Stringargs[]){
OuterClass2outer=newOuterClass2();
OuterClass2.StaticInnerClass.innerMethod();
//调用静态内部类的静态方法
OuterClass2.outerMethod();
//创建静态内部类对象
OuterClass2.StaticInnerClassstaticInner=newOuterClass2.StaticInnerClass();
intnum=staticInner.innerMethod2(); //调用静态内部类实例方法
}
}
classOuterClass2{ //外部类
privatedoublex=0.0; //内部静态类不可以访问外部类实 例变量
staticprivateintn=10; //外部类静态变量
staticvoidouterMethod(){ //外部类静态方法
System.out.println("fromOuterClass...");
}
voidouterMethod2(){
System.out.println("fromOuterClass’instancemethod2()...");
}
staticclassStaticInnerClass{ //静态内部类
staticprivateintm=5; //静态内部类静态变量
staticvoidinnerMethod(){ //静态内部类静态方法
intsum;
n=20; //只可以访问外部类静态变量
sum=n+m;
System.out.println("fromInnerClasssum="+sum);
outerMethod(); //只可以调用外部类静态方法
}
intinnerMethod2(){
n=100;
outerMethod();
System.out.println("fromInnerMethod2()n="+n);
returnn;
}
} //静态内部类结束
} //外部类结束
如同不用创建对象就可调用静态方法一样,上例静态内部类中的静态方法利用:
OuterClass2.StaticInnerClass.innerMethod(); //静态内部类调用其静态方法
来调用。
注意,可以在静态内部类的方法中,直接访问外部类的静态变量n和调用静态方法outerMethod()。
但不允许访问外部类的实例变量x以及实例方法outerMethod2()。
静态内部类中也可以提供实例方法,如:
staticclassStaticInnerClass{
intinnerMethod2(){
n=100; //只可访问外部类静态变量
outerMethod(); //只可调用外部类静态方法
System.out.println("fromInnerMethod2()n="+n);
returnn;
}
} //静态内部类结束
静态内部类的实例方法中亦只允许访问外部类的静态成员。
可以使用下列语法格式创建一个静态内部类对象并且调用其实例方法,以及静态方法:
OuterClass2.StaticInnerClassstaticInner=newOuterClass2.StaticInnerClass(); //创建静态内部类对象
intnum=staticInner.innerMethod2(); //调用实例方法
staticInner.innerMethod(); //调用其静态方法
java静态内部类的使用
[java] viewplaincopy
1.package Chapter10;
2.public class StaticInternal {
3. private static String name = "\"聂庆亮\"";
4. public static void setStatic(String n) { // 外部类的非静态方法
5. System.out.println("[现在访问的是外部类的静态方法!
]");
6. name = n;
7. }
8. static class InnerClass_2 { // 静态内部类开始
9. String address, mail; // 声明String类型变量
10. long phoneNum; // 声明long类型变量
11. int qq; // 声明int类型变量
12. static void getStatic() { // 静态内部类的静态方法
13. System.out.println("[访问外部类的静态变量] name = " + name);
14. setStatic("尹继平"); // 访问外部类的静态方法
15. }
16. // 静态内部类的非静态方法
17. public void setString(String address, String mail) {
18. System.out.println("1.静态内部类的带String型参数的非静态主法");
19. this.address = address;
20. this.mail = mail;
21. }
22. public void setInt(long phoneNum, int qq) {
23. System.out.println("2.静态内部类的带int型参数的非静态主法!
");
24. this.phone
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 部类