将一个类定义在另一个类的里面,里面那个类就称为内部类(内部类也称为嵌套类或者内置类)。内部类分为成员内部类和方法内部类。对于内部类,具有以下的特点:
外部类名.this
】。外部类名.内部类名 内部类实例名 = new 外部类名().new 内部类名()
当内部类在外部类的成员位置的时候可以被成员修饰符修饰:
外部类名.内部类名 内部类实例名 = new 外部类名.内部类名()
直接创建内部类的实例(不需要先创建外部类的实例了);如果要访问内部类的静态成员就可以这样:Outter.Inner.静态方法或者变量
访问内部类
class Outer{ // 定义外部类
private String info = "hello world" ; // 定义外部类的私有属性
class Inner{ // 定义内部类
public void print(){ // 定义内部类的方法
System.out.println(info) ; // 直接访问外部类的私有属性
}
}
// 定义外部类的方法
public void fun(){
new Inner().print() ; //通过内部类的实例化对象调用内部类的方法
}
}
public class InnerClassDemo{
public static void main(String args[]){
new Outer().fun() ; // 调用外部类的fun()方法调用内部类的方法
Outer.Inner inner = new Outer().new Inner();
inner.print(); // 直接实例化内部类。格式:外部类.内部类 内部类实例 = new 外部类().new 内部类()
}
}
内部类能够访问外部类的原理(内部类持有外部类的引用外部类名.this
)
class Outer{
private String info = "外部类的info" ;
class Inner{
String info = "内部类中的info";
public void print(){
String info = "内部类的print方法中的info";
System.out.println(info) ; // print方法中的info
System.out.println(this.info); // Inner中的info,this.info和Inner.this.info等效
System.out.println(Outer.this.info);// Outer中的info
}
}
// 定义外部类的方法
public void fun(){
new Inner().print() ; //通过内部类的实例化对象调用内部类的方法
}
}
public class InnerClassDemo{
public static void main(String args[]){
new Outer().fun() ; // 调用外部类的fun()方法调用内部类的方法
}
}
静态内部类的一些性质
class Outer{
private static String info = "外部类的info" ;
static class Inner{
/**
* 静态内部类的非静态方法
*/
public void print(){
System.out.println(info) ; // print方法中的info
}
/**
* 静态内部类的静态方法
*/
public static void fun(){
System.out.println(info);
}
}
// 定义外部类的方法
public void fun(){
new Inner().print() ; //通过内部类的实例化对象调用内部类的方法
}
}
public class InnerClassDemo{
public static void main(String args[]){
Outer.Inner inner = new Outer.Inner(); // 访问静态内部类的非静态成员
inner.print();
Outer.Inner.fun(); // 访问静态内部类的静态成员
}
}
方法内部类
/**
* 方法内部类
*/
class Outer{
private static String info = "外部类的info" ;
public void fun(){
class Inner{ // 方法内部类,处于局部,不能被成员修饰符修饰(静态、私有)
public void print(){
System.out.println(info);
}
}
new Inner().print();
}
}
public class InnerClassDemo{
public static void main(String args[]){
new Outer().fun();
}
}
方法内部类访问局部变量,局部变量应该是final类型
/**
* 方法内部类
*/
class Outer{
private static String info = "外部类的info" ;
public void fun(final int num){ // 局部变量被final修饰之后才可以被局部内部类访问
final String msg = "局部中的msg"; // 局部变量被final修饰之后才可以被局部内部类访问
class Inner{
public void print(){
System.out.println(msg);
System.out.println(num);
}
}
new Inner().print();
}
}
public class InnerClassDemo{
public static void main(String args[]){
Outer outer = new Outer();
outer.fun(1); // 局部变量的生存期在栈中,方法运行完之后值就消失
outer.fun(2);
}
}
匿名内部类是内部类的简写格式。匿名内部类必须继承自一个类或者实现某个接口,匿名内部类实际上是匿名子类对象。匿名内部类中的方法一般不会超过3个。
abstract class Abs{
public abstract void show();
}
/**
* 匿名内部类
*/
class Outer{
private String info = "外部类的info" ;
public void fun(){
new Abs() {
@Override
public void show() {
System.out.println("show方法执行!" + info);
}
}.show(); // Abs的子类对象(因为只有子类才可以覆写抽象方法),调用show方法
}
}
public class InnerClassDemo{
public static void main(String args[]){
Outer outer = new Outer();
outer.fun();
}
}
匿名内部类的局限:一次只能调用一次自己的方法。多态的情况下无法向下转型。
abstract class Abs{
public abstract void show();
}
/**
* 匿名内部类
*/
class Outer{
private String info = "外部类的info" ;
public void fun(){
new Abs() {
@Override
public void show() {
System.out.println("show方法执行!" + info);
}
}.show(); // Abs的子类对象(因为只有子类才可以覆写抽象方法),调用show方法
new Abs() {
@Override
public void show() {
System.out.println("show方法执行!" + info);
}
public void hello(){
System.out.println("匿名子类自己的hello方法," + info);
}
}.hello(); // 匿名内部类一次只能调用自己的一个方法,不能既调用show又调用hello
}
}
public class InnerClassDemo{
public static void main(String args[]){
Outer outer = new Outer();
outer.fun();
}
}
因为任何类都是继承自Object类,所以我们可以不实现接口或者显式继承类来创建匿名内部类。
public class InnerClassDemo{
public static void main(String args[]){
new Object(){
void myfun(){
System.out.println("myfun"); // Object的子类对象
}
}.myfun();
}
}