为了澄清,我要问的是
public class A{
private/*or public*/ B b;
}
与
public class A{
private/*or public*/ class B{
....
}
}
我绝对可以考虑使用其中一个的某些原因,但我真正想看到的是令人信服的示例,这些示例表明了利弊不只是学术上的。
为了澄清,我要问的是
public class A{
private/*or public*/ B b;
}
与
public class A{
private/*or public*/ class B{
....
}
}
我绝对可以考虑使用其中一个的某些原因,但我真正想看到的是令人信服的示例,这些示例表明了利弊不只是学术上的。
Answers:
假设您正在构建树,列表,图等。为什么要向外部世界公开节点或单元的内部细节?
使用图形或列表的任何人都应该仅依赖于其接口,而不是其实现,因为您可能希望将来有一天将其更改(例如,从基于数组的实现更改为基于指针的实现),而使用您的客户端数据结构(每个)都必须修改其代码,以使其适合新的实现。
相反,将节点或单元的实现封装在私有内部类中,可以让您自由地在需要时随时修改实现,而不会迫使客户端相应地调整其代码,只要数据结构的接口保持不变即可。无动于衷。
隐藏数据结构的实现细节也会带来安全优势,因为如果您要分发类,则只会使接口文件与已编译的实现文件一起可用,而没人会知道您是否在实际使用数组或指针的实现,从而保护您的应用程序免受某种形式的利用或至少由于不当使用或检查您的代码而导致的知识。除了实际问题之外,请不要低估这种情况下这是一个非常优雅的解决方案。
我认为将内部定义的类用于在类中短暂使用以允许特定任务的类是公平的。
例如,如果您需要绑定由两个不相关的类组成的数据列表:
public class UiLayer
{
public BindLists(List<A> as, List<B> bs)
{
var list = as.ZipWith(bs, (x, y) => new LayerListItem { AnA = x, AB = y});
// do stuff with your new list.
}
private class LayerListItem
{
public A AnA;
public B AB;
}
}
如果您的内部类被另一个类使用,则应将其分开。如果内部类包含任何逻辑,则应将其分开。
基本上,我认为它们非常适合在数据对象中插入漏洞,但是如果它们实际上必须包含逻辑,则很难维护它们,因为如果需要更改它们,则必须知道在哪里寻找它们。
tuple.ItemX
会使代码不清楚。
我避免使用Java中的内部类,因为在存在内部类的情况下热交换不起作用。我讨厌这个,因为我真的不愿意出于这样的考虑而折衷代码,但是那些Tomcat重新启动加起来了。
使用私有内部类的原因之一可能是因为您使用的API需要从特定类继承,但是您不想将该类的知识导出给外部类的用户。例如:
// async_op.h -- someone else's api.
struct callback
{
virtual ~callback(){}
virtual void fire() = 0;
};
void do_my_async_op(callback *p);
// caller.cpp -- my api
class caller
{
private :
struct caller_inner : callback
{
caller_inner(caller &self) : self_(self) {}
void fire() { self_.do_callback(); }
caller &self_;
};
void do_callback()
{
// Real callback
}
caller_inner inner_;
public :
caller() : inner_(*this) {}
void do_op()
{
do_my_async_op(&inner_);
}
};
在这种情况下,do_my_async_op要求将回调类型的对象传递给它。此回调具有API使用的公共成员函数签名。
当从external_class调用do_op()时,它将使用私有内部类的实例,该实例从所需的回调类继承,而不是指向其自身的指针。外层类有一个对外层类的引用,其简单目的是将回调转移到外层类的私有 do_callback成员函数中。
这样做的好处是,您确保没有其他人可以调用公共的“ fire()”成员函数。
根据Depth的C#中的Jon Skeet的说法,使用嵌套类是实现完全惰性的线程安全单例(请参阅第5版)(直到.NET 4)的唯一方法。
私有类和内部类用于提高封装级别并隐藏实现细节。
在C ++中,除了私有类外,通过实现类cpp的匿名名称空间也可以实现相同的概念。这很好地用于隐藏/私有化实现细节。
它与内部或私有类具有相同的想法,但是在更高的封装级别上,因为它在文件的编译单元外部是完全不可见的。它的任何内容都不会出现在头文件中,也不会在类的声明中向外显示。