Терпите меня ... Я не думаю, что это слишком субъективно, но, возможно, я ошибаюсь.
Недавно я хотел выделить некоторый повторяющийся код, который рисовал пользовательский фон Bitmap в нашем приложении BlackBerry.
(Хотя этот вопрос на самом деле не касается BlackBerry, поэтому я приведу здесь некоторые подробности о графическом интерфейсе BB, чтобы люди не-BB Java могли взвесить ...)
Класс FullScreen из BB API - у него есть метод paint (Graphics), который фреймворк вызывает для рисования экрана и любых добавляемых к нему компонентов. Это можно переопределить, чтобы выполнить пользовательское рисование - например, рисование растрового фона до того, как произойдет любое другое рисование (более новые API BB предоставляют класс Background, но наше приложение должно работать на старых телефонах).
Я хотел, чтобы у меня было несколько экранов с одинаковым фоном, на каждом из которых была какая-то особенная картина ... вот что я придумал:
abstract public class BGFullScreen extends FullScreen {
Bitmap bg;
public BGFullScreen(Manager mgr, long style) {
super(mgr, style);
bg = Bitmap.getBitmapResource("bg.jpg");
}
abstract protected void innerPaint(Graphics g);
protected void paint(Graphics g) {
g.drawBitmap(new XYRect(0, 0, bg.getWidth(), bg.getHeight()), bg, 0, 0);
innerPaint(g);
super.paint(g);
}
}
Каждый экран затем подклассирует этот абстрактный класс и реализует innerPaint (). Таким образом, когда фреймворк BB вызывает метод paint (), на каждом экране могут быть пользовательские элементы рисования ПОСЛЕ рисования фона (так что любое рисование происходит поверх фона), но ДО создания компонентов экрана, когда выполняется FullScreen. вызывается paint ().
(Я придумал это, потому что я изучал Common Lisp дома, и мне пришло в голову, что я хотел сделать что-то вроде комбинации методов с чередованием в CLOS)
Вот пример реализации абстрактного класса выше:
public class MainAppScreen extends BGFullScreen {
public MainAppScreen() {
super(new VerticalFieldManager(), 0);
// add some components to the screen:
add(new ButtonField(...));
add(...)
}
protected void innerPaint(Graphics g) {
// stuff drawn will be on top of background and under buttons
g.draw(...)
}
}
По сути, я хочу, чтобы дочерний класс вызывал метод, вызываемый между реализацией его родителя и реализацией того же метода его прародителем. Я не мог найти другой способ сделать это на Java ...
Это идиоматическая Java? Это на самом деле очень часто, и это глупый вопрос? Это действительно ужасный дизайн? (Эксперты BB, как я могу сделать это по-другому?)
Отредактировано, чтобы добавить: Это работает как описано - рисунок происходит в порядке, который я хочу.