简体   繁体   中英

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

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.)

这在面向方面的编程语言(例如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:

Metaclasses in python:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM