内部类(inner class),顾名思义,就是定义在一个类的内部。
内部类的特点:
1、内部类方法可以访问该类定义所在的作用域(外部类)中的数据,包括私有数据。
2、内部类可以对同一个包中的其他类隐藏起来(public类与默认修饰符的类在同一个包内都是可以被访问的)。
3、当想定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷(当然Java8中的lambda是个更好的选择)。
最简单的内部类实现:
/**
* Created by N3verL4nd on 2016/11/28.
*/
class Outer{
private int x = 100;
class Inner{
public void show(){
System.out.println(x);
}
}
public void show(){
Inner inner = new Inner();
inner.show();
}
}
public class HelloWorld {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
}
}
内部类的访问特点:
1、内部类可以直接访问外部类的成员。
2、外部类要访问内部类,必须建立内部类的对象。
内部类的一些特点:
1、内部类可以被成员修饰符所修饰(private, protected, public,static,默认修饰符),毕竟内部类在外部类成员函数的位置。其他类只能够被public与默认修饰符修饰。
2、普通的内部类不能有静态域和方法。
/**
* Created by N3verL4nd on 2016/11/28.
*/
class Outer{
private int x = 100;
private static int y = 200;
//内部类可以被任意成员修饰符(private,protected,public,默认修饰符)修饰
public class Inner{
public void show(){
System.out.println("Inner::show..." + x);
}
}
public static class StaticInner{
//如果内部类定义了静态成员,该内部类也必须是静态的。
public void print(){
System.out.println("StaticInner::print..." + y);
}
public static void show(){
System.out.println("StaticInner::show..." + y);
}
}
public void show(){
Inner inner = new Inner();
inner.show();
}
}
public class HelloWorld {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
//直接访问外部类中的内部类的成员
Outer.Inner inner = new Outer().new Inner();
inner.show();
//如果内部类是静态的,相当于一个外部类
Outer.StaticInner staticInner = new Outer.StaticInner();
staticInner.print();
Outer.StaticInner.show();
}
}
当内部类不需要引用外部类的对象时,可以将内部类声明为静态内部类,以便取消产生的引用外部类的引用(外部类.this)。
举例:
/**
* Created by N3verL4nd on 2016/11/28.
*/
class MinMax{
public static class Pair<T>{
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
}
public static Pair getMinMax(int... arr){
if (arr == null || arr.length == 0)
return null;
int first = arr[0];
int second = arr[0];
for (int x : arr){
if (x < first)
first = x;
if (x > second)
second = x;
}
return new Pair(first, second);
}
}
public class HelloWorld
{
public static void main(String[] args) {
int[] arr = {2, 5, 1, 3, 4};
MinMax.Pair pair = MinMax.getMinMax(arr);
System.out.println(pair.getFirst() + " " + pair.getSecond());
}
}
/**
* Created by N3verL4nd on 2016/11/28.
*/
class Outer{
private int num = 3;
class Inner{
private int num = 4;
public void show1(){
int num = 5;
System.out.println(num);
}
public void show2(){
System.out.println(this.num);
}
public void show3(){
System.out.println(Outer.this.num);
}
}
}
public class HelloWorld {
public static void main(String[] args) {
new Outer().new Inner().show1();
new Outer().new Inner().show2();
new Outer().new Inner().show3();
}
}
因为内部类持有外部类的引用,所以内部类能够直接访问外部类的成员。
局部内部类:
局部内部类不能被public/private等修饰符修饰,它的作用于被限定在声明这个局部类的块中。
除method方法之外,没有任何方法知道Inner类的存在。
局部内部类不仅可以访问外部类的数据,还可以访问局部变量,但是必须用final修饰。
/**
* Created by N3verL4nd on 2016/11/28.
*/
class Outer{
void method(){
//内部类在局部位置上只能访问局部中被final修饰的局部变量。
final int x = 100;
class Inner{
void show(){
System.out.println(x);
}
}
Inner inner = new Inner();
inner.show();
}
}
public class HelloWorld {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
匿名内部类: