это возможно в Java или любом другом языке программирования - PullRequest
0 голосов
/ 08 марта 2010
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 ]

6 голосов
/ 08 марта 2010

AspectJ может предоставить вам эту функцию, но это отдельный этап компиляции и некоторые дополнительные библиотеки.

public aspect ServerLogger {
    pointcut printSomething ();

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

Проект Eclipse предоставляет отличную реализацию AspectJ, которая прекрасно интегрируется с Eclipse и Maven. Для этого есть множество отличной документации и множество действительно хороших материалов для этого здесь, на StackOverflow.

[обновление]

Для доступа к информации о параметре вы можете использовать

thisJoinPoint.getSignature(); 

метод для доступа к информации о вызываемой функции, если возвращаемый объект является экземпляром MethodSignature , вы можете использовать Signature.getParameterNames () для доступа к параметрам вызываемой функции. Я думаю, что вам придется немного подумать, чтобы на самом деле получить значения - AspectJ, похоже, не справится с этим для вас. Мне бы пришлось провести эксперименты, чтобы получить рабочий код для вас.

2 голосов
/ 08 марта 2010

Чтобы ответить на «любой другой язык программирования»: это легко возможно в 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.)

1 голос
/ 08 марта 2010

Это возможно в аспектно-ориентированных языках программирования, таких как AspectJ .

0 голосов
/ 08 марта 2010

Помимо аспектно-ориентированного программирования, взгляните на Pattern Template Pattern, http://en.wikipedia.org/wiki/Template_method_pattern.

Вкратце: у родительского класса есть абстрактный метод, который должны реализовать подклассы, этот абстрактный метод вызывается методом из родительского класса, в который помещаются ваши распечатки или любые другие необходимые операторы.

0 голосов
/ 08 марта 2010

В 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:

Метаклассы в Python:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...