我希望我能得到一些关于这个问题的澄清。所以一个类的层次结构是这样的:抽象类,具体类1和具体类2。ConcreteClass1扩展了AbstractClass, ConcreteClass2扩展了ConcreteClass1:
ConcreteClass1中的构造函数如下:
private final AbstractClass parent;
public ConcreteClass1( int id, AbstractClass aParent )
{
super( id );
parent = aParent;
}
我想知道在什么情况下这可能有用。我不知道如何ConcreteClass1可以实例化,除非null被传递给父参数。在ConcreteClass2中使用了类似的构造函数(也就是说,它也有一个AbstractClass类型的参数)。
这是一个合理的设计吗?
在任何层次结构或继承类型布局中都特别有用。
例如,假设鼠标单击GUI元素。假设你的类有一个方法
handleClick(int x, int y);
第一次点击可以由底层组件处理,拥有父组件允许结构将点击传递给父组件。这类似于向上链接方法/事件。
或者,这也可以由一些外部控制器来完成,该控制器管理click方法被调用的元素,但它可能比只使用父模型更复杂,或者更不干净(尽管并不总是)。
在这种类型的模型中,只有当"parent"是顶层元素时,它才会为null,其余的元素都将使父元素更接近顶部。
是的,你第一次想要获得一个实例,你必须传递null
,但在随后的时间你可以传递一个以前创建的实例。
这是非常常见的,在许多框架和库中使用,例如Qt的QObject
是这样的,目的是创建一个运行时实例的分层树。很明显,这个树的根不能也不应该有父节点。
EDIT:只是给一个实际的例子,左边的树是你的类继承树,右边的树是一个运行时对象树的例子。注意实例可以是AbstractClass
的任何子类。
(CC1表示ConcreteClass
, CC2表示ConcreteClass2
)
AbstractClass X (NULL)
| |
| |
ConcreteClass1 root:CC1
| /
| /
ConcreteClass2 ins2:CC2 ins3:CC1
| /
| /
ins4:CC1 ins5:CC2 ins6:CC2
... ... ...