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

简介: 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的你,真的会面向对象编程吗?》详细讲解了。

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

1. public class People {
2. 
3.  String userName;
4.  int userAge;
5. 
6.  void say() {
7.    System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
8.  }
9. }

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

 

1.2 封装类

 

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

1. public class People {
2. 
3.  private String userName;
4.  private int userAge;
5. 
6.  public void say() {
7.    System.out.println("The people " + this.userName + " is "+ this.userAge + " years old!");
8.  }
9. 
10.   public String getUserName() {
11.     return userName;
12.   }
13.   public void setUserName(String userName) {
14.     this.userName = userName;
15.   }
16.   public int getUserAge() {
17.     return userAge;
18.   }
19.   public void setUserAge(int userAge) {
20.     this.userAge = userAge;
21.   }
22. }

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

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

 


二、内部类

 

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

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

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

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

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

 


2.1 成员内部类

 

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

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

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

1. public class People {
2. 
3.  class Book{
4.    String bookName;
5. 
6.    Book(String bookName){
7.      this.bookName = bookName;
8.    }
9. 
10.     void open() {
11.       System.out.println("The " + this.bookName + " was opened!");
12.     }
13.   }
14. }

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

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

实际代码如下:

1. public class Main {
2. 
3.  public static void main(String[] args) {
4.    People.Book book = new People().new Book("Java程序设计"); 
5.    book.open();
6.  }
7. }

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

 


2.2 静态内部类

 

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

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

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

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

1. static class Book{
2.  String bookName;
3. 
4.  Book(String bookName){
5.    this.bookName = bookName;
6.  }
7. 
8.  void open() {
9.    System.out.println("The " + this.bookName + " was opened!");
10.   }
11. }

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

1. import cn.zwz.People.Book;
2. 
3. public class Main {
4. 
5.  public static void main(String[] args) {
6.    Book book = new Book("Java程序设计"); 
7.    book.open();
8.  }
9. }

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


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

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

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

1. public class People {
2. 
3.  public void say(String issue) {
4.    class Issue {
5.      public void speakIsser() {
6.        System.out.println("My issues is " + issue);
7.      }
8.    }
9.    new Issue().speakIsser();
10.   }
11. }

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

1. public class Main {
2. 
3.  public static void main(String[] args) {
4.    People people = new People();
5.    people.say("Hello ZWZ!");
6.  }
7. }

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

 


2.4匿名内部类

 

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

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

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

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

代码如下所示:

1. interface Issue{
2.  public void speakIsser();
3. }
4. public class People {
5. 
6.  public void say(String issue) {
7.    new Issue() {
8.      public void speakIsser() {
9.        System.out.println("My issues is " + issue);
10.       }
11.     }.speakIsser();
12.   }
13. }

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

1. public class Main {
2. 
3.  public static void main(String[] args) {
4.    People people = new People();
5.    people.say("Hello ZWZ!");
6.  }
7. }

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

 

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

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

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

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

 


三、总结

 

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


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

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


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

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


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

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


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

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


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


相关文章
|
2月前
|
Java 编译器
【Java】内部类
【Java】内部类
22 0
|
4月前
|
Java
【Java基础面试二】、个Java文件里可以有多个类吗(不含内部类)?
这篇文章讨论了Java文件中类的定义规则,指出一个Java文件可以包含多个类(不包含内部类),但其中最多只能有一个public类,且如果有public类,它的名称必须与文件名一致。
|
4月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
38 5
|
5月前
|
Java
Java进阶之内部类
【7月更文挑战第13天】Java内部类增进代码组织与封装,允许直接访问外部类成员,包括私有成员。主要有四种类型:成员、静态、局部和匿名内部类。匿名内部类常用于一次性实现接口或扩展类。内部类可隐藏实现细节,减少命名冲突,并在特定上下文中定义辅助类。示例展示了静态和非静态内部类如何在Shape类中封装Circle和Rectangle。使用内部类能提升代码可读性,但可能增加复杂性。
39 6
|
4月前
|
Java
【Java】内部类、枚举、泛型
【Java】内部类、枚举、泛型
|
6月前
|
Java
一篇文章讲明白Java中内部类详解—匿名内部类
一篇文章讲明白Java中内部类详解—匿名内部类
95 2
|
6月前
|
设计模式 Java 编译器
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
Java中的内部类(如果想知道Java中有关内部类的知识点,那么只看这一篇就足够了!)
|
6月前
|
Java 编译器
24. 【Java教程】内部类
24. 【Java教程】内部类
30 2
|
7月前
|
Java 程序员
Java的内部类与匿名类的技术性文章
Java的内部类与匿名类的技术性文章
44 1
|
7月前
|
Java
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)
58 3