<div class="iteye-blog-content-contain" style="font-size: 14px">
首先什么是内部类(Oracle网站上称之为Nested class.)?
所谓Java内部类即在另一个类的内部定义的类(declared within another class), 内部类分为静态内部类(static nested class )和非静态内部类(non-static nested class)。很容易理解不须代码示例。
静态内部类:行为上静态内部类等同于外部类(another top-level class),因此static nested class不能直接访问outer class 实例的变量和方法,但可以访问 outer class 的静态变量和方法。此外static nested class可以直接通过outer class 的类名访问,如:OuterClass.StaticNestedClass. 代码示例
public class StaticNestedClassExample {
/*
* an instance variable
*/
private String outerString;
/*
* a class variable
*/
private static String outerStaicString;
/*
* an instance method
*/
public String outerMethod() {
return "";
}
/*
* a class method
*/
public static String outerStaticMethod() {
return "";
}
/*
* static nested class
*/
public static class StaticNestedClass {
private String innerString;
private static String innerStaticString;
public void innerMethod() {
this.innerString = outerString;// Compiling error. can not refer directly to outer class instance variables
// and methods
outerMethod();// Compiling error. can not refer directly to outer class instance variables and methods
this.innerString = outerStaicString;// OK
outerStaticMethod();// OK
StaticNestedClass outerClass = new StaticNestedClass();
outerClass.outerMethod();// outerMethod can be accessed by an OuterClass instance.
innerStaticString = outerClass.outerString;// outerString can be accessed by an OuterClass instance.
}
public static void innerStaticMethod() {
innerStaticString = outString; // Compiling error.
innerStaticString = outerStaicString;// OK
outerMethod();// Compiling error.
outerStaticMethod();// OK
StaticNestedClass outerClass = new StaticNestedClass();
outerClass.outerMethod();// outerMethod can be accessed by an OuterClass instance.
innerStaticString = outerClass.outerString;// outerString can be accessed by an OuterClass instance.
}
}
public static void main(String... args) {
StaticNestedClass nestObject2 = new StaticNestedClass();
StaticNestedClass nestObject1 = new StaticNestedClassExample.StaticNestedClass();
}
}
接下来描述一下对非静态内部类non-static nested class的理解,常用的non-static nested class,我把它分为三种:General,Local,Asynomous.
General的内部类也就是在top-level 的类中定义另一个类,类似与成员变量。
Local 的内部类通常是在top-level 的方法中定义一个类,当然这个类是有名字的,而且不能用public来修饰。
而Aysnomous内部类与Local唯一不同的就是没有名字,匿名类常用于实现接口。
看代码:
package nested.classes.inner;
import java.util.List;
public class InnerClassExample {
public class GneralInnerClass { // General
}
public void outerMethod() {
class LocalInnerClass { // Local
}
}
public void outerMethod2() {// Anonymous
new Runnable() {
@Override
public void run() {
}
};
}
}
以上是理解内部类定义以及相关概念的描述。
接下来,我们为什么要用内部类呢?
为什么使用内部类呢,个人还真不能说个一青二白,如果真要说,我认为主要是用来对类的封装使用以及逻辑上的组装,另外就是可以让代码易读易维护,还有在优快云 看到说使用内部类可以实现所谓的多继承http://blog.youkuaiyun.com/yu422560654/article/details/7466260,也就是说outer class已经继承了一个类如果想在这个outer class A中继承或使用另一个outer class B 的方法,可以在这个outer class A里面实现一个内部类来继承outer class B。举几个之所以使用内部类原因的例子来帮助理解吧:
/
*
* Why use nested classes?
* There are several compelling reasons for using nested classes,among them:
*
* 1. It is a way of logically grouping classes that only used in one place;
* If a class is useful to only one other class, then it is logical to embed * it in that class and keep the two together. Nesting such "helper classes"
* makes their package more streamlined.
*/
public class LogicalGrouping {
public static void validatePhoneNumber(String number) {
class PhoneNumber {
private String formattedPhoneNumber = null;
static final int standardLength = 11;
final static String regularExpression = "[^0-9]";
PhoneNumber(String number) {
String currentNumber = number.replaceAll(regularExpression, "");
if (currentNumber.length() == standardLength) {
formattedPhoneNumber = currentNumber;
} else {
formattedPhoneNumber = null;
}
}
public String getNumber() {
return formattedPhoneNumber;
}
}
if (null == new PhoneNumber(number).getNumber()) {
System.out.println("Invalid Number");
} else {
System.out.println("OK.");
}
}
public static void main(String[] args) {
validatePhoneNumber("1810-1109-123");
}
}
在这个例子中,假设有个一个utility class 其中有个校验手机号的方法,而且这个类中的PhoneNumber 类只对这个utility class 有用,所以我们就用内部类的形式把这个校验逻辑写在一起,可以这样理解吧?再来一段代码:
/**
* Why use nested classes? There are several compelling reasons for using * nested classes,among them:
*
* 2.Increased encapsulation
*
* Consider two top-level classes, A and B, where B needs access to members of * A that would otherwise be declared
* private. By hiding class B within class A, A's members can be declared * private and B can access them. In addition, B
* itself can be hidden from the outside world.
*/
public class CorruptOfficial {//贪官
private String privateCoffer;//小金库
private class Concubine {//情妇
Concubine() {
System.out.println(privateCoffer);
}
}
}
这个例子可以说很形象,一个类A要访问另一类B的成员变量b,但是B的成员变量是不能让其他类访问的,所以只能声明为private,但是A需要访问,怎么办呢?把A声明称B的内部类。这样可以把类A隐藏起来。
例子中,贪官的小金库是不允许任何人访问的,但是贪官的小三可以,这种情况下只能把小三声明为贪官的内部类了,而且可以把小三隐藏的很好,不为公众所知!!
关于使用内部类可以让代码易读以维护的例子就偷懒不写了。
Others
1 静态内部类不能直接访问外部类的非静态成员变量或者方法,但是可以访问外部类的静态变量和方法
2.非静态内部类不能声明静态的成员变量和方法,除了常量表达式。例如:
public class CorruptOfficial {
private String privateCoffer;
private class Concubine {
static private String fighting;//compile error;
final static private String finalFighting = "Fighting";//OK
static void serve(){} //Compile error
Concubine() {
System.out.println(privateCoffer);
}
}
}
3.如果需要访问外部类的实例成员变量和方法则将内部类声明为non-static,不需要则可以声明为static
其实在工作中,内部类很少使用,至少我很少使用,只是稍微弄懂一下。
</div>