内部类

1.什么是内部类,为什么要用内部类?

  如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。

例如:身体和心脏的关系。汽车和发动机的关系。

  可以将一个类定义在另一个类的定义内部,这就是内部类。

  当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容。

如:

class Body{
         private class XinZang{//将这个内部类封装起来,对外界提供访问方式
                   void move(){}
             };
}

public void show(){
         new XinZang().move();//调用其功能方法
}

2.内部类的分类

(1)成员内部类

(2)局部内部类(包含匿名内部类)

  •  成员内部类的定义格式

修饰符 class 外部类名称 {

  修饰符 class 内部类名称 {

    // ...

  }

  // ...

}

注意:内用外,可以随意访问;外用内,需要借助内部类对象。

 对于这种既有外部class,也有内部class,编译后的.class文件是什么样的?

如何使用成员内部类?有两种方式:

  • 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法

 运行结果:

  •  直接方式:

公式:

一般都是 类名称 对象名 = new 类名称();

现在是这样:外部类名称.内部类名称 对象名 = new 外部类名称(). new 内部类名称();

 3.内部类的同名变量访问

如果出现了重名现象,格式:外部类名称.this.外部类的成员变量名

 运行结果:

 5.局部内部类

如果一个类定义在一个方法内部的,那么这就是一个局部内部类

“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

 定义格式:

修饰符 class 外部类名称 {

  修饰符 返回值类型 外部类的方法名称(参数列表) {

    class 局部内部类名称 {

      // ...

    }

  }

}

 6.类的权限修饰符

public > protected > (default) > private

定义一个类的时候,权限修饰符规则:

(1)外部类:public / (default)

(2)成员内部类:public / protected / (default) / private

(3)局部内部类:什么都不能写

 7.局部内部类的final问题

局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】

 备注:

从Java 8+ 开始,只要局部变量事实不变,那么final关键字可以省略。

 原因:

(1)new 出来的对象在堆内存中

(2)局部变量是跟着方法走的,在栈内存中

(3)方法运行结束之后,立刻出栈,局部变量就会立刻消失

(4)但是new出来的对象会在堆中持续存在,直到垃圾回收消失

(5)因此,局部变量,和 new出来的对象生命周期不一样,必须保证局部变量不能变。

8.匿名内部类(重点

 如果接口的实现类,或者是父类的子类,只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】

 匿名内部类的定义格式:

接口名称 对象名 = new 接口名称() {

  // 覆盖重写所有抽象方法

};

 不需要写实现类了

 图中画框的就是匿名内部类

 对格式"new 接口名称() {...}"进行解析:

(1)new代表创建对象的动作

(2)接口名称就是匿名内部类需要实现哪个接口

(3){...}这才是匿名内部类的内容

匿名内部类适用于什么样的场景?

这个类只想用一次,创建对象的时候用,之后再也不用了,这种情况下,可以使用匿名内部类

匿名内部类注意事项:

(1)匿名内部类,在创建对象的时候,只能使用唯一一次。

如果希望多次创建对象,而且类的内容一样的话,那么就必须使用单独定义的实现类了。

注意:匿名内部类省略的是类名,但不是匿名对象,对象名称就叫objA

(2)匿名对象,在调用方法的时候,只能调用唯一一次

如果希望同一个对象,调用多次方法,那么必须给对象起个名字

 

 

 运行结果:

 (3)匿名内部类是省略了【实现类/子类名称】,匿名对象是省略了【对象名称】

这两个不是一回事!!!

9.内部类的访问规则

  (1)内部类可以直接访问外部类中的成员,包括私有

之所以可以直接访问,是因为内部类中持有了一个外部类的引用,格式:外部类名.this

  (2)外部类要访问内部类,必须要建立内部类的对象

  (3)在外部其他类中访问内部类的方式

    Outer.Inner in=new Outer().new Inner();
class Outer{//外部类
	private int x=3;
	class Inner{//内部类
		void function(){
			System.out.println("inner"+x);
		}
	}
	void method(){
		Inner in =new Inner();
		in.function();//要想访问内部类中的function方法,必须建立内部类对象
	}
}
class InnerClassDemo{//外部其他类
	public static void main(String[] args){
		Outer out=new Outer();
		out.method();
		//在外部其他类中访问内部类的方式
		Outer.Inner in=new Outer().new Inner();
		in.function();
	}
}

  (4)在外部其他类中,如何直接访问static内部类的非静态成员

    new Outer.Inner().function();

  (5)在外部其他类中,如何直接访问static内部类的静态成员

     Outer.Inner.function();

注意:如果一个内部类中定义了静态成员,那么该内部类必须是static

class Outer{//外部类
	private int x=3;
	static class Inner{//内部类中定义了静态方法,所以该内部类必须是static
		static void function(){
			System.out.println("inner"+x);
		}
	}

  外部类的静态方法访问内部类,该内部类也必须是static

class Outer{//外部类
	static class Inner{//内部类
		void show(){
			System.out.println("inner show");
		}
	}
	public static void method(){//外部类中的静态方法访问内部类,该内部类必须是static
		new Inner().show();
		
	}
}

  

原文地址:https://www.cnblogs.com/GumpYan/p/5738253.html