1.概述:把类定义在其他类的内部,这个类就称为内部类。
如:类B定义在类C中,B就是C的内部类。
class C{ //B为类A的内部类 class B{ } } |
2.访问特点:
(1)内部类可以直接访问外部类的成员,包括私有成员;
(2)外部类访问内部类成员,必须创建对象,通过对象访问。
class C{ //B为类A的内部类 private int num=10; class B{ public int Bnum=20; public void show() { //内部类直接访问外部类的成员 System.out.println(num); } } public void show1() { //直接访问内部类对应成员,报错 //System.out.println(Bnum); //通过创建内部类对象访问,成功 B b=new B(); System.out.println(b.Bnum); } }
|
3.内部类的分类
根据内部类的位置不同,可将内部类分为成员内部类、局部内部类。
class C{ //成员内部类 class B{ } public void show1() { //局部内部类 class D{ } } } |
4.成员内部类
成员内部类的访问格式:
外部类名.内部类名 对象名=外部类对象.内部类对象
class C{ //成员内部类 class B{ public void show() { System.out.println("你好"); } } }
public class niming { public static void main(String[]args) { //创建对象访问对应内部类函数成员 C.B b=new C().new B(); b.show(); } } |
虽然内部类可以以上述方式访问,但实际开发中,常将内部设为私有成员,以保护数据的安全,不让外部直接使用
(1)将内部类设为私有成员的使用方法
class C{ //成员内部类,设为私有 private class B{ public void show() { System.out.println("你好"); } } public void show1() { B b=new B(); b.show(); } }
public class niming { public static void main(String[]args) { //创建对象访问对应内部类函数成员 C c=new C(); c.show1(); } } |
(2)将内部类设为静态类
特定:静态内部类访问外部类成员时,只能访问外部类的静态成员
class C{ //静态成员变量 private static int num=20; //静态成员方法 public static void show2() { System.out.println("hello world"); } //成员内部类,设为私有静态 private static class B{ public void show() { System.out.println(num); show2(); } } public void show1() { B b=new B(); b.show(); } } public class niming { public static void main(String[]args) { //创建对象访问对应内部类函数成员 C c=new C(); c.show1(); } } |
Private 与 static修饰内部类的特点
Private 保证了数据的安全
Static 让数据访问更方便
(3)成员内部类面试题
补齐程序 class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; System.out.println(?); System.out.println(??); System.out.println(???); } } } 在控制分别输出:30,20,10 |
答案:(注意:内部类与外部类不存在继承关系)
class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; //三个变量对应的变量名相同 System.out.println(num);//访问的是本方法中的num变量,满足就近原则 System.out.println(this.num);//通过this变量,访问方法外,本类中的变量,this代表Inner类对象 System.out.println(Outer.this.num);//通过外部类名加this,返回外部类对象,访问对象外部类的num //System.out.println(new Outer().num); //通过创建对象的方式访问外部成员变量不推荐 } } } public class niming { public static void main(String[]args) { Outer.Inner inner=new Outer().new Inner(); inner.show(); } } |
5.局部内部类
(1)可以直接访问外部类的成员
class C{ //静态成员变量 private int num=20; //局部内部类访问外部类成员 public void show1() { class B{ public void show() { System.out.println(num); } } } } |
(2)方法内部通过创建内部类的对象来访问局部内部类的成员
class C{ //静态成员变量 private int num=20; //局部内部类访问外部类成员 public void show1() { class B{ public void show() { System.out.println(num); } } B b=new B(); b.show(); } public void show2() { B b=new B();//此处报错 //原因:局部内部类在在方法中定义,随着方法的调用产生,随着方法调用完消失,所以不能用此方法直接创建对象 } } |
(3)局部内部类访问局部变量
1)局部内部类访问局部变量时,必须用final修饰局部变量
2)原因:方法中的局部变量在方法调用时产生,在方法调用后消失,若方法消失后,内部类就不能再访问局部变量,但用final修饰后,在编译之后,产生的字节码中,会将对应的final修饰的变量认成常量,即内部类访问的是常量值
class C{ //静态成员变量 private int num=20; //局部内部类访问外部类成员 public void show1() { final int testNum=30; class B{ public void show() { System.out.println(num); System.out.println(testNum); //编译后,此句变为 //System.out.println(30); } } B b=new B(); b.show(); } } |
6.匿名内部类
(1)概念:即内部类的简化写法
(2)前提:存在一个类(可以是具体类也可以是抽象类) 或接口
(3)格式:new 类名或接口名{重写的方法}
(4)本质:创建的是继承了类或实现了接口的子类匿名对 象。
interface D{ void ShowContext(); } class B{ public void show() { //匿名内部类的实现 new D(){ @Override public void ShowContext() { System.out.println("hello"); } }; }; } |
(5)匿名内部类方法的访问
//方法1:直接在new A内部类后边加点加方法,这样访问,如果方法多了,调用太麻烦 new D(){ @Override public void ShowContext() { System.out.println("hello"); } }.ShowContext(); //方法2:通过创建对象来访问,多态思想 D a=new D(){ @Override public void ShowContext() { System.out.println("hello"); } }; a.ShowContext(); |
(6)匿名内部类在开发中的使用,一般是方法参数为接口的情况
interface D{ void ShowContext(); } class B{ //参数为接口对象 public void show(Dd) { d.ShowContext(); } }
public class niming { public static void main(String[]args) { B b=new B(); //调用时使用匿名类创建匿名对象 b.show(new D(){ @Override public void ShowContext() { // TODO Auto-generated method stub System.out.println("hello"); } }); } } |
(7)匿名内部类的面试题
interface Inter { void show(); } class Outer { //补齐代码 } class OuterDemo { public static void main(String[] args) { Outer.method().show(); } } 要求在控制台输出”HelloWorld”
|
答案:
//思路:Outer.method() 说明method()为Outer类中的静态方法 // Outer.method().show();因为method()后边用点调用了对应的方法,相当于一个对象调用某个方法,而show方法又是接口Inter中的方法, //即想到method应返回一个Inter的实现类对象,而又不能创建新对象,所以想到使用匿名类 interface Inter { void show(); } class Outer { public static Inter method() { return new Inter() { @Override public void show() { System.out.println("hello world"); } }; } } public class niming { public static void main(String[]args) { Outer.method().show(); } } |