Java的内部类和匿名类 , 您了解过吗?

本文原创首发CSDN,本文链接 https://blog.csdn.net/qq_41464123/article/details/107480664 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本链接,谢谢配合。



零、为什么要写内部类?

 

之前在学习Android百度地图的时候,发现一个Activity中居然有两个嵌套的类(Class),成功引起了我的注意,于是最近在暑假系统了学习了Java中的四种内部类。

最初在大二入门Java的时候,我就了解过Java的匿名类和内部类,那时候觉得这些都是理论性的东西,实际开发不一定能用到,于是就淡化了。直到最近,发现Java的内部类机制在实际开发中用处还是不小的,于是系统的学习了内部类,并写下了这篇总结。

 


一 、类

 

1.1 基础类

 

类的概念、访问权限修饰符,我已经在《学习Java的你,真的会面向对象编程吗?》详细讲解了。

类是什么?类是静态的模板,规定了 将该类实例化的对象 的共性。

public class People {
	
	String userName;
	int userAge;
	
	void say() {
		System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
	}
}

看,这就是一个 People 类,他有成员变量 userNameuserAge,还有成员方法say()

 

1.2 封装类

 

如果结合上Java的封装原则,那么,就需要为成员变量、成员方法加上访问权限修饰符,代码就变成了这个样子:

public class People {
	
	private String userName;
	private int userAge;
	
	public void say() {
		System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
	}

	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public int getUserAge() {
		return userAge;
	}
	public void setUserAge(int userAge) {
		this.userAge = userAge;
	}
}

从程序功能上来说,前后两段代码的功能是一致的,但是从Java语言开发规范角度来讲,每一个实体类都必须满足封装原则,简单来讲,实体类的成员变量必须为私有类型,并且提供 set 和 get 方法让外部获取、修改变量。

可以说,上面这段程序才是真正意义上的Java实体类Bean。

 


二、内部类

 

我的理解:内部类就是类中类,依附于普通类中,可以间接实现Java类的多继承。

内部类是指在一个外部类的内部再定义一个类,内部类作为外部类的一个成员,是依附于外部类存在的。

内部类可以是静态的,通常用 protected 或者 private 关键字修饰,外部类只能使用public或者系统默认权限。

如果你对Java的访问权限不熟悉,可以看一下我这篇文章《一文搞懂Java的 构造方法 和 访问权限》

内部类主要有四种,分别是成员内部类、方法内部类、静态内部类、匿名内部类(图片来源于网络,侵删)

 


2.1 成员内部类

 

成员内部类,顾名思义就是内部类作为成员存在于类中,和成员变量、成员方法同级。

比如下面这个 People 类,包含了一个内部类 Book,该类和成员变量 userName 、userAge 同级。

Book内部类,也可以拥有自己的成员变量、成员方法,以及自身的构造方法

public class People {

	class Book{
		String bookName;
		
		Book(String bookName){
			this.bookName = bookName;
		}
		
		void open() {
			System.out.println("The " + this.bookName + " was opened!");
		}
	}
}

我们如果要实例化这个成员内部类,就必须采用

外部类.内部类 内部类对象 = new 外部类().new 内部类();

 实际代码如下:

public class Main {

	public static void main(String[] args) {
		People.Book book = new People().new Book("Java程序设计"); 
		book.open();
	}
}

 运行效果如下,也就是调用了内部类 Book 的 open() 方法,输出这样一句话。


2.2 静态内部类

 

在讲解静态内部类之前,先讲解一下静态,也就是static关键字

static是静态的意思。在Java语言中,static关键字修饰的成员是可以被所有对象共享的。

如果某个类加了static关键字,则直接可以使用类名直接访问。

将2.1小节的People类中的 Book子类,加上一个 static关键字 修饰

static class Book{
	String bookName;
	
	Book(String bookName){
		this.bookName = bookName;
	}
	
	void open() {
		System.out.println("The " + this.bookName + " was opened!");
	}
}

那么外部就直接可以使用类名进行实例化操作,就像一个普通实例类一样,如下面代码所示:

import cn.zwz.People.Book;

public class Main {

	public static void main(String[] args) {
		Book book = new Book("Java程序设计"); 
		book.open();
	}
}

 我们可以得到和 2.1小节所讲的一致的效果。


本文原创首发CSDN,本文链接 https://blog.csdn.net/qq_41464123/article/details/107480664 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本链接,谢谢配合。


2.3方法内部类

 

方法内部类是指在Java方法中定义的类。

我们在原有的 People 类中,定义一个say()方法,在该方法中定义一个 Issue 内部类。

在 Issue 内部类中,定义一个方法 speakIsser(),内容是输出话题的名称。

public class People {
	
	public void say(String issue) {
		class Issue {
			public void speakIsser() {
				System.out.println("My issues is " + issue);
			}
		}
		new Issue().speakIsser();
	}
}

接着编写测试方法,实例化一个 People 对象,并调用 people 的 say() 方法

public class Main {

	public static void main(String[] args) {
		People people = new People();
		people.say("Hello ZWZ!");
	}
}

运行结果显示,people 的 say() 方法,调用了 Issue内部类中的 speakIsser()方法,输出了这句话。

 


2.4匿名内部类

 

我们对第三小节的程序稍加修改

1. 定义一个Issue接口,或者普通类。

2. 在 People 类的 say()方法中,new 出来一个 Issue 对象,实现 speakIsser() 抽象方法的具体实现。

3. 在Issue对象的后面调用speakIsser()方法。

代码如下所示:

interface Issue{
	public void speakIsser();
}
public class People {
	
	public void say(String issue) {
		new Issue() {
			public void speakIsser() {
				System.out.println("My issues is " + issue);
			}
		}.speakIsser();
	}
}

测试方法程序,同第三小节的方法内部类,不做修改

public class Main {

	public static void main(String[] args) {
		People people = new People();
		people.say("Hello ZWZ!");
	}
}

运行结果如下图所示,即效果同第三小节的方法内部类。

 

匿名内部类是一种特殊的内部类,这种类没有名字,通过new关键字直接创建某一个类的匿名子类的对象来使用。

以下情况需要用到匿名类:

  1. 只用到类的一个实例。
  2. 类在定义后马上用到。
  3. 类非常小,通常5行代码之内。
  4. 给类命名不会导致代码更容易被理解。

但是需要注意:匿名内部类不能定义构造方法,并且功能上会受到很大的限制,如果不是很有必要,尽量不要去使用

 


三、总结

 

以上就是Java四种内部类的常见用法。


1.成员内部类,就是内部类作为一个成员,存在于类中。

实例化方法:   外部类.内部类 内部类对象 = new 外部类().new 内部类();


2.静态内部类,在成员内部类的基础上,多了一个static关键字,是静态的类,所有的对象都可以直接通过类名调用。

实例化方法:   内部类 内部类对象 = new new 内部类();


3.方法内部类,在类的方法中,定义内部类。

实例化方法:   new 内部类().内部类方法();   注意只能在当前方法中实例化。


4.匿名内部类,直接new一个没有名字的类,并且直接调用其中的方法。

实例化方法:    new 内部类(){ ...... }.内部类中的方法();


参考文献:《Java语言面向对象程序设计(第二版)》 清华大学出版社

原文地址:https://www.cnblogs.com/yyzwz/p/13393207.html