[ https://issues.apache.org/jira/browse/GROOVY-11627?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17951052#comment-17951052 ]
Jochen Theodorou edited comment on GROOVY-11627 at 5/15/25 10:47 AM: --------------------------------------------------------------------- [~emilles] Long explanation: {code:Java} class A { def foo() {bar()} } class B extends A { def bar(){1} } assert new B().foo() == 1 {code} This means bar becomes callable if we work on an instance that implements bar(). The problem now comes from bar() not only being valid for a method bar that takes no arguments. It could be with varargs. But imagine bar would have an argument, then there are many many more possible matches. Let's say we have bar("m") and in B we have the public method bar(Object) and bar(String). Well, it is easy, we then call bar(String) as per "normal" method dispatch. But what if bar(String) is private and bar(Object) is not? If private methods are implementation detail, then this means they should not be visible to calls made from A, right? But to calls from B they must. But then again any class was supposed to be able to call a private method on B like a public method as long as the instance is exactly B. This would say it must be possible to call the private method from A. The whole thing looks maybe a bit strange, but think of this without public and private. Then the way Groovy does method dispatch means, any subclass can provide a more specific method causing that method been used instead. Example: {code:Java} class A { def dispatch(x){m(x)} def m(x) {"object case"} } class B extends A { def m(String x) {"string case"} } def a = new A() assert a.dispatch(null) == "object case" assert a.m(null) == "object case" assert a.dispatch("string")== "object case" assert a.m("string") == "object case" def b = new B() assert b.dispatch(null) == "object case" assert b.m(null) == "object case" assert b.dispatch("string") == "string case" assert b.m("string") == "string case" {code} I hope that explains use and problem a bit. It should be clear that this is no feature for static compilation. was (Author: blackdrag): [~emilles] Long explanation: {code:Java} class A { def foo() {bar()} } class B extends A { def bar(){1} } assert new B().foo() == 1 {code} This means bar becomes callable if we work on an instance that implements bar(). The problem now comes from bar() not only being valid for a method bar that takes no arguments. It could be with varargs. But imagine bar would have an argument, then there are many many more possible matches. Let's say we have bar("m") and in B we have the public method bar(Object) and bar(String). Well, it is easy, we then call bar(String) as per "normal" method dispatch. But what if bar(String) is private and bar(Object) is not? If private methods are implementation detail, then this means they should not be visible to calls made from A, right? But to calls from B they must. But then again any class was supposed to be able to call a private method on B like a public method as long as the instance is exactly B. This would say it must be possible to call the private method from A. The whole thing looks maybe a bit strange, but think of this without public and private. Then the way Groovy does method dispatch means, any subclass can provide a more specific method causing that method been used instead. Example: {code:Java} class A { def dispatch(x){m(x)} def m(x) {"object case"} } class B extends A { def m(String x) {"string case"} } def a = new A() assert a.dispatch(null)c == "object case" assert a.m(null) == "object case" assert a.dispatch("string")== "object case" assert a.m("string") == "object case" def b = new B() assert b.dispatch(null) == "object case" assert b.m(null) == "object case" assert a.dispatch("string") == "string case" assert b.m("string") == "string case" {code} I hope that explains use and problem a bit. It should be clear that this is no feature for static compilation. > Compile Error when private and public functions use same name in compile > static mode > ------------------------------------------------------------------------------------ > > Key: GROOVY-11627 > URL: https://issues.apache.org/jira/browse/GROOVY-11627 > Project: Groovy > Issue Type: Bug > Components: Compiler, Static compilation > Affects Versions: 5.0.0-alpha-12 > Reporter: Saravanan > Assignee: Eric Milles > Priority: Minor > > When I define a class in Groovy with 2 methods with the same name, one > private and one public, I get this error during static compilation > {quote}Mixing private and public/protected methods of the same name causes > multimethods to be disabled and is forbidden to avoid surprising behaviour. > Renaming the private methods will solve the problem. > {quote} > I understand the need for multi methods and dispatching with runtime types, > but how can I disable this behaviour? I am using @CompileStatic and it still > hits this error > Per Jochen > {quote}CompileStatic does not support multi methods, so I totally agree that > this message should not appear for static compiled classes. > {quote} -- This message was sent by Atlassian Jira (v8.20.10#820010)