JAVA内部类概念简介
概览
将用一些例子来阐述各种类型内部类的使用场景以及优势(与top-level-classes enclose-class相比)
概念
分类
内部类即classes within classes.在Java中有两种类型的类,即top-level-classes(classed defined directly within a package)和nested classes(classes defined within top-level-classes).
优点
1. help grouping the related functionlity together. 如果A类仅仅被B类使用,很明显,A类是不必要声明为top-level-classes的,此时A类作为内部类的好处是:减少混乱、增加可读性。(reduce clutter and increase readability)
2. nested classes is able to access all the class members of their enclosing top-level-class(including the private members and variables).这比传统使用实例来访问非private变量和方法有效得多(如例子一);在事件驱动的程序中,这个优势更加明显。
3. 内部类与子类的区别,或者说内部类的优势之一是内部类可以访问顶层类的私有成员,而子类不行,除非父类成员用protected声明。
例子一
//使用实例来访问非私有成员或函数
public class A{
public Integer a;
public void print(){
System.out.println("Foobar");
}
}
public class Main{
public static void main(String[] args){
System.out.println(new A().a);
new A().print();
}
}
嵌套类的类型与基本栗子
不同嵌套类之间有一些细微差别。
non-static nested classes
作为top-level-classes: 不能访问内部类的成员.
作为nested classes: 可以直接访问顶层类的所有成员(包括私有成员)。
嵌套类所处位置:可以是任意块。只是在块内不能有修饰词:private/public/protected
public class Outer {
private class Inner1{ }
public class Inner2{}
protected class Inner3{}
class Inner4{}
//普通块
{
class Inner5{ }
}
//静态块
static{
class Inner6{ }
}
//方法内部
public void method1(){
class Inner7{}
}
}
inner Classes
这是使用最广泛的一种。唯一限制的条件是:内部类中不能有static声明
public class OuterClass {
private int private_member_variable = 100;
// show如何定义内部类
public class InnerClass {
public void printPrivateVariable() {
//访问顶层类的内部成员很便利
System.out.println(private_member_variable);
}
}
//【在顶层类内部】如何获取内部类的实例
public void callInnerClassMethod() {
InnerClass innerClass = new InnerClass();
innerClass.printPrivateVariable();
}
public static void main(String args[]) {
OuterClass outerClass = new OuterClass();
outerClass.callInnerClassMethod();
}
}
在顶层类外部如何获取内部类的实例?
public class TestClass {
public static void main(String args[]) {
OuterClass outerClass = new OuterClass();
//注意语法
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.printPrivateVariable();
}
}
匿名内部类:Anonymous Classes
匿名内部类和普通内部类的唯一区别是匿名,即没有名字
public class code3 {
public static void main(String[] args) {
/**public Thread(Runnable target),
new Runnable(){xxx}就是一个匿名内部类*/
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println("i'm anonymous classes");
}
});
thread.start();
}
}
使用时机: when an object instance are required on the fly (fly感觉是享元模式,轻量型的意思)
以何种方式: 继承类,或者实现类
语法
1. new Interface to implement . 如上个例子。
2. abstract/concrete class to extend () {body of the anonymous class to be defined};
static nested classes
静态嵌套类与顶层类是隔绝的,即与非静态内部类相反,静态嵌套类不能【直接访问】顶层类的成员。原因是静态成员,静态类成员仅能直接访问静态成员。可以通过顶层类的object instance访问顶层类的成员。
public class OuterClass {
private int private_member_variable = 100;
//静态嵌套类的定义
public static class StaticInnerClass {
public void printPrivateVariables() {
OuterClass outerClass = new OuterClass();
//访问顶层类的成员是通过顶层类的object instance
System.out.println(outerClass.private_member_variable);
}
}
public static void main(String args[]) {
//静态嵌套类和一般的顶层类是一样的
StaticInnerClass staticInnerClass = new StaticInnerClass();
staticInnerClass.printPrivateVariables();
}
}
顶层类外部是如何实例化静态嵌套类的
public class Test {
public static void main(String args[]) {
OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
staticInnerClass.printPrivateVariables();
}
}
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
shadowing 遮蔽
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
output
x = 23
this.x = 1
ShadowTest.this.x = 0
解释:
1. The variable x defined as a parameter of the method methodInFirstLevel
shadows the variable of the inner class FirstLevel
嵌套类、内部类、内置类都是同一种意思,栗子如下
class OuterClass {
...
class NestedClass {
...
}
}
补充内容
内部类有4种风味:
1. static nested classes
2. inner classes
3. method local inner classes
4. anonymous inner classe可进一步划分为两大类
1. static: Nested classes that are declared static are called static nested classes.
2. non-static : Non-static nested classes are called inner classes.
上述2、3、4就是非静态的内部类。
优点:
1. 更能体现Java语言的封装特性。设top-class为b,a为其内部类。a可以访问b的成员(函数,变量),a声明为private,可以对外隐藏自己。
2. more readable and maintainable。把被使用到的代码(内部类)放置在离调用方更近的地方。
3. 当只在一处使用某些代码,使用内部类对组织类有好处(包组织更合理化)。
4. 更能体现Java语言的面向对象特性.
参考
【1】http://www.javaworld.com/article/2075984/java-language/introduction-to-nested-classes-in-java.html
【2】https://www.tutorialspoint.com/java/java_innerclasses.htm
【3】https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/innerclasses/spec/innerclasses.doc.html
【4】http://www.javaworld.com/article/2077411/core-java/inner-classes.html
【5】https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html