内部类就是指在一个类的内部去定义一个类,举个例子就是人的身体相当于一个外部类,它有自己的各种器官(相当于各种成员、属性),心脏相当于内部类,当然它也有自己的属性和行为,心脏可以通过血管通往人体的各个器官,就好像内部类可以访问外部类的成员一样。
内部类的属性
- 类名称只能用在定义过的范围中,除非用限定的名称来引用它。
- 内部类的名称必须与所嵌套的类不同。
- 内部类可以使用所嵌套类的成员变量。
- 内部类可以被定义在方法体中。此时,任何变量,不论是局部变量还是正式参数,如果变量被标记为final,那么,就可以被内部类中的方法访问。
- 内部类可以被定义为abstract。
只有内部类可以被声明为private或protected,以便防护它们不受来自外部类的访问。访问protected不妨碍内部类使用其它类的任何成员,只要一个类嵌套另一个。
内部类的基本结构
//外部类
class out{
private int number = 10;
//内部类
class In{
public void print(){
System.out.println(number);
}
}
}
public class Test{
public static void main(String[] args){
Out.In in = new Out().new In();
in.print();
}
}
//运行结果为:10
从上述代码我们可以看出内部类可以随意的使用外部类的成员变量(包括私有)而不用生成外部类的对象,这是内部类的优点,程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class,$代表Out.in中的点.号,必须先有外部类的对象才能生成内部类的对象,因为内部类的对象的作用就是为了访问外部类中的成员变量。
内部类的变量访问形式
class Out{
private int num = 10;
class In{
private int num = 20;
public void print(){
int num = 30;
System.out.println("局部变量:"+num);
System.out.println("内部变量:"+this.num);
System.out.println("外部变量:"+Out.this.num);
}
}
}
public class TestClass {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
}
}
//运行结果为:
//局部变量:30
//内部变量:20
//外部变量:10
从上面两个例子可以看出当内部类在没有同名的成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量,否则内部类中的局部变量会覆盖外部类的成员变量,而访问内部类本身的成员变量可用this.属性名,访问外部类的成员变量需要使用Out.this.属性名。
静态内部类
- 被自动地声明为static的内部类成为嵌套类。这些内部类失去了在局部范围和其它嵌套类中使用数据或变量的能力。
- 内部类不能声明任何static成员;只有嵌套类可以声明static成员。因此,一个需求static成员的内部类必须使用来自嵌套类的成员。
class Out{
private static int num2 = 10;
static class In{
private int num = 20;
public void print(){
int num = 30;
System.out.println("局部变量:"+num);
System.out.println("内部变量:"+this.num);
System.out.println("外部变量:"+num2);
}
}
}
public class TestClass {
public static void main(String[] args) {
Out.In in = new Out.In();
in.print();
}
}
//结果:
局部变量:30
内部变量:20
外部变量:10
静态内部类只能访问外部类的静态成员变量。
私有内部类
如果一个内部类只希望被外部类中的方法所操作,那么可以使用private将其声明为内部类。
class Out{
private static int num = 10;
private class In{
public void inPrint(){
System.out.println(num);
}
}
public void outPrint(){
new In().inPrint();
}
}
public class TestClass {
public static void main(String[] args) {
Out out = new Out();
out.outPrint();
}
}
//运行结果:10
在上面的代码中我们只能通过外部类里面来生成内部类的对象来进行操作,而无法直接new出内部类对象,这样内部类只有外部类可控制。
方法内部类
class Out{
private static int a = 10;
public void outPrint(final int b){
class In{
public void inPrint(){
System.out.println(a);
System.out.println(b);
}
}
new In().inPrint();
}
}
public class TestClass {
public static void main(String[] args) {
Out out = new Out();
out.outPrint(3);
}
}
//运行结果为:
10
3
匿名类
匿名类就是没有名字的类。
匿名类只能使用一次,它通常用来简化代码的编写。
使用匿名类的前提是:必须继承一个父类或实现一个接口
不使用匿名类来实现抽象方法:
abstract class Father{
public abstract void say();
}
class Son extends Father{
@Override
public void say() {
System.out.println("hello");
}
}
public class Test2 {
public static void main(String[] args) {
Father f = new Son();
f.say();
}
}
//结果:hello
使用内部类:
abstract class Father{
public abstract void say();
}
public class Test2 {
public static void main(String[] args) {
Father f = new Father(){
public void say(){
System.out.println("hello");
}
};
f.say();
}
}
//结果:hello
匿名类不具有构造器,Java会暗中调用其超类的构造器。
如果有一个简单的类,其代码易懂,并且你熟悉其所处的上下文,那匿名类是个很好的选择。
在Java中,匿名类经常被用于执行用户接口的简单事件处理。
f.addWindowListener(
new WindowAdapter()
{
Public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
“`