原版出处:百度传课《JavaSE轻松入门基础教程》 讲师:李伟
----概述:
一个类被嵌套定义在另一个类中,那么这个类就被称之为内部类,包含内部类的类就被称之为外部类。
----如何使用内部类:
1:
public class InnerTest{
public static void main(String[] args){
Outer out = new Outer; //现在外部类中定义一个调用内部类的方法,在通过此方法去访问内部类。
out.useInner();
}
}
public class Outer{
private String out_string="这是外部类的一个私有属性";
public void useInner(){
Inner in = new Inner();
in.print();
}
//创建内部类
class Inner{
public void print(){
System.out.println(out_string); //内部类是可以访问外部类的私有属性的,因为私有的是本类可见。
}
}
}
2:
public class InnerTest{
public static void main(String[] args){
Outer out = new Outer;
Outer.Inner in = out.new Inner();
in.print(); //直接调用内部类
}
}
注:
1:两种方法都必须先把外部类 new 一个出来。
2:内部类相当于外部类的成员变量或方法。
----匿名内部类
概念:就是没有名字的内部类
定义:
public class TestInner{
public static void main(String[] args){
OuterI outer = new OuterI(){ //利用内部类去实现接口
public void show(){
System,out,println("这是匿名内部类的show");
}
}; //注:此处有分号!因为此处定义了一个匿名内部类。
outer.show();
}
interface OuterI{ //定义了一个接口
public void show();
}
}
----局部内部类
概念:
在类的局部位置(即方法)的进行定义的类叫做局部内部类。
特点:
1:在局部内部类里面可以访问外部类的所有成员变量。
2:局部内部类访问方法中的局部变量的时候,该局部变量必须声明为final类型。
拓展:为什么局部变量必须是final类型?
因为局部变量是随着方法而存在的,一旦方法被调用,则局部变量被启用,一旦方法调用结束,则局部变量被废弃。但是局部内部类的生命周期要比方法长(下例中:方法调用结束后,
oi还指向内部类,所以内部类还存在),方法调用结束时,局部内部类还存在,所以必须将局部变量声明为final类型(即变成常量)。
实例:
public class TestInner{
public static void main(String[] args){
Outer o = new Outer();
OutI oi = o.eat(1); //oi指向了局部内部类
}
}
public Outer{
private String name;
public OutI eat(final int i){ //返回值类型为OutI,Inner是OutI的实现,所以返回的new Inner(),就是OutI类型。
final int count = 0;
class Inner implements OutI{
public void innerEat(){
System.out.println(name);
System.out.println(i); //参数会被赋值,所以不需要进行初始化。
System.out.println(count); //需要被初始化
}
}
return new Inner(); //返回了一个OutI类型
}
}
interface OutI{} //定义了一个接口
----静态内部类
概念:使用static修饰的内部类,称之为静态内部类。
特点:
1:在内部类前添加static修饰符。
2:静态内部类中可以声明static成员变量,非静态内部类中不可以。//因为静态内部类中的静态变量一旦被创建,那么它就存在了,而非静态内部类此时还没有存在。
3:静态内部类不可以使用外部类的非静态成员变量。//因为静态变量和非静态变量的生命周期是不一样的。
4:创建静态内部类的对象,不需要其外部类的对象。
形式:
1:创建非静态内部类的形式:
Outer o = new Outer();
Outer.Inner i = o.new Inner(); //使用了外部类的对象,对象被创建,表示外部类就被创建,外部类被创建后,才能被内部类访问。(外部类都没被创建,你内部类去访问个什么?)
2:创建静态内部类的形式:
Outer.Inner i = new Outer.Inner();
注:
1:内部类和外部类是同级的,在编译时内部类也会生成独立的class文件。
2:在内部类里面有对外部类的一个引用。
----引用外部类的对象
public class Outer{
private int count = 1;
class Inner{
private int count = 2;
public void print(int count){
System.out.println(count); //显示的是3 此处的count有个就近原则,先找本方法内的,在找内部类内的,最后再找外部类内的。(这是变量同名的情况下)
System.out.println(this.count); //显示的是2
System.out.println(Outer.this.count); //显示的是1
}
}
public static void main(String[] args){
Outer outer = new Outer();
Outer.Inner i = outer.new Inner();
i.print(3);
}
}
总结:
调用方法里的:count
调用内部类里的:this.count
调用外部类里的:Outer.this.count
----内部类的继承
public class Test extends A.B{ //A.B表示继承的是A类中的B类。
public Test(A a){ //相当于int i
a.super(); //调用A的构造方法,使外部类A实例化。
}
}
class A{
classB{
}
}
详解:若Test要继承内部类B,那么使用Test的时候,内部类B将被实例化,而此时外部类A还未被实例化,所以需要先把外部类A实例化。
----概述:
一个类被嵌套定义在另一个类中,那么这个类就被称之为内部类,包含内部类的类就被称之为外部类。
----如何使用内部类:
1:
public class InnerTest{
public static void main(String[] args){
Outer out = new Outer; //现在外部类中定义一个调用内部类的方法,在通过此方法去访问内部类。
out.useInner();
}
}
public class Outer{
private String out_string="这是外部类的一个私有属性";
public void useInner(){
Inner in = new Inner();
in.print();
}
//创建内部类
class Inner{
public void print(){
System.out.println(out_string); //内部类是可以访问外部类的私有属性的,因为私有的是本类可见。
}
}
}
2:
public class InnerTest{
public static void main(String[] args){
Outer out = new Outer;
Outer.Inner in = out.new Inner();
in.print(); //直接调用内部类
}
}
注:
1:两种方法都必须先把外部类 new 一个出来。
2:内部类相当于外部类的成员变量或方法。
----匿名内部类
概念:就是没有名字的内部类
定义:
public class TestInner{
public static void main(String[] args){
OuterI outer = new OuterI(){ //利用内部类去实现接口
public void show(){
System,out,println("这是匿名内部类的show");
}
}; //注:此处有分号!因为此处定义了一个匿名内部类。
outer.show();
}
interface OuterI{ //定义了一个接口
public void show();
}
}
----局部内部类
概念:
在类的局部位置(即方法)的进行定义的类叫做局部内部类。
特点:
1:在局部内部类里面可以访问外部类的所有成员变量。
2:局部内部类访问方法中的局部变量的时候,该局部变量必须声明为final类型。
拓展:为什么局部变量必须是final类型?
因为局部变量是随着方法而存在的,一旦方法被调用,则局部变量被启用,一旦方法调用结束,则局部变量被废弃。但是局部内部类的生命周期要比方法长(下例中:方法调用结束后,
oi还指向内部类,所以内部类还存在),方法调用结束时,局部内部类还存在,所以必须将局部变量声明为final类型(即变成常量)。
实例:
public class TestInner{
public static void main(String[] args){
Outer o = new Outer();
OutI oi = o.eat(1); //oi指向了局部内部类
}
}
public Outer{
private String name;
public OutI eat(final int i){ //返回值类型为OutI,Inner是OutI的实现,所以返回的new Inner(),就是OutI类型。
final int count = 0;
class Inner implements OutI{
public void innerEat(){
System.out.println(name);
System.out.println(i); //参数会被赋值,所以不需要进行初始化。
System.out.println(count); //需要被初始化
}
}
return new Inner(); //返回了一个OutI类型
}
}
interface OutI{} //定义了一个接口
----静态内部类
概念:使用static修饰的内部类,称之为静态内部类。
特点:
1:在内部类前添加static修饰符。
2:静态内部类中可以声明static成员变量,非静态内部类中不可以。//因为静态内部类中的静态变量一旦被创建,那么它就存在了,而非静态内部类此时还没有存在。
3:静态内部类不可以使用外部类的非静态成员变量。//因为静态变量和非静态变量的生命周期是不一样的。
4:创建静态内部类的对象,不需要其外部类的对象。
形式:
1:创建非静态内部类的形式:
Outer o = new Outer();
Outer.Inner i = o.new Inner(); //使用了外部类的对象,对象被创建,表示外部类就被创建,外部类被创建后,才能被内部类访问。(外部类都没被创建,你内部类去访问个什么?)
2:创建静态内部类的形式:
Outer.Inner i = new Outer.Inner();
注:
1:内部类和外部类是同级的,在编译时内部类也会生成独立的class文件。
2:在内部类里面有对外部类的一个引用。
----引用外部类的对象
public class Outer{
private int count = 1;
class Inner{
private int count = 2;
public void print(int count){
System.out.println(count); //显示的是3 此处的count有个就近原则,先找本方法内的,在找内部类内的,最后再找外部类内的。(这是变量同名的情况下)
System.out.println(this.count); //显示的是2
System.out.println(Outer.this.count); //显示的是1
}
}
public static void main(String[] args){
Outer outer = new Outer();
Outer.Inner i = outer.new Inner();
i.print(3);
}
}
总结:
调用方法里的:count
调用内部类里的:this.count
调用外部类里的:Outer.this.count
----内部类的继承
public class Test extends A.B{ //A.B表示继承的是A类中的B类。
public Test(A a){ //相当于int i
a.super(); //调用A的构造方法,使外部类A实例化。
}
}
class A{
classB{
}
}
详解:若Test要继承内部类B,那么使用Test的时候,内部类B将被实例化,而此时外部类A还未被实例化,所以需要先把外部类A实例化。