public abstract class Master
{
public void printForAllMethodsInSubClass()
{
System.out.println ("Printing before subclass method executes");
System.out.println ("Parameters for subclass method were: ....");
}
}
public class Owner extends Master {
public void printSomething () {
System.out.println ("This printed from Owner");
}
public int returnSomeCals ()
{
return 5+5;
}
}
不搞乱子类的方法......是否可以在子类的方法执行之前执行printForAllMethodsInSubClass()
?
更新
使用AspectJ / Ruby / Python等 是否也可以打印参数?以上格式如下:
public abstract class Master
{
public void printForAllMethodsInSubClass()
{
System.out.println ("Printing before subclass method executes");
}
}
public class Owner extends Master {
public void printSomething (String something) {
System.out.println (something + " printed from Owner");
}
public int returnSomeCals (int x, int y)
{
return x+y;
}
}
答案 0 :(得分:6)
AspectJ可以为您提供此功能,但它是一个单独的编译步骤,并涉及一些额外的库。
public aspect ServerLogger {
pointcut printSomething ();
before(): printSomething()
{
(Master)(thisJoinPointStaticPart.getTarget()).printForAlMethodsInSubClass();
}
}
Eclipse Project提供了一个很好的AspectJ实现,可以很好地与Eclipse和Maven集成。这里有很多很棒的文档,在StackOverflow上有很多非常好的材料。
[更新]
要访问参数信息,您可以使用
thisJoinPoint.getSignature();
如果返回的Object是MethodSignature的实例,则访问有关被调用函数的信息的方法,您可以使用Signature.getParameterNames()来访问被调用函数的参数。你必须使用一些反射来实际获得值,我认为 - AspectJ似乎并没有为你处理这个问题。我必须做一些实验来为你获得一些有用的代码。
答案 1 :(得分:2)
回答“任何其他编程语言”:在Ruby中很容易实现:
class Master
REDEFINED = []
def printForAllMethodsInSubClass
puts 'Printing before subclass method executes'
end
def self.method_added(meth)
if self < Master and not Master::REDEFINED.include? meth
new_name = "MASTER_OVERRIDE_#{meth}".intern
Master::REDEFINED.push meth, new_name
alias_method new_name, meth
define_method(meth) {|*args| printForAllMethodsInSubClass; send(new_name, *args)}
end
end
end
您还可以在子类中使用代理声明方法:
class Master
def printForAllMethodsInSubClass
Printing before subclass method executes
end
def self.master_method(name)
define_method(name) {|*args| printForAllMethodsInSubClass; yield *args}
end
end
class Owner
master_method(:print_something) do
puts "This was printed from Owner"
end
end
(这种方法也很自然地转换为Python装饰器。)
答案 2 :(得分:1)
这在面向方面的编程语言中是可行的,例如AspectJ。
答案 3 :(得分:0)
在Python中,您可以使用元类来完成此操作,这是一个小例子。你可以把它做得更优雅,但这只是为了说明点
import types
class PrintMetaClass(type):
def __init__(cls, name, bases, attrs):
# for every member in the class
override = {}
for attr in attrs:
member = attrs[attr]
# if it's a function
if type(member) == types.FunctionType:
# we wrap it
def wrapped(*args, **kwargs):
print 'before any method'
return member(*args, **kwargs)
override[attr] = wrapped
super(PrintMetaClass, cls).__init__(name, bases, attrs)
for attr in override:
setattr(cls, attr, override[attr])
class Foo:
__metaclass__ = PrintMetaClass
def do_something(self):
print 2
class Bar(Foo):
def do_something_else(self):
print 3
在这个例子中,PrintMetaClass
阻碍了Foo
类的创建,并且它的任何子类重新定义了每个方法,使其成为原始包装,并在开始。 Bar
类只需从Foo
继承,将__metaclass__
定义为PrintMetaClass
即可获得类似方面的行为。
OOP中的Metaclasess:
python中的元类:
答案 4 :(得分:0)
除面向方面编程外,还要看模板方法模式http://en.wikipedia.org/wiki/Template_method_pattern。
简而言之:父类有一个抽象方法,子类必须实现,这个抽象方法由父类中的方法调用,在那里放置你的打印输出或任何必要的语句。