内部类的定义与使用:在类内部进行其他类结构嵌套操作
首先我们来看一段内部内的代码结构,观察内部类的简单使用
class Outter{
private String msg = "Outter中的字符串";
//-----------------------------------------------------------
//内部类
class Inner{
private String inMsg = "Inner中的字符串";
public void fun(){
//直接调用外部类的私有属性
System.out.println(msg);
}
}
//------------------------------------------------------------
public void test(){
Inner in = new Inner();
in.fun();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.test();
}
}
为什么会存在内部类呢?
内部类优点:
(1).内部类与外部类可以方便的访问彼此的私有域(包含私有方法、私有属性)
(2).内部类是另外一种封装(保护性),对外部的其他类隐藏(心脏包在人身体内部)
(3).内部类可以实现java 单继承的局限
内部类的单继承局限代码如下:
class A{
private String msg = "test";
public String getMsg(){
return msg;
}
}
class B{
private int age = 20;
public int getAge(){
return age;
}
}
class C{
//-------------------------------------------------
class InnerClassA extends A{
public String name(){
return super.getMsg();
}
}
class InnerClassB extends B{
public int age(){
return super.getAge();
}
}
//----------------------------------------------------
public String name(){
return new InnerClassA().name();
}
public int age(){
return new InnerClassB().age();
}
}
public class Test{
public static void main(String[] args){
C c = new C();
System.out.println(c.name());
System.out.println(c.age());
}
}
缺点:结构复杂
内部类与外部类的关系:
a . 对于非静态内部类,内部类的创建需要依赖外部类对象,在没有外部类实例之前无法创建非静态内部类。
b . 内部类是一个相对独立的个体,与外部类没有is - a 关系
c . 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部元素,需要通过内部类的引用间接访问。
非静态内部类直接访问外部类的元素例子:
class Outter{
private String msg;
private int age;
class Inner{
public void display(){
msg = "test"; //隐藏 Outter.this.msg = "test";
age = 20; //同隐藏
System.out.println(msg);
System.out.println(age);
}
}
public void test(){
Inner in = new Inner();
in.display();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.test();
}
}
外部访问内部例子:
class Outter{
class Inner{
private String msg = "InnerClass";
}
public void test(){
Inner in = new Inner(); //创建对象以后才能用
System.out.println(in.msg);
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.test();
}
}
创建内部类语法(在外部类外部)
(1)创建非静态内部类
外部类 . 内部类 内部类引用 = new 外部类().new 内部类( );
outter . Inner in = new Outter() . new Inner();
(2) 创建静态内部类
外部类 . 内部类 内部类引用 = new 外部类 . 内部类();
outter . Inner in = new outter . Inner();
内部类的分类:
I . 成员内部类(成员方法) * * * * *
a. 成员内部类不能存在任何static 变量或方法,可以访问外部类的静态域
b . 成员内部类是依附外部类的,而static时部依赖对象的,所有只有先创建了外部类才能创建内部类。
存在私有内部类(静态、成员均可)
ArrayList中Node内部类、HashMap 中 Entry 内部类(私有内部类)
outter . Inner in = new outter() .new Inner();
成员内部类实例:
class Outter{
private String name = "test";
private static int age = 20;
class Inner{
public void fun(){
System.out.println(name);
System.out.println(age);
}
}
}
public class Test{
public static void main(String[] args){
Outter.Inner in = new Outter().new Inner();
in.fun();
}
}
II. 静态内部类(静态方法)(静态方法与对象无关)* * * * *
a . 静态内部类的创建不需要依赖外部类,可以直接创建
b .静态内部类不可以使用任何外部类的非static 域(包含属性与方法),但可以存在自己的成员变量
class Outter{
private String name = "test";
private static int age = 20;
static class Inner{
private String name = "test";
public void fun(){
System.out.println(age);
System.out.println(name);
}
}
}
public class Test{
public static void main(String[] args){
Outter.Inner in = new Outter.Inner();
in.fun();
}
}
III. 方法内部类
a. 方法内部类不允许使用访问权限修饰符 public private protected 均不允许
b. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问。
c . 方法内部类如果要想使用方法形参,该形参必须使用final 声明(JDK8 将形参变为隐式final声明)
class Outter{
private int num;
public void display(int test){
class Inner{
private void fun(){
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.display(20);
}
}
IV. 匿名内部类(lamdba 表达式前身)
匿名内部类就是一个没有名字的方法内部类。因此特点与方法内部类完全一样,除此之外,还有两个自己的特点:
a . 匿名内部类必须继承一个抽象类或者实现一个接口
b . 匿名内部类没有构造方法
interface MyInterface{
void test();
}
class Outter{
private int num;
public void display(int para){
//匿名内部类实现了MyInterface接口
new MyInterface(){
public void test(){
System.out.println("匿名内部类"+para);
}
}.test();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.display(20);
}
}
结果
匿名内部类20