在Ruby中,我想实现像这样的Java样本:
class A {
private void f() { System.out.println("Hello world"); }
public void g() { f(); }
}
class B extends A {
public void f() { throw new RuntimeException("bad guy");}
}
public class Try {
public static void main(String[] args) { new B().g();}
}
这将在Java中打印“Hello world”,但是直接的Ruby转录本:
class A
def g; f; end
private
def f; puts "Hello world"; end
end
class B < A
def f; raise "bad guy"; end
end
B.new.g # want greet
当然会引发一个坏人 - 由于方法查找机制的差异(我意识到'私人'的含义在这些语言之间是非常不同的)
有没有办法达到类似的效果? 我真的不关心可见性,实际上更喜欢这里的所有公共方法。 我的目标只是将超类中的方法与覆盖子类中的方法隔离开来(这会破坏其他基本方法)。
我想如果有一个解决方案,那也适用于modules / includes吗?
module BaseAPI
def f; puts "Hello world"; end
def g; f; end;
end
module ExtAPI
include BaseAPI
# some magic here to isolate base method :f from the following one?
def f; raise "bad guy"; end # could actually be something useful, but interfering with base 'g'
end
include ExtAPI
g # want greet
后续行动:这看起来是一种罕见的情况,可以用Java而不是Ruby: - /
答案 0 :(得分:0)
class A
def g
real_f
end
private
def f
real_f
end
def real_f
puts "Hello world"
end
end
class B < A
def f
raise "bad guy"
end
end
B.new.g # want hello world
我觉得这些明显的答案不是你想要的。 Ruby只是没有强制机制。但仅仅为了记录,我们可以构建一个替代类AA。你甚至可以比这更聪明,并使用method_missing()动态插入别名方法。
class A
def g
f
end
def f
puts "Hello world"
end
end
class AA
def initialize
@x = A.new
end
def g
@x.g
end
def f
@x.f
end
end
class B < AA
def f
raise "bad guy"
end
end
B.new.g # want hello world
答案 1 :(得分:-1)
class A; def g;f;end ; private ;def f;puts "Hello world";end;end
class B < A
def self.method_added(name)
if superclass.method_defined? name or superclass.private_method_defined? name
raise "A trial to add a new instance method: #{name}, this is not allowed."
end
end
def f;raise "bad guy";end;
end
#=>`method_added': A trial to add a new instance method: f,
# this is not allowed.(RuntimeError)