内部类
定义:在一个类的内部进行其他类结构的嵌套。
先写一个内部类
class Outer{
private String msg = "Hello World";
//=============内部类==================
class Inner{
public void print(){
System.out.println(Outer.this.msg);//调用Outer的private属性
}
}
//=============内部类==================
//产生一个内部类对象并调用内部类的print方法
public void fun(){
new Inner().print();
}
}
public class Test{
public static void main(String[] args) {
Outer ou = new Outer();
ou.fun();
}
}
引入内部类后,程序的结构有些混乱。虽然内部类破坏了程序的结构,但是从另一方面来讲,内部类可以方便的操作外部类的私有访问。
如果这个操作不用内部类来写,会是什么情况呢?
class Outer{
private String msg = "Hello World";
public String getMsg(){
return msg;
}
public void fun(){
new Inner().print(this);
}
}
class Inner{
public void print(Outer ou){
System.out.println(ou.getMsg());
}
}
public class Test{
public static void main(String[] args) {
Outer ou = new Outer();
ou.fun();
}
}
可见代码比上面的复杂了一些,要写get函数获取outer类的私有属性。
内部类存在的意义:
1.内部类与外部类可以互相访问彼此的私有域(最大优点)
2.内部类可以实现Java的单继承局限
3.内部类可以对同一包中的其他类隐藏起来,仅供外部类使用(保护性)
缺点:结构复杂
内部类分类
1.成员内部类——对比成员方法理解
a.成员内部类不能存在任何static变量或方法,但可以访问外部类的静态域;(成员内部类需要依附外部类的创建而创建,而static变量或方法与对象无关,即便没有外部类也可以创建static变量或方法,这就与前面矛盾)
b.成员内部类需要依附外部类——new Outter().new Inner();先创建外部类再创建内部类;
c.内部类可以使用private封装,表示私有内部类,该内部类仅供外部类使用(如HaspMap中的Entry内部类,ArrayList中的Node内部类)
2.静态内部类-用static修饰——对比静态方法理解
a.静态内部类的创建不需要外部类,可以直接创建
b.静态内部类不可以访问外部类的任何非static域,但可以存在成员变量
3.方法内部类
class Outer{
private String msg = "Hello World";
public void fun(){
class Inner{
public void print(){
System.out.println(Outer.this.msg);//调用Outer的private属性
}
}
new Inner().print();;
}
}
public class Test{
public static void main(String[] args) {
Outer ou = new Outer();
ou.fun();
}
}
1.方法内部类不能使用任何访问权限修饰符(如public、private)
2.方法内部类对外(方法外)完全隐藏,除了该方法可以访问它之外,其余地方均不能访问
3.方法内部类要想使用方法形参,该形参必须使用final声明(jdk8变为隐式final声明)
4.匿名内部类——方法内部类的特殊版本——lambda表达式的第一步
1.没有访问权限修饰符
2.匿名内部类必须继承一个抽象类或者实现一个接口
3.匿名内部类没有构造方法,因为它没有类名
interface Iif{
public void display();
}
class Test{
public static void main(String[] args) {
new Iif(){
@Override
public void display(){
System.out.println("匿名内部类");
}
}.display();
}
}
创建内部类
创建内部类的语法(在外部类的外部)
创建非静态内部类
外部类.内部类 内部类引用 = new 外部类().new 内部类();
Outer.Inner in = new Outter().new Inner();
之所以要先进行外部类对象的实例化,因为此时外部类存在普通属性,这些属性必须进行实例化后才能访问。
如果说现在一个内部类只想被外部类使用,即:不希望直接产生内部类的实例化对象,可以使用private定义。
在进行属性访问时,都需要加上this关键字。所以如果想在内部类中明确的使用this,那么语法形式如下:外部类.this.属性
创建静态内部类
外部类.内部类 内部类引用 = new 外部类.内部类();
Outer.Inner in = new Outer.Inner();
内部类与外部类的关系
1.对非静态内部类而言,内部类的创建需要依赖外部类的实例化对象,在没有外部类对象之前是无法创建内部类的。
2.内部类是一个相对独立的个体,与外部类也不是继承关系。
3.内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问。