顾名思义,就是定义在另一个类的内部的类
为了更好的理解内部类,我们定义如下两个类,后面的所有说明都基于这两个类:
package com.aran.innerClass;
/**
* 一个外部类
*
* @Author Aran
* @Date 2020/6/24 8:06 下午
*/
public class Ouuter {
}
package com.aran.innerClass;
/**
* 一个其他类
*
* @Author Aran
* @Date 2020/6/24 8:06 下午
*/
public class Other {
}
即作为类的成员的内部类,直接写在类的内部的,与类的成员变量和成员方法同级
示例:
package com.aran.innerClass;
/**
* 一个外部类
*
* @Author Aran
* @Date 2020/6/24 8:06 下午
*/
public class Outter {
private String v1= "我是v1,我是Outter的成员变量";
public void SayHelloInOuuter(){
System.out.println("Hello,我是Outter的成员方法SayHelloInOutter");
}
public class Inner{
public void SayHiInInner(){
System.out.println("Hi,我是内部类Inner的SayHiInInner");
}
}
}
说明:
那么, 这样的内部类是否可以访问外部类的成员变量和方法呢?
示例:
package com.aran.innerClass;
/**
* 一个外部类
*
* @Author Aran
* @Date 2020/6/24 8:06 下午
*/
public class Outter {
private String v1= "我是v1,我是Outter的成员变量";
private final String v2 = "我是v2,我是Outter的final变量";
private static String v3 = "我是v3,我是Outter中的static变量";
private String v4 = "我是[外部类]的同名非静态变量";
private static String v5 = "我是[外部类]的同名静态变量";
public void SayHelloInOuuter(){
System.out.println("Hello,我是Outter的成员方法SayHelloInOutter,我不是静态的");
}
public static void SayHahaInOuuter(){
System.out.println("Haha,我是Outter的成员方法SayHahaInOuuter,我是静态的");
}
public class Inner{
private String v4 = "我是[内部类]的同名变量";
/**
* Inner classes cannot have static declarations
*/
//private static String v5 = "我是[内部类]的同名静态变量";
// public static void test();
public void SayHiInInner(){
System.out.println("Hi,我是内部类Inner的SayHiInInner");
System.out.println("内部类访问外部类的普通变量:" + v1);
System.out.println("++++++++++++++++++++++++++++");
System.out.println("内部类访问外部类的final变量:" + v2);
System.out.println("++++++++++++++++++++++++++++");
System.out.println("下面是内部类访问外部类的非静态&静态方法:");
SayHelloInOuuter();
SayHahaInOuuter();
System.out.println("++++++++++++++++++++++++++++");
System.out.println("内部类访问外部类的static变量:" + v3);
System.out.println("++++++++++++++++++++++++++++");
System.out.println("内部类访问外部类的同名非静态变量:" + Outter.this.v4);
System.out.println("++++++++++++++++++++++++++++");
}
}
public static class Inner2{
private static String v5 = "我是[内部类]的同名静态变量";
private String v4 = "我是[内部类]的同名静态变量";
public void sayXixiInInner2(){
System.out.println("静态内部类访问外部类同名静态变量:" + v5);
// System.out.println("内部类访问外部类的普通变量:" + v1);
// System.out.println("++++++++++++++++++++++++++++");
// System.out.println("内部类访问外部类的final变量:" + v2);
// System.out.println("++++++++++++++++++++++++++++");
// System.out.println("下面是内部类访问外部类的非静态&静态方法:");
// SayHelloInOuuter();
SayHahaInOuuter();
// System.out.println("++++++++++++++++++++++++++++");
// System.out.println("内部类访问外部类的static变量:" + v3);
// System.out.println("++++++++++++++++++++++++++++");
// System.out.println("内部类访问外部类的同名非静态变量:" + Outter.this.v4);
// System.out.println("++++++++++++++++++++++++++++");
}
}
public void outterCallInner() {
Inner inner = new Inner();
inner.SayHiInInner();
System.out.println("==============================");
Inner2 inner2 = new Inner2();
inner2.sayXixiInInner2();
}
public static void main(String[] args) {
new Outter().outterCallInner();
}
}
输出:
Hi,我是内部类Inner的SayHiInInner
内部类访问外部类的普通变量:我是v1,我是Outter的成员变量
++++++++++++++++++++++++++++
内部类访问外部类的final变量:我是v2,我是Outter的final变量
++++++++++++++++++++++++++++
下面是内部类访问外部类的非静态&静态方法:
Hello,我是Outter的成员方法SayHelloInOutter,我不是静态的
Haha,我是Outter的成员方法SayHahaInOuuter,我是静态的
++++++++++++++++++++++++++++
内部类访问外部类的static变量:我是v3,我是Outter中的static变量
++++++++++++++++++++++++++++
内部类访问外部类的同名非静态变量:我是[外部类]的同名非静态变量
++++++++++++++++++++++++++++
==============================
静态内部类访问外部类同名静态变量:我是[内部类2]的同名静态变量
Haha,我是Outter的成员方法SayHahaInOuuter,我是静态的
说明:
如果在Other中该如何Outter内部类的变量和方法呢?
示例:
package com.aran.innerClass;
/**
* 一个其他类
*
* @Author Aran
* @Date 2020/6/24 8:06 下午
*/
public class Other {
public static void main(String[] args) {
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
//obvious equal to
/**
* Outter.Inner inner = new Outter().new Inner();
*/
inner.SayHiInInner();
}
}
输出:
Hi,我是内部类Inner的SayHiInInner
内部类访问外部类的普通变量:我是v1,我是Outter的成员变量
++++++++++++++++++++++++++++
内部类访问外部类的final变量:我是v2,我是Outter的final变量
++++++++++++++++++++++++++++
下面是内部类访问外部类的非静态&静态方法:
Hello,我是Outter的成员方法SayHelloInOutter,我不是静态的
Haha,我是Outter的成员方法SayHahaInOuuter,我是静态的
++++++++++++++++++++++++++++
内部类访问外部类的static变量:我是v3,我是Outter中的static变量
++++++++++++++++++++++++++++
内部类访问外部类的同名非静态变量:我是[外部类]的同名非静态变量
++++++++++++++++++++++++++++
可以看出,与直接在Outter中调用结果一致。
说明:
局部,内部类,即,定义在类的成员方法中的类
package com.aran.innerClass;
/**
* 局部内部类示例
*
* @Author Aran
* @Date 2020/6/25 10:17 上午
*/
public class Outter1 {
/**
* 外部类独有属性
*/
private int v1 = 1;
/**
* 外部类同名属性
*/
private int v2 = 2;
/**
* 外部类静态属性
*/
private static int v3 = 3;
/**
* 外部类的非静态方法
*/
private void OutterMethod(){
System.out.println("这是外部类的非静态方法!");
}
/**
* 外部类的静态方法
*/
private static void OutterStaticMethod() {
System.out.println("这是外部类的静态方法!");
}
/**
* 含有局部内部类的方法
*/
public void OutterMethodHasInnerClass(){
int v4 = 4;
/**
* 局部内部类,类前不能有访问修饰符
*/
class Inner{
private int v5 = 5;
private final int v2 = 22;
/**
* 局部内部类方法
*/
public void InnerMethod(){
System.out.println("这是局部内部类的方法!");
/**
* 访问方法内局部变量
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("访问局部内部类所在方法内部属性:" + v4);
/**
* 访问外部类同名属性
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("外部类的同名属性:" + Outter1.this.v2);
/**
* 外部类的静态属性
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("外部类的静态属性:" + v3);
/**
* 访问内部类中的属性
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("内部类之内的属性:" + v2);
/**
* Variable 'v4' is accessed from within inner class, needs to be final or effectively final
*/
// v4 = 12;
/**
* 访问外部类中的非静态方法
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("访问外部类中的非静态方法");
OutterMethod();
/**
* 访问外部类中的静态方法
*/
System.out.println("+++++++++++++++++++++++++++++++++");
System.out.println("访问外部类中的静态方法:");
OutterStaticMethod();
}
}
Inner inner = new Inner();
inner.InnerMethod();
}
public static void main(String[] args) {
Outter1 outter1 = new Outter1();
outter1.OutterMethodHasInnerClass();
}
}
输出:
这是局部内部类的方法!
+++++++++++++++++++++++++++++++++
访问局部内部类所在方法内部属性:4
+++++++++++++++++++++++++++++++++
外部类的同名属性:2
+++++++++++++++++++++++++++++++++
外部类的静态属性:3
+++++++++++++++++++++++++++++++++
内部类之内的属性:22
+++++++++++++++++++++++++++++++++
访问外部类中的非静态方法
这是外部类的非静态方法!
+++++++++++++++++++++++++++++++++
访问外部类中的静态方法:
这是外部类的静态方法!
说明:
如果想在内部类中使用v4,那么v4不能被修改
使用局部内部类时,通常还可以再进一步。假如只想创建这个类的一个实例,甚至不需要为类指定名字,这样一个类被称为 匿名内部类
匿名内部类的格式如下:
new SuperType(construction parameters){
inner class methods and data
}
其中,SuperType可以是接口,如ActionListener,如果是这样,内部类就是实现这个接口。SuperType也可以是一个类,如果是这样,内部类就要扩展这个类。
由于构造器的名字必须与类名相同,而匿名内部类没有类名,所以,匿名内部类不能有构造器。 实际上,构造参数要传递给超类(superclass)构造器。具体地,只要内部类实现一个接口,就不能有任何构造参数。不过,仍是要提供一组小括号:
new InterfaceType()
{
methods and data
}
示例:
package com.aran.innerClass;
/**
* 接口(interface)中的方法默认都是public的
* @Author Aran
* @Date 2020/6/25 6:13 下午
*/
public interface IAnimal {
void speak();
}
下面实现这个接口
package com.aran.innerClass;
/**
* @Author Aran
* @Date 2020/6/25 6:15 下午
*/
public class Outter3 {
public static IAnimal getInnerInstance(String speak){
return new IAnimal() {
@Override
public void speak() {
System.out.println(speak);
}
};
//上面的分号必须有
}
public static void main(String[] args) {
/**
* 调用的speak()是重写后的speak方法
*/
Outter3.getInnerInstance("小狗 旺旺").speak();
}
}
输出:
小狗 旺旺
说明:
这一篇是java内部类的基础,不妥之处,望大神指正!
参考