内部类分为:成员内部类,局部内部类,匿名内部类和静态内部类。
成员内部类
- 成员内部类可以访问外围类的所有的成员属性和方法。
- 成员内部类中不能存在任何static的变量和方法。
- 成员内部类是依附于外围类的,所以只有先创建了外围类才能创建内部类。
- 内部类对象有一个隐式引用,该引用指向了创建它的外部类对象。该外围类引用由编译器在构造器中设置。
public class Outer {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//成员内部类
class InnerClass{
public InnerClass(){
name="Hello";
age=10;
}
}
public static void main(String[] args) {
Outer outer = new Outer();
//Outer.InnerClass innerClass=outer.new InnerClass(); //ok
InnerClass innerClass=outer.new InnerClass();
System.out.println(outer.name+" "+outer.age);
}
}
输出结果:
Hello 10
- 在
main
方法中,不能通过InnerClass innerClass=new InnerClass();
建立内部类的对象。因为main方法是static
方法,在static
方法中没有默认this
引用。这种情况下需要先建立内部类对象,设为outer
,然后通过InnerClass innerClass=outer.new InnerClass();
- 在内部类的方法(非static)内则直接可以通过
InnerClass innerClass=new InnerClass();
建立内部类对象。上边的语句等价于InnerClass innerClass=this.new InnerClass();
局部内部类
- 局部内部类定义在方法或作用域内,出了该方法或者域就会失效。
- 《Java核心技术 I》局部内部类不仅可以访问包含它们的外部类,还可以访问局部变量。不过那些局部变量必须被声明为
final
。但是我在Java1.8.0中,没有加final
也能访问局部变量,此处存疑。
定义在方法内的内部类
public class Outer {
private String name;
private int age;
public void display(){
//定义在方法中的内部类
class InnerClass{
public InnerClass(){
name="Hello";
age=10;
}
public void display(){
System.out.println(name+" "+age);
}
}
InnerClass innerClass=new InnerClass();
innerClass.display();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.display();
}
}
输出结果:
Hello 10
定义在作用域内的内部类,
public class Outer {
private String name;
private int age;
public void display(boolean b){
if(b){
//定义在域中的内部类,出了if语句即访问不到该内部类
class InnerClass{
public InnerClass(){
name="Hello";
age=10;
}
public void display(){
System.out.println(name+" "+age);
}
}
InnerClass innerClass=new InnerClass();
innerClass.display();
}else{
//访问不到InnerClass
}
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.display(true);
}
}
输出结果
Hello 10
访问局部变量
public class Outer {
private String name;
private int age;
public void display( int b){
//访问局部变量,没有加局部变量,也能访问
class InnerClass{
public InnerClass(){
name="Hello";
age=10;
}
public void display(){
if(b==1)
System.out.println(name + " " + age);
}
}
InnerClass innerClass=new InnerClass();
innerClass.display();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.display(1);
}
}
输出结果:
Hello 10
匿名内部类
- 创建匿名内部类的语法格式:
new SuperType(construction parameters){
inner class methods and data
}
- 由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。取而代之的是,将构造器参数传递给超类构造器。尤其在内部类实现接口的时候,不能有任何构造参数,同时还必须提供
()
。 - 当new匿名内部类时,这个接口或者类必须是首先存在的。
public class Outer {
private String name="Hello";
private int age=10;
//外围类方法
public Display getDisPlay( ){
//相当于返回一个实现Display接口的子类
return new Display(){
public void display(){
System.out.println(name+" "+age);
}
};
}
//定义接口
interface Display{
void display();
}
public static void main(String[] args) {
Outer outer = new Outer();
Display d=outer.getDisPlay();
d.display();
}
}
输出结果:
Hello 10
静态内部类
- 使用内部类是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象(访问外围类对象)。这样,便产生类静态内部类。
- 静态内部类的创建不依赖于外围类。
- 静态内部类不能使用任何外围类的非static成员变量和方法。
public class Outer {
private int b=20;
private int a=10;
public Pair compare(){
if (a>b)
return new Pair(b,a);
else
return new Pair(a,b);
}
//静态内部类
static class Pair{
private int min;
private int max;
public Pair(int min,int max){
this.min=min;
this.max=max;
}
public int getMin() {
return min;
}
public int getMax() {
return max;
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Pair pair=outer.compare();
System.out.println(pair.getMin()+" "+pair.getMax());
}
}
输出结果
10 20
如有错误,欢迎留言指正!