[英]Change instanceof to polymorphism
How to remove the operator "instanceof" and replace it with polymorphism? 如何删除运算符“ instanceof”并将其替换为多态? Both NamedPlace and DescribedPlace are subclasses to the main class Place.
NamedPlace和DescribedPlace都是主类Place的子类。
class RightClickListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent mev) {
p = (Place) mev.getSource();
if (mev.getModifiers() == InputEvent.BUTTON3_MASK) {
if (p instanceof NamedPlace) {
JOptionPane.showMessageDialog(null, p.getName() + " " + p.getPosition(), "Platsinfo: ", JOptionPane.INFORMATION_MESSAGE);
}
if (p instanceof DescribedPlace) {
JOptionPane describedPane = new JOptionPane();
describedPane.setMessage("Name: " + p.getName() + " " + p.getPosition() + "\n" + "Description: " + ((DescribedPlace) p).getDescription());
describedPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = describedPane.createDialog(p, "Platsinfo:");
dialog.setVisible(true);
}
}
}
}
You can give Place
the abstract method and add the implementation to the subclasses. 您可以给
Place
抽象方法,然后将实现添加到子类中。
abstract class Place {
// ..
public abstract void action();
}
class NamedPlace extends Place {
public void action() {
JOptionPane.showMessageDialog(null, p.getName() + " " + p.getPosition(), "Platsinfo: ", JOptionPane.INFORMATION_MESSAGE);
}
}
class DescribedPlace extends Place {
public void action() {
JOptionPane describedPane = new JOptionPane();
describedPane.setMessage("Name: " + p.getName() + " " + p.getPosition() + "\n" + "Description: " + ((DescribedPlace) p).getDescription());
describedPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = describedPane.createDialog(p, "Platsinfo:");
dialog.setVisible(true);
}
}
and then use this in the listener. 然后在侦听器中使用它。
class RightClickListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent mev) {
p = (Place) mev.getSource();
if (mev.getModifiers() == InputEvent.BUTTON3_MASK) {
p.action();
}
}
}
But, depending on what Place
is exactly, that might not be a good idea (eg if it's not a GUI class). 但是,根据
Place
的确切位置,这可能不是一个好主意(例如,如果它不是GUI类)。
The only way would be to first add an abstract method like doTheThing()
to your base class. 唯一的方法是首先向基类中添加一个抽象方法,如
doTheThing()
。
So that you then simple call p.doTheThing()
in that listener. 这样您就可以在该侦听器中简单地调用
p.doTheThing()
。
And of course, NamedPlace implements that method to do: 当然,NamedPlace实现了该方法:
JOptionPane.showMessageDialog(null, p.getName() + " " + p.getPosition(), "Platsinfo: ", JOptionPane.INFORMATION_MESSAGE);
and the other class implements it to do 另一个类实现它
JOptionPane describedPane = new JOptionPane();
...
That technically does what you ask for, but it is also not a very elegant solution. 从技术上讲,这可以满足您的要求,但这也不是一个很好的解决方案。 As those two methods are doing really different things.
由于这两种方法的作用确实不同。
A more reasonable solution could be that you have an abstract method that returns a (formatted) string for example, that then gets added to a (uniform) message window, or something alike. 一个更合理的解决方案可能是,您有一个抽象方法,该方法例如返回一个(格式化的)字符串,然后将其添加到一个(统一的)消息窗口中,或类似的方法。
The point of polymorphism is to allow doing "similar" things using a common interface. 多态性的目的是允许使用通用接口执行“相似”的操作。 It doesn't help with doing completely different things under the same hood.
在相同的环境下做完全不同的事情无济于事。
If your Place
classes shouldn't be aware of the specific response implementation to a click, then you can use visitor pattern , and separate your Place
hierarchy from it's response implementations. 如果您的
Place
类不应该知道单击的特定响应实现,则可以使用visitor pattern ,并将Place
层次结构与其响应实现分开。
Then you can provide different implementationsfor different situations, and your Place
classes will not grow and tightly couple with more and more situation specific code. 然后,您可以针对不同情况提供不同的实现,并且
Place
类将不会增长,并且会与越来越多的情况特定代码紧密结合。
To achieve that, update your parent class (I prefer to use interface) Place
with additional method: 为此,请使用其他方法更新您的父类(我更喜欢使用接口)
Place
:
public interface Place {
void accept(Visitor visitor);
}
And implement it: 并实现它:
public final class NamedPlace {
@Override
public void accept(Visitor visitor) {
visitor.visitNamedPlace(this);
}
}
public final class DescribedPlace {
@Override
public void accept(Visitor visitor) {
visitor.visitDescribedPlace(this);
}
}
Now the visitor interface will look like this: 现在,访问者界面将如下所示:
public interface Visitor {
void visitNamedPlace(NamedPlace place);
void visitDescribedPlace(DescribedPlace place);
}
The visitor pattern is now ready. 访客模式现已准备就绪。 And let's use it in your example:
并在您的示例中使用它:
class RightClickListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent mev) {
((Place) mev.getSource()).accept(new Visitor() {
@Override
public void visitNamedPlace(NamedPlace p) {
JOptionPane.showMessageDialog(null, p.getName() + " " + p.getPosition(), "Platsinfo: ", JOptionPane.INFORMATION_MESSAGE);
}
@Override
public void visitDescribedPlace(DescribedPlace p) {
JOptionPane describedPane = new JOptionPane();
describedPane.setMessage("Name: " + p.getName() + " " + p.getPosition() + "\n" + "Description: " + ((DescribedPlace) p).getDescription());
describedPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = describedPane.createDialog(p, "Platsinfo:");
dialog.setVisible(true);
}
});
}
}
} }
Your choice is actually: 您的选择实际上是:
It depends on your use cases. 这取决于您的用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.