开发者

is this possible in java or any other programming language

public abstract class Master
{
    public void printForAllMethodsInSubClass()
    {
        System.out.println ("Printing before subclass method executes");
            Syste开发者_高级运维m.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;
    }
}

Without messing with methods of subclass...is it possible to execute printForAllMethodsInSubClass() before the method of a subclass gets executed?

update:

Using AspectJ/Ruby/Python...etc Would it also be possible to print the parameters? Above code formatted below:

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


AspectJ can provide this functionality for you, but it's a separate compilation step and some extra libraries involved.

public aspect ServerLogger {
    pointcut printSomething ();

    before(): printSomething()
    {
            (Master)(thisJoinPointStaticPart.getTarget()).printForAlMethodsInSubClass();
    }
}

The Eclipse Project provides a great implementation of AspectJ that integrates nicely with Eclipse and Maven. There's a boatload of great documentation available for it, and a lot of really good material for it here on StackOverflow.

[update]

To access parameter info, you can use the

thisJoinPoint.getSignature(); 

method to access information about the function being called if the returned Object is an instance of MethodSignature, you can use Signature.getParameterNames() to access the parameters to the function being called. You'd have to use a bit of reflection to actually get at the values, I think - AspectJ doesn't seem to handle this for you. I'd have to actually do some experimentation to get some working code for you.


To answer the "any other programming language": It's easily possible in 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

You could also make a proxy declaration method to use in subclasses:

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

(This approach would also translate very naturally to Python decorators.)


This is possible in aspect-oriented programming languages, such as AspectJ.


In Python you can accomplish this using meta classes, here's a small example. You can probably make it more elegantly but it is just to make the point

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

In this example, the PrintMetaClass gets in the way of the creation of the Foo class and any of its subclasses redefining every method to be a wrapper of the original and printing a given message at the beginning. The Bar class receives this aspect-like behavior simply by inheriting from Foo which defines its __metaclass__ to be PrintMetaClass.

Metaclasess in OOP:

  • http://en.wikipedia.org/wiki/Metaclass

Metaclasses in python:

  • http://www.python.org/doc/essays/metaclasses/
  • http://www.ibm.com/developerworks/linux/library/l-pymeta.html


Besides aspect oriented programming have a look at Template Method Pattern, http://en.wikipedia.org/wiki/Template_method_pattern.

In short: the parent class have an abstract method, which subclasses have to implement, this abstract method is called by a method in the parent class where put your printouts or whatever necessary statements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜