这是可能的java或任何其他编程语言

时间:2010-03-08 17:58:58

标签: java programming-languages

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;
    }
}

5 个答案:

答案 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

简而言之:父类有一个抽象方法,子类必须实现,这个抽象方法由父类中的方法调用,在那里放置你的打印输出或任何必要的语句。