Java内部类(语法层)
一 内部类主要概念:
java内部类是java程序设计语言中比较难以理解的概念.何为内部类,简单来讲就是定义在当前类也可以称为外部类的内部.说的通俗点,就是java允许在一个类的花括号{}之中在定义一个类如下图示:
package com.javase.nostatic;
public class Test {
class In{
}
}
在语法层面上对于java内部类的理解可以从二个角度出发.第一,对于外部类而言内部类本身就是外部类的一个成员和其他的成员,元素是一样的.第二对于内部类本身而言内部类又是一个有自己类文件的类.这点可以通过编译内部类发现,内部类编译后的class字节码文件名总是以外部类名加上$加上内部类名这样的格式命名例如:Outclass$InClass.class这样.
二 内部类的分类及使用说明:
按照作用域的不同内部类可以分为成员内部类与局部内部类俩种.
成员内部类又可以细分为静态成员内部类与非静态成员内部类.
局部内部类有可以细分为匿名内部类和非匿名内部类
1): 非静态成员内部类:
非静态成员内部类与外部类的定义方式一致,同样的它和外部类的其他非静态成员一样,都需要有一个外部类的实例对象.这点和内部类的创建以及使用密切相关.我们在外部类本身使用内部类时直接创建对象即可,但是在外部类范围之外,就需要首先创建外部对象才可以在创建非静态内部类对象.这是为什么呢?这和java的语法规定和内存管理息息相关..而简单的来说非静态成员内部类的对象需要引用一个外部类对象这也是内部类的一个作用,内部类可以使用封装性的方式来使用外部类的方法及外部类的实例变量..所以这也要决定了创建一个内部类对象的时候,堆中必须已经有一个外部类对象了.那么为什么在外部类本身可以不创建外部对象就直接创建内部类对象呢?原因是java 虚拟机在调用一个实例方法的时候,会默认传入一个隐示参数.这个参数就是调用方法的对象本身.这也是java为什么需要调用方法前必须要创建对象.所以在外部类的方法中当前外部类对象已经存在了自然可以直接创建内部类.
package com.javase.nostatic;
/**
* 外部类内部类示例一
*
* @author wsp
*/
public class Goods {
/**外部类的实例成员变量*/
private int num = 10;
/**
* 一个具有private访问权限的实例成员内部类实现了Contents接口
* @author wsp
*/
public class Content implements Contents {
/**内部类的实例成员变量*/
private int i = 11;
private int num = 2;
@Override
public int value() {
return i*Goods.this.num;
}
}
/**
* 一个具有protected访问权限的实例成员内部类实现了Destiantion接口
* @author wsp
*/
class GDestiantion implements Destiantion{
/**内部类的实例成员变量*/
private String label;
/**私有的构造器*/
public GDestiantion(String lable){
this.label = lable;
}
@Override
public String readLabel() {
// TODO Auto-generated method stub
return label;
}
}
/**
* 返回内部类实例
* @param s
* @return
*/
public Destiantion dest(String s){
return new GDestiantion(s);
}
/**
* 返回内部类实例
* @param s
* @return
*/
public Contents cont(){
return new Content();
}
}
/**
* 使用外部类提供的方法创建内部类
*/
public void test1(){
Goods goods = new Goods();
Contents cont = goods.cont();
Destiantion dt = goods.dest("hello 内部类");
System.out.println(cont.value());
System.out.println(dt.readLabel());
}
/**
* 在外部类范围之外使用自己的内部类
*/
@Test
public void test2(){
//创建内部类对象之前必须存在外部类对象
Goods goods = new Goods();
//通过外部类对象调用内部类的构造器创建内部类对象
Goods.Content ct = goods.new Content();
System.out.println(ct.value());
}
还有内部类有一个特征就是它也遵从就近原则.什么意思呢?比如说外部类有一个实例成员变量为num,内部类也有一个实例成员变量num.那么在内部类中它肯定会优先使用内部类的num.那如何使用外部类的num呢?可以通过外部类.this.num来使用.非静态内部类中不能存在静态成员..
2): 静态成员内部类:
静态成员内部类就没有非静态成员内部类那么复杂了,首先静态成员内部类本身就属于外部类的一个静态成员,所以它不需要有当前外部类对象的实例引用可以自由的创建对象,同时它的内部可以有静态成员和非静态成员这点和外部类一致..但是遵从Java的语法规则.静态内部类不能使用外部类的实例成员只可以使用静态成员.
public class TestOut {
static class A{
private int num;
private static String names;
public A(){
}
public void say(){
test1();
}
}
public static void test1(){
A a = new A();
}
}
}
}