`
chenxiaobin
  • 浏览: 24285 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

理解嵌套类和内部类(转)

    博客分类:
  • java
阅读更多
1.2 深入理解嵌套类和内部类
1.2.1 什么是嵌套类及内部类?
可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:
静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为
内部类(inner)。嵌套类从JDK1.1开始引入。其中inner类又可分为三种:
    其一、在一个类(外部类)中直接定义的内部类;
    其二、在一个方法(外部类的方法)中定义的内部类;
    其三、匿名内部类。
下面,我将说明这几种嵌套类的使用及注意事项。
1.2.2 静态嵌套类
如下所示代码为定义一个静态嵌套类,

public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";

static class Person{
private String address = "swjtu,chenDu,China";
public String mail = "josserchai@yahoo.com";//内部类公有成员
public void display(){
//System.out.println(id);//不能直接访问外部类的非静态成员
System.out.println(name);//只能直接访问外部类的静态成员
System.out.println("Inner "+address);//访问本内部类成员。
}
}

public void printInfo(){
Person person = new Person();
person.display();

//System.out.println(mail);//不可访问
//System.out.println(address);//不可访问

System.out.println(person.address);//可以访问内部类的私有成员
System.out.println(person.mail);//可以访问内部类的公有成员

}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
在静态嵌套类内部,不能访问外部类的非静态成员,这是由Java语法中"静态方法不能直接访问非静态成员"所限定。
若想访问外部类的变量,必须通过其它方法解决,由于这个原因,静态嵌套类使用很少。注意,外部类访问内
部类的的成员有些特别,不能直接访问,但可以通过内部类来访问,这是因为静态嵌套内的所有成员和方法默认为
静态的了。同时注意,内部静态类Person只在类StaticTest 范围内可见,若在其它类中引用或初始化,均是错误的。
1.2.3 在外部类中定义内部类
    如下所示代码为在外部类中定义两个内部类及它们的调用关系:

public class Outer{
int outer_x = 100;

class Inner{
public int y = 10;
private int z = 9;
int m = 5;
public void display(){
System.out.println("display outer_x:"+ outer_x);
}
private void display2(){
System.out.println("display outer_x:"+ outer_x);
}

}

void test(){
Inner inner = new Inner();
inner.display();
inner.display2();
//System.out.println("Inner y:" + y);//不能访问内部内变量
System.out.println("Inner y:" + inner.y);//可以访问
System.out.println("Inner z:" + inner.z);//可以访问
System.out.println("Inner m:" + inner.m);//可以访问

InnerTwo innerTwo = new InnerTwo();
innerTwo.show();
}

class InnerTwo{
Inner innerx = new Inner();
public void show(){
//System.out.println(y);//不可访问Innter的y成员
//System.out.println(Inner.y);//不可直接访问Inner的任何成员和方法
innerx.display();//可以访问
innerx.display2();//可以访问
System.out.println(innerx.y);//可以访问
System.out.println(innerx.z);//可以访问
System.out.println(innerx.m);//可以访问
}
}

public static void main(String args[]){
Outer outer = new Outer();
outer.test();
}
}
以上代码需要说明有,对于内部类,通常在定义类的class关键字前不加public 或 private等限制符,若加了
没有任何影响,同时好像这些限定符对内部类的变量和方法也没有影响(?)。另外,就是要注意,内部类Inner及
InnterTwo只在类Outer的作用域内是可知的,如果类Outer外的任何代码尝试初始化类Inner或使用它,编译就不
会通过。同时,内部类的变量成员只在内部内内部可见,若外部类或同层次的内部类需要访问,需采用示例程序
中的方法,不可直接访问内部类的变量。

1.2.4 在方法中定义内部类
    如下所示代码为在方法内部定义一个内部类:

public class FunOuter {
int out_x = 100;

public void test(){
class Inner{
String x = "x";
void display(){
System.out.println(out_x);
}
}
Inner inner = new Inner();
inner.display();
}

public void showStr(String str){
//public String str1 = "test Inner";//不可定义,只允许final修饰
//static String str4 = "static Str";//不可定义,只允许final修饰
String str2 = "test Inner";
final String str3 = "final Str";
class InnerTwo{
public void testPrint(){
System.out.println(out_x);//可直接访问外部类的变量
//System.out.println(str);//不可访问本方法内部的非final变量
//System.out.println(str2);//不可访问本方法内部的非final变量
System.out.println(str3);//只可访问本方法的final型变量成员
}
}
InnerTwo innerTwo = new InnerTwo();
innerTwo.testPrint();
}

public void use(){
//Inner innerObj = new Inner();//此时Inner己不可见了。
//System.out.println(Inner.x);//此时Inner己不可见了。
}


public static void main(String[] args) {
FunOuter outer = new FunOuter();
outer.test();
}
}

从上面的例程我们可以看出定义在方法内部的内部类的可见性更小,它只在方法内部
可见,在外部类(及外部类的其它方法中)中都不可见了。同时,它有一个特点,就是方法
内的内部类连本方法的成员变量都不可访问,它只能访问本方法的final型成员。同时另一个
需引起注意的是方法内部定义成员,只允许final修饰或不加修饰符,其它像static等均不可用。
1.2.5 匿名内部类
    如下所示代码为定义一个匿名内部类:匿名内部类通常用在Java的事件处理上


import java.applet.*;
import java.awt.event.*;

    public class AnonymousInnerClassDemo extends Applet{
    public void init(){
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent me){
             showStatus("Mouse Pressed!");
        }
        })
    }
    public void showStatus(String str){
        System.out.println(str);
    }
    }

在 上面的例子中,方法addMouseListener接受一个对象型的参数表达式,于是,在参数里,我们定义了一个匿名内部类这个类是一个 MouseAdapter类型的类,同时在这个类中定义了一个继承的方法mousePressed,整个类做为一个参数。这个类没有名称,但是当执行这个 表达式时它被自动实例化。同时因为,这个匿名内部类是定义在AnonymousInnerClassDemo 类内部的,所以它可以访问它的方法 showStatus。这同前面的内部类是一致的。
1.2.6 内部类使用的其它的问题

通过以上,我们可以清楚地看出内部类的一些使用方 法,同时,在许多时候,内部类是在如Java的事件处理、或做为值对象来使用的。同时,我们需注意最后一个问题,那就是,内部类同其它类一样被定义,同样 它也可以继承外部其它包的类和实现外部其它地方的接口。同样它也可以继承同一层次的其它的内部类,甚至可以继承外部类本身。下面我们给出最后一个例子做为 结束:



public class Layer {
//Layer类的成员变量
private String testStr = "testStr";

//Person类,基类
class Person{
String name;
Email email;
public void setName(String nameStr){
this.name = nameStr;
}
public String getName(){
return this.name;
}
public void setEmail(Email emailObj){

this.email = emailObj;
}
public String getEmail(){
return this.email.getMailStr();
}
//内部类的内部类,多层内部类
class Email{
String mailID;
String mailNetAddress;
Email(String mailId,String mailNetAddress){
this.mailID = mailId;
this.mailNetAddress = mailNetAddress;
}
String getMailStr(){
return this.mailID +"@"+this.mailNetAddress;
}
}
}
//另一个内部类继承外部类本身
class ChildLayer extends Layer{
void print(){
System.out.println(super.testStr);//访问父类的成员变量
}
}
//另个内部类继承内部类Person
class OfficePerson extends Person{
void show(){
System.out.println(name);
System.out.println(getEmail());
}
}
//外部类的测试方法
public void testFunction(){
//测试第一个内部类
ChildLayer childLayer = new ChildLayer();
childLayer.print();

//测试第二个内部类
OfficePerson officePerson = new OfficePerson();
officePerson.setName("abner chai");
//注意此处,必须用 对象.new 出来对象的子类对象
//而不是Person.new Email(...)
//也不是new Person.Email(...)
officePerson.setEmail(officePerson.new Email("josserchai","yahoo.com"));

officePerson.show();
}
public static void main(String[] args) {
Layer layer = new Layer();
layer.testFunction();
}
}
分享到:
评论

相关推荐

    Java 深入理解嵌套类和内部类

    Java 深入理解嵌套类和内部类,让你对知识点有个全面深入的理解

    深入理解Java嵌套类和内部类

    本篇文章主要介绍了深入理解Java嵌套类和内部类,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    详细分析内部类的发生内存泄漏的原因

    如果您已了解静态类和内部类,则应该熟悉使用Java代码中的嵌套类的基础知识。在这个相关的技巧中,我将带您了解嵌套类的陷阱之一,这是内部类在JVM中导致内存泄漏和内存不足错误的潜力。 之所以会发生这种类型的内存...

    freeMark if嵌套

    if的嵌套前段时间一直没有用过,用这个小例子看。能够很好理解 主要注意:()>这个括号

    (超赞)JAVA精华之--深入JAVA API

    1.2 深入理解嵌套类和内部类 1.2.1 什么是嵌套类及内部类? 1.2.2 静态嵌套类 1.2.3 在外部类中定义内部类 1.2.4 在方法中定义内部类 1.2.5 匿名内部类 1.2.6 内部类使用的其它的问题 1.3 文件和流 1.3.1 什么是数据...

    JAVA SE学习精华集锦

    1.2 深入理解嵌套类和内部类 47 1.2.1 什么是嵌套类及内部类? 47 1.2.2 静态嵌套类 48 1.2.3 在外部类中定义内部类 48 1.2.4 在方法中定义内部类 49 1.2.5 匿名内部类 49 1.2.6 内部类使用的其它的问题 50 1.3 文件...

    Java编程入门文档教程合集

    【】Java入门深入理解嵌套类和内部类【】Java和JSP编程的六个常见问题【】JAVA基础知识【】Java编程语言.(第三版)【】Java设计模式-图解-附代码【】第1章【】编程必备Eclipse快捷键资源截图: 资源太大,传百度...

    Java精华学习资料

    深入理解嵌套类和内部类 文件和流 java中的一些常用词汇 J2SE学习中的30个基本概念 Java线程 Java 5.0多线程编程 Java Socket编程 Java的内存泄漏 抽象类与接口的区别 Java变量类型间的相互转换 ……

    JAVA 7 程序设计.part2.rar

    然后深入解析了接口和抽象类、枚举、集合框架、泛型、输入输出、嵌套类和内部类等内容,掌握这部分内容有助于深入理解Java的底层原理;接着阐述Swing的基础和高级知识、多态、注解、国际化、Java网络、JDBC、Java...

    JAVA 7 程序设计.part1.rar

    然后深入解析了接口和抽象类、枚举、集合框架、泛型、输入输出、嵌套类和内部类等内容,掌握这部分内容有助于深入理解Java的底层原理;接着阐述Swing的基础和高级知识、多态、注解、国际化、Java网络、JDBC、Java...

    疯狂JAVA讲义

    学生提问:非静态内部类对象和外部类对象的关系是怎样的? 206 6.7.2 静态内部类 207 学生提问:为什么静态内部类实例方法也不能访问外部类的实例属性呢? 207 学生提问:接口里是否能定义内部接口? 208 6.7.3 ...

    深入理解变量作用域

    但是如果一个函数定义嵌套在另外一个函数中,那么嵌套的函数中有声明的变量就具有嵌套的局部作用域。当然我们知道全局变量是全局对象的属性,而局部变量是一个特殊的调用对象的属性,那么我们就可以再次关注一下变量...

    Java语言程序设计实验指导书

    3 对象和类 编写程序实现类和对象的操作,掌握构造函数与静态成员的使用。 4 继承与多态 编写程序实现类的继承、多态的实现。 5 抽象类、接口与内部类 编写程序实现类的继承、与接口的编写。 6 异常 编程实现处理...

    C++ Primer第四版【中文高清扫描版】.pdf

    14.9.4 重载确定和类的实参 461 14.9.5 重载、转换和操作符 464 小结 466 术语 467 第四部分 面向对象编程与泛型编程 第15章 面向对象编程 471 15.1 面向对象编程:概述 472 15.2 定义基类和派生类 473 15.2.1 定义...

    Python变量在函数中的作用域.md

    学习理解函数的嵌套和作用域的概念,掌握变量的可访问性规则; 阅读Python官方文档和相关教程,了解更深入的作用域相关内容; 参考优秀的Python代码库和项目,学习函数设计和变量作用域的实践经验; 积极参与Python...

    javaSE代码实例

    第6章 对象和类——Java世界的细胞 77 6.1 面向对象概述 77 6.1.1 面向对象程序设计思想的诞生 77 6.1.2 面向过程与面向对象思想的对比 78 6.1.3 面向对象技术的背景和特点 79 6.2 类的定义与对象的创建...

Global site tag (gtag.js) - Google Analytics