当前位置: 首页 > 编程笔记 >

Java 中引入内部类的意义?

富波光
2023-03-14
本文向大家介绍Java 中引入内部类的意义?,包括了Java 中引入内部类的意义?的使用技巧和注意事项,需要的朋友参考一下

前言

这是个好问题,因为它让我想起来自己刚学到内部类时候的“想用的冲动”。

导致我代码里到处都是层层的内部类套嵌。不但经常搞得静态域错误一堆(内部类不允许有static成员字段),而且过一段时间自己都搞不清当初写的是什么。

一个很重要的设计准则是:设计是做减法,能不用模式就不用模式。

这个准则对内部类来说同样适用。

所以回答这个问题的基调应该是:

能不用内部类就不用内部类。

实践

我以前觉得内部类用来有针对性地暴露外部类的特定接口,比一下子把整个对象都给人家要好。比如说下面代码中的外部类Outer实现了三个接口方法,能跑,能飞,能思考。然后有三个方法getRunner(),getFlyer(),getThinker()有针对性地对外暴露部分功能接口。

 public interface Runnable{ public void run(); } public interface Flyable{ public void fly(); } public interface Thinkable{ public void think(); } public class Outer{
 public void run(){ //do something } 
 public void fly(){ //do something }
 public void think(){ //do something } 
public class Runner implements Runnable{ 
public void run(){Outer.this.run();} } 
public class Flyer implements Flyable{ 
public void fly(){Outer.this.fly();} } 
public class Thinker implements Thinkable{ 
public void think(){Outer.this.think();} } 
public Runner getRunner(){return new Runner();} public Flyer getFlyer(){return new Flyer();} 
public Thinker getThinker(){return new Thinker();} } 

但实际上直接实现三个接口不是就很好嘛。用内部类根本算不上优雅,多了很多代码。仅仅为了暴露接口根本不需要使用内部类。

public interface Runnable{ public void run(); } public interface Flyable{ public void fly(); } public interface Thinkable{ public void think(); } public class Outer implements,Runnable,Flyable,Thinkable{ 
public void run(){ //do something } 
public void fly(){ //do something } 
public void think(){ //do something } } 

再或者说常见的控制框架。我们定义个Event接口,必须有action()方法。在外部类里定义事件处理的流程。然后定义了几个实现Event接口的内部类。

public interface Event{ public void action(); } public class Controller{ 
private int id; 
private List<Event> list=new ArrayList<Event>(); 
public void prepare(){ //put new events into the list } 
public void doEvents(){ //do every events in the list } 
public class A implements Event{ 
public void action(){ //do something } } 
public class B implements Event{ 
public void action(){ //do something } } } 

但这也不是非内部类不可。独立定义A,B类,最后再把Event对象组合到Controller里完全可以,而且更简洁易读。

另外,说到内部类,经常会提到闭包,回调。但内部类也不是唯一的方案。简单的继承,组合都能实现同等的数据封装效果。

但Java到底需不需要内部类?答案还是需要的。Java引入内部类的真正意义就在于,还是有很多情况,没有内部类是处理不了的,或者用内部类处理起来更加优雅。

还是第一个例子。如果外部类不止有一种接口实现方法。如果我实现了Runnable接口,就只能定义一个run()方法。这时候内部类就派用场了。比如,企鹅既会跑,又会游泳。所以它的两个内部类实现两种不同的run()。可以返回两种不同的Runnable引用。

public interface Runnable{ public void run(); } public class Penguin{ 
public void run(){ //do something } 
public void swim(){ //do something } 
public class Running implements Runnable{
 public void run(){Penguin.this.run();} } 
public class Swimming implements Runnable{ 
public void run(){Penguin.this.swim();} } 
public Runner getRunner(){return new Running();} public Flyer getSwimmer(){return new Swimming();} } 

另一种典型场景就是多继承。如果外部类已经继承了某个基类,比如说企鹅继承自鸟类。但Runnable这时候正好是一个abstract抽象类呢?Java不支持多继承,内部类可以解决这个问题。

public class Bird{ //some code here } 
public abstract class Runnable{ 
public abstract void run(); } 
public class Penguin extends Bird{ 
public class Runner extends Runnable{ //do something } 
public Runner penguinCanRun(){return new Runner();} } 

刚才提到了控制框架可以不用内部类。但实际上你看看事件驱动的Swing里到处都是内部类。为什么呢?因为有大量的事件,而且多数事件的相应方法只被用到了一次。用内部类是为了控制类的数量,考虑的是更好地封装。

内部类另外一个好的特性就是它独立于外部类,不会像组合一样随着外部类的初始化而一起被初始化。而是在我们需要它的时候再创建它。比如说容器里的迭代器,需要我们手动创建。作为可选组件存在于外部类中,不会增加外部类的负担。

总之,要知道什么时候真正需要内部类,先要搞清楚什么时候可以不用内部类。内部类不是大力丸,不要滥用内部类

 类似资料:
  • 我在学习Java中读到关于内部班级的文章。我找到了这个密码 编译后,javap的动物$Brain输出为 这解释了内部类如何在内部类构造函数中获取对其封闭实例的引用。但是当我像这样将内部类定义为private时 然后编译后,javap'动物$Brain'给出输出为 那么为什么输出不同呢?为什么没有显示内部类构造函数?在后一种情况下,内部类也获得了封闭类实例的引用。

  • 问题内容: 我有以下Java代码: 得出666和999。现在,我尝试在c#中设置类似的代码,但是似乎无法完成相同的工作。如果是这样,用c#编程时通常如何达到类似的效果? 问题答案: 您需要使内部类将外部类的实例作为构造函数参数。(这是Java编译器实现内部类的方式)

  • 本节我们将介绍 Java 中的内部类。通过本节的学习,我们将了解到什么是内部类,内部类的分类和作用。在内部类的分类部分,我们将逐一学习各个类型的内部类如何定义,如何实例化以及各自的特点,要注意区分不同类型内部类的异同。有了这些基础知识之后,我们也会结合示例介绍为什么需要内部类。 1. 概念 在 Java 语言中,可以将一个类定义在另一个类里面或者一个方法里面,我们把这样的类称为内部类。 与之对应的

  • 局部内部类是指在一个方法中定义的内部类。示例代码如下: 局部内部类有如下特点: 1)局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。 2)局部内部类只在当前方法中有效。 3)局部内部类中不能定义 static 成员。 4)局部内部类中还可以包含内部类,但是这些内部类也不能使用访问控制修饰符(public、priv

  • 问题内容: 这就是我现在正在做的。有没有更好的方法来访问超类? 我正在使用Google Web Toolkit进行编程,但是我认为这确实是一个通用的Java问题。 问题答案: 您可以使用所谓的qualified 。 [JLS 15.8.4。合格的](http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.8

  • 本文向大家介绍深入理解Java嵌套类和内部类,包括了深入理解Java嵌套类和内部类的使用技巧和注意事项,需要的朋友参考一下  一、什么是嵌套类及内部类 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。嵌套类从JDK1.1开始引入。其中inner类