我想问你为什么我们需要内部类以及为什么要使用它们?
我知道如何使用内部类,但我不知道为什么......
答案 0 :(得分:11)
一些内部类被公开暴露(例如Java中的Map.Entry
),但这是迄今为止的例外而非常态。
内部类基本上是一个实现细节。
例如,Swing广泛使用事件侦听器的内部类。如果没有它们,你最终会用一堆你不需要看的类来污染全局命名空间(这可能会使它们的目的更难确定)。
本质上,内部类是范围的一种形式。包访问会从包外部隐藏类。私有内部类将该类隐藏在该类之外。
Java中的内部类也可以替代缺少函数指针或方法委托(在C#中)或闭包。它们是将函数传递给另一个函数的手段。例如,在您拥有的Executor
班级中:
void execute(Runnable r);
所以你可以传入一个方法。在C / C ++中可以通过以下方式实现:
void execute(void (*run)());
是指向函数的指针。
答案 1 :(得分:3)
Java中的匿名内部类是一种使用适配器模式的方法。
interface Bar
{
public void bar();
}
class Foo
{
public void foo()
{
// do something relevant
}
// it happens that foo() defines the same contract (or a compatible one) as
// Bar.bar(); with an anonymous inner class we can adapt Foo to the Bar
// interface
public Bar asBar()
{
// return an instance of an anonymous inner class that implements
// the Bar inteface
return new Bar()
{
public void bar()
{
// from an inner class, we can access the enclosing class methods
// as the "this pointers" are "linked"
foo();
}
};
}
}
在Java中,请确保您了解difference between inner classs and nested class:
内部类与a相关联 封闭类的实例和 可以直接访问该对象 方法和领域
C#没有Java的内部类,只有嵌套类。
答案 2 :(得分:3)
大多数时候我使用内部类是因为内部类与其他语言中可用的closure概念最接近。这样可以创建和使用内部嵌套作用域的对象,该对象可以访问其外部作用域的变量。这通常用于创建回调(例如,在Swing中定义各种Listener
)等。
答案 3 :(得分:3)
来自wikipedia的这篇文章可能会帮助你理解为什么我们需要一个内部阶级:
普通或顶级类的实例可以存在于自己的上。相比之下,如果没有绑定到顶级类,则无法实例化内部类的实例。
让我们采用四轮汽车的抽象概念。我们的车轮具有特定的功能,依赖于我们的汽车的一部分。这个概念并不代表车轮作为可能是车辆一部分的更一般形式的车轮。相反,它代表它们特定于此。我们可以使用内部类对这个概念进行建模,如下所示:
我们有顶级的Car级。 Class Car的实例由Wheel类的四个实例组成。 Wheel的这种特殊实现特定于汽车,因此代码不会对车轮的一般概念进行建模,这将更好地表示为顶级车级。因此,它在语义上与Car类连接,而Wheel的代码在某种程度上与其外部类相关联。
内部类为我们提供了一种准确建模此连接的机制。我们说我们的轮子类是Car.Wheel,Car是顶级类,Wheel是内部类。
因此,内部类允许程序的某些部分的面向对象,否则这些部分将被封装到类中。
答案 4 :(得分:2)
我使用它们作为范围,例如,如果我有类电子书并且我有ebookPrice,我将ebookPrice包含在电子书类之间,因为它与它相关并且只能在其中使用(至少在概念上)。
ebookPrice可以继承自Price的更高范围,并且与其他所有类相关。
(只是我的两分钱)。
答案 5 :(得分:2)
有些语言将内部课程带到了不同的级别,比如Beta和Newspeak。在这些语言中,类的嵌套用作包装(即没有包)。
为了更好地了解此愿景,请参阅对象团队博客上的"How many concepts for modules do we need?"。另见Gilad Bracha在his blog ...
上的工作