Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OOP:有没有哪种习惯用法可以简化界面提取和减少冗长的自动转发?_Java_Oop_Inheritance_Lisp_Composition - Fatal编程技术网

Java OOP:有没有哪种习惯用法可以简化界面提取和减少冗长的自动转发?

Java OOP:有没有哪种习惯用法可以简化界面提取和减少冗长的自动转发?,java,oop,inheritance,lisp,composition,Java,Oop,Inheritance,Lisp,Composition,编辑 尽管我在下面使用了伪Java语法进行说明,但这个问题并不局限于任何一种编程语言。请随意发布您喜爱的编程语言中的惯用语或语言提供的机制 当试图通过组合而不是继承重用现有类时,Old,首先从现有类手动创建一个新接口,然后在new中编写转发函数是非常繁琐的。如果Old中有大量的公共方法,而您只需要覆盖其中的一小部分,那么这个练习就变得特别浪费 忽略像Eclipse这样的IDE,虽然可以帮助完成这个过程,但仍然不能减少需要读取和维护的代码的冗长程度,如果有两种语言机制来 自动提取Old的公共方法

编辑

尽管我在下面使用了伪Java语法进行说明,但这个问题并不局限于任何一种编程语言。请随意发布您喜爱的编程语言中的惯用语或语言提供的机制


当试图通过组合而不是继承重用现有类时,
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
    )中将冗长程度降至最低

  • 是否有其他提供此类机制的语言

  • 编辑

    现在,我不知道这些语言的细节,但我希望像Scheme、Lisp、Clojure这样的“Lispy”语言不会在这里让人失望。。。毕竟,forlisp是一种“可编程编程语言”(根据paulgraham和其他人的说法)

    编辑2


    我可能不是
    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来判断他是否有帮助。这是一个