Java OOP:有没有哪种习惯用法可以简化界面提取和减少冗长的自动转发?
编辑 尽管我在下面使用了伪Java语法进行说明,但这个问题并不局限于任何一种编程语言。请随意发布您喜爱的编程语言中的惯用语或语言提供的机制Java OOP:有没有哪种习惯用法可以简化界面提取和减少冗长的自动转发?,java,oop,inheritance,lisp,composition,Java,Oop,Inheritance,Lisp,Composition,编辑 尽管我在下面使用了伪Java语法进行说明,但这个问题并不局限于任何一种编程语言。请随意发布您喜爱的编程语言中的惯用语或语言提供的机制 当试图通过组合而不是继承重用现有类时,Old,首先从现有类手动创建一个新接口,然后在new中编写转发函数是非常繁琐的。如果Old中有大量的公共方法,而您只需要覆盖其中的一小部分,那么这个练习就变得特别浪费 忽略像Eclipse这样的IDE,虽然可以帮助完成这个过程,但仍然不能减少需要读取和维护的代码的冗长程度,如果有两种语言机制来 自动提取Old的公共方法
当试图通过组合而不是继承重用现有类时,
Old
,首先从现有类手动创建一个新接口,然后在new
中编写转发函数是非常繁琐的。如果Old
中有大量的公共方法,而您只需要覆盖其中的一小部分,那么这个练习就变得特别浪费
忽略像Eclipse这样的IDE,虽然可以帮助完成这个过程,但仍然不能减少需要读取和维护的代码的冗长程度,如果有两种语言机制来
Old
的公共方法,例如,通过操作员的接口;及
Old
接口方法(例如,通过forwardsTo
操作符)转发到Old
的组合实例,您只提供希望在New
中覆盖的少数方法的定义// A hypothetical, Java-like language
class Old {
public void a() { }
public void b() { }
public void c() { }
private void d() { }
protected void e() { }
// ...
}
class New implements interfaceOf Old {
public New() {
// This would auto-forward all Old methods to _composed
// except the ones overridden in New.
Old forwardsTo _composed;
}
// The only method of Old that is being overridden in New.
public void b() {
_composed.b();
}
private Old _composed;
}
我的问题是:
New
和类(如New
)中将冗长程度降至最低我可能不是
Old
的作者,也可能不想更改其源代码,实际上是想将其用作黑盒。这可以通过允许您指定一个“一网打尽”的神奇方法的语言来实现(例如,php中的\u call()
)。您可以在这里捕获任何未明确重写的函数调用,检查它是否存在于类Old
中,如果存在,只需转发调用即可
大概是这样的:
public function __call($name, $args)
{
if (method_exists($old, $name))
{
call_user_func([$obj, $name], $args);
}
}
我认为Go有这样一种机制,一个结构可以嵌入来自另一个结构的方法 看一看。这可能是您要问的第二个问题。首先,在“面向类”语言的上下文中回答设计问题: 如果您真的需要在使用它的任何地方用它的完整接口
IOld
替换旧的
,只是为了使实现IOld
的新的
,表现得像您想要的那样,那么您实际上应该使用继承
如果您只需要IOld
的一小部分用于New
,那么您应该只将该部分放入接口ICommon
,并让Old
和New
实现它。在这种情况下,只有在Old
和New
都有意义的情况下,才将Old
替换为ICommon
其次,在这种情况下,Common Lisp能为您做些什么?
CommonLisp与Java和其他面向类的语言非常不同
只有几个指针:在公共Lisp中,对象主要用于数据的结构和分类,而不是代码。您在这里找不到“每个文件一个类”、“每个类一个文件”或“包名完全对应于目录结构”。方法不“属于”类,而是属于泛型函数,泛型函数的唯一职责是根据其参数的类进行调度(这有一个很好的副作用,即支持无缝的多重调度)。有多重继承。没有这样的接口。有一种更强烈的倾向,即使用包来实现模块化,而不仅仅是组织类。导出哪些符号(Java术语中的“public”)是按包定义的,而不是按类定义的(这显然与上述内容无关)
我认为您的问题要么在公共Lisp环境中完全消失,因为您的代码没有强制进入类结构中,要么非常自然地通过多次分派和/或(可能是多次)继承来解决或表达
人们需要至少一个完整的例子和周围系统的大部分来尝试翻译成常见的Lisp习语。您编写的代码差别如此之大,以至于尝试几种形式的一对一翻译没有任何意义。“Lisp”通常不是一种基于类的面向对象语言,而是一种编程语言家族,主要结合了命令式、过程式和函数式风格。有些Lisp,比如Common Lisp,具有面向对象的功能,但是如果您对此有真正的疑问,那么您应该问一个特定的问题。就目前而言,OO之间存在巨大差异,这使得答案不是很有用,也无法解决您在Java中遇到的问题。如果可以用Java做一些事情,那就太好了,但我并不是专门寻找Java解决方案——Common Lisp应该很好。我记得Paul Graham在他的ACL书中提到ACL支持“开箱即用”的编程范式,如OOP、AOP等,不需要在编译器级别进行语言扩展。我不知道的是,上述用例是否由公共Lisp(或任何其他类似的Lisp)或其他语言支持。因此,问题就来了。你想解决哪一个真正的问题?了解CommonLisp并没有帮助。通用Lisp中的OOP与Java的工作方式不同。提示:使用Smalltalk。请让OP来判断他是否有帮助。这是一个