Java初学——内部类

初识内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
内部类是一个非常有用的特性但又比较难理解使用的特性(我到现在都没有怎么使用过内部类,对内部类也只是略知一二)。

内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类。

public class OuterClass {
        private String name ;
        private int age;
        
        class InnerClass{
            public InnerClass(){
                name = "chenssy";
                age = 23;
            }
        }
    }

在这里InnerClass就是内部类,对于初学者来说内部类实在是使用的不多。
广泛意义上的内部类一般来说包括这四种:成员内部类局部内部类静态内部类匿名内部类。下面就先来了解一下这四种内部类的用法。

一、成员内部类

public class Outer{
	private int a =99;//外部类的私有变量
	//内部类Inner
	public class Inner{
		int b = 2;//内部类的变量
		public void test() {
			System.out.println("访问外部类的a:"+a);
			System.out.println("访问内部类的b:"+b);
		}
	}
	
	public static void main(String[] args) {
		Outer o = new Outer();//创建外部类对象o
		Inner i = o.new Inner();//使用外部类创建内部类对象i
		i.test();//调用test方法
	}
}

结果为

访问外部类的a:99
访问内部类的b:2

这样看起来,类Inner像是类Outer的一个成员,Outer称为外部类。
从上面的代码中我们可以看到,成员内部类的使用方法:

  1. Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如public 、 protected 、 private 等
  2. Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer类中的私有属性a
  3. 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );

不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法

二、局部内部类

局部内部类就是内部类定义在外部类的方法中,局部内部类只在该方法的内部可见,即只在该方法内可以使用。

public class Outer{
	public void show() {
		final int a = 25;
		// 局部内部类
		class Inner {
			public void print() {
				System.out.println("访问外部方法中的a:"+a);
			}
		}
		Inner mi = new Inner();//创建局部内部类对象
		mi.print();//调用方法
	}
	
	public static void main(String[] args) {
		Outer o = new Outer();//创建外部类对象
		o.show();//调用方法
	}
}

注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。

三、静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

public class Outer{
	static int b = 1;
	//静态内部类
	public static class Inner{
		int b =2;
		public void test() {
			System.out.println("外部类b"+ Outer.b);
			System.out.println("内部类b"+ b);
		}
	}
	
	public static void main(String[] args) {
		Inner i = new Inner();
		i.test();
	}
}

静态内部类的特点是:

  1. 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。
  2. 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。
  3. 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();

四、匿名内部类

匿名内部类应该是平时我们编写代码时用得最多的

abstract class Person{//声明一个抽象类
    public abstract void eat();
 }
 
public class train{
	public static void main(String[] args) {
		Person p =new Person() {//匿名内部类
			@Override
			public void eat() {
				System.out.println("吃点什么。。");
			}
		};
		p.eat();
	}
}

可以看到,我们直接将抽象类Person中的方法在大括号中实现了,这样便可以省略一个类的书写,并且,匿名内部类还能用于接口上。

interface Person{//声明一个抽象类
    public abstract void eat();
 }
 
public class train{
	public static void main(String[] args) {
		Person p =new Person() {//匿名内部类
			@Override
			public void eat() {
				System.out.println("吃点什么。。");
			}
		};
		p.eat();
	}
}

上下两个运行结果都是:吃点什么。。
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现。

使用匿名内部类的过程中,我们需要注意如下几点:

  1. 使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
  2. 匿名内部类中是不能定义构造函数的。
  3. 匿名内部类中不能存在任何的静态成员变量和静态方法。
  4. 匿名内部类为局部内部类(即方法内部类),所以局部内部类的所有限制同样对匿名内部类生效。
  5. 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

文章部分来源于网络,再次整理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值