Java中内部类的定义与使用
(一)内部类的基本概念
内部类:所谓内部类就是在一个类的内部进行其他类结构的嵌套的操作。
- 内部类可以访问外部类的属性,方法;
- 外部类无法访问内部类的属性,方法,若要访问,需要通过实例化内部类的对象。
- 内部类使用外部类属性:外部类名.this.属性名—也可只用属性名;
内部类使用内部类属性:this.属性名——也可只用属性名。 - 普通类若要访问其他类的属性,需要进行对象引用。
举例如下:
//普通类
//Outer为外部类
class Outer{
String name = "kelly";
//Inner为内部类
class Inner{
//内部类中的方法
public void print(){
//内部类可以使用外部类的属性,1,直接使用,2,外部类名称.this.属性名
System.out.println(Outer.this.name+" is beautiful");
}
}
//外部类中的方法
public void fun(){
//外部类不能直接使用内部类的属性和方法,需要对内部类进行实例化
Inner inner = new Inner();//实例化
inner.print();//调用内部类的方法
}
}
//主类
public class TestClass{
public static void main(String[] args){
Outer out = new Outer();//对外部类实例化
out.fun();//调用外部类的方法
}
}
运行结果如下:
引入内部类后,程序的结构有些混乱。虽然内部类破坏了程序的结构,但是从另一方面 来讲,内部类可以方便的操作外部类的私有访问。
可将内部类移出 与 外部类 写成平行类。
普通类若要访问其他类的属性,需要进行对象引用。
修改以上代码:
//Outer类与Inner类都是普通类,并且两个类是平行关系
class Outer{
String name = "kelly";
public void fun(){//(3)out对象调用了fun方法
Inner inner = new Inner(this);//(4)this表示当前对象
inner.print();//(7)调用Inner类的方法
}
}
//普通类若要访问其他类的属性,需要进行对象引用
class Inner{
Outer out; //对Outer类的对象引用
public Inner(Outer out){//(5)调用Inner的构造方法
this.out = out;//(6)引用传递
}
public void print(){//(8)执行方法
System.out.println(out.name+" is beautiful");
}
}
//主方法
public class TestClass{
public static void main(String[] args){
Outer out = new Outer();//(1)实例化Outer类对象
out.fun();//(2)调用Outer类方法
}
}
运行结果与上面代码一致:
(二)内部类为什么存在
内部类为什么存在:
- 内部类可以访问外部类的数据;
- 其他包中的类看不到内部类,内部类被隐藏,只有其对应的外部类可以看到;
- JAVA中只能单继承, 内部类解决单继承缺陷。
(三)内部类与外部类的关系 - 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的;
- 内部类是一个相对独立的个体,使用的时候完全独立,但是创建的时候需要引用外部类实例化;
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素;
- 外部类可以通过内部类引用间接访问内部类元素。
内部类创建的两种形式:
- 在外部类内部创建内部类
在外部类内部创建内部类,就像普通对象一样直接创建。
Inner inner = new Inner(); - 在外部类以外的其他类中创建内部类
外部类.内部类 内部类对象 = new 外部类().new 内部类();
Outter.Inner inner = new Outter().new Inner();
举例如下:
1,在外部类内部创建内部类
class Outer{
private String name;
private int age;
class Inner{
public Inner(){
Outer.this.name = "kity";
Outer.this.age = 21;
}
public void print(){
System.out.println(name+" is beautiful,his age is "+age);
}
}
public void fun(){
//两种方法都可行
//Outer.Inner inner = new Outer().new Inner();
Inner inner = new Inner();
inner.print();
}
}
public class TestClass{
public static void main(String[] args){
Outer out = new Outer();
out.fun();
}
}
运行结果如下:
2,在外部类以外的其他类中创建内部类
class Outer{
private String name;
private int age;
class Inner{
public Inner(){
Outer.this.name = "kity";
Outer.this.age = 21;
}
public void print(){
System.out.println(name+" is beautiful,his age is "+age);
}
}
public void fun(){
Inner inner = new Inner();
inner.print();
}
}
class Test4{
public void funnnn(){
//在其他类中创建内部类的时候注意形式
Outer.Inner inner = new Outer().new Inner();
inner.print();
}
}
public class TestClass{
public static void main(String[] args){
Test4 out = new Test4();
out.funnnn();
}
}
运行结果与上面代码一致:
(四)内部类
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
1, 成员内部类
- 成员内部类中不能存在任何static的变量和方法;
- 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类 。
2, 静态内部类
- 关键字static可以修饰成员变量、方法、代码块,其实它还可以修饰内部类,使用static修饰的内部类我们称之为静 态内部类。
- 静态内部类的创建是不需要依赖于外围类,可以直接创建 。
- 静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类则都可以 。
举例:
class Outer{
private static String name = "jack";
static class Inner{
public void print(){
//静态内部类使用外部类的实行时,只能调用外部类的static属性
//此时不能用 (外部类名.this.属性名)形式,直接使用属性名即可
// System.out.println("姓名为:"+Outer.this.name);---error
System.out.println("姓名为:"+name);
}
}
public void fun(){
Inner inner = new Inner();
inner.print();
}
}
public class TestClass{
public static void main(String[] args){
Outer out = new Outer();
out.fun();
}
}
运行结果如下:
3, 方法内部类(局部内部类)
- 方法内部类定义在外部类的方法中。
- 方法内部类和成员内部类基本一致,只是它们的作用域不同,方法内部类只能 在该方法中被使用,出了该方法就会失效。
- 局部内部类不允许使用访问权限修饰符 public private protected 均不允许。
- 局部内部类对外完全隐藏,除了创建这个类的方法可以访问它其他的地方是不允许访问的。
- 局部内部类要想使用方法形参,该形参必须用final声明(JDK8形参变为隐式final声明)。
举例:
class Outer{
private String name = "Alice";
//方法内部类定义在外部类方法中,只能在该方法中使用
public void display(){
class Inner{
public void print(){
System.out.println(name+" is beautiful!!!");
}
}
new Inner().print();//创建匿名对象并调用方法内部类中的方法
}
}
public class TestClass{
public static void main(String[] args){
Outer out = new Outer();
out.display();
}
}
结果如下:
4, 匿名内部类
匿名内部类其实就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束.除此之外,还有一些地方需要 注意:
- . 匿名内部类是没有访问修饰符的;
- 匿名内部类必须继承一个抽象类或者实现一个接口 ;
- 匿名内部类中不能存在任何静态成员或方法
- 匿名内部类是没有构造方法的,因为它没有类名
- 与局部内部相同匿名内部类也可以引用方法形参。此形参也必须声明为 final
- 匿名内部类最多只能创建一个对象,没办法创建更多对象。