[英]Java dynamic class casting using visitor pattern or reflection? Missing steps or bad implementation?
我正在創建基於用戶輸入具有共同屬性的對象,然后將這些對象傳遞給將根據對象類型采取適當操作的通用方法。 我已經能夠使用一個訪問者類來使它工作,但這並不是我想要的。 我希望能夠在通用方法中確定對象類型,然后訪問與該對象關聯的方法。 我不確定我是否接近並且只是缺少一些東西,或者我只是執行不正確...還是兩者都=)。 這是我的(完整)代碼:
package com.theory.bang.big;
public interface Particle
{
public enum ParticleType {
QUARK,
LEPTON
}
int processParticle(Particle p);
}
package com.theory.bang.big;
import java.util.ArrayList;
public class Quark implements Particle
{
ArrayList<String> flavorList;
/**
* Constructor for objects of class Quark
*/
public Quark()
{
flavorList = new ArrayList<String>();
flavorList.add("up");
flavorList.add("down");
flavorList.add("charm");
flavorList.add("strange");
flavorList.add("top");
flavorList.add("bottom");
}
public ArrayList<String> getFlavors()
{
return flavorList;
}
@Override
public int processParticle(Particle p)
{
System.out.println("In processParticle(Quark)");
// Never called?
return 0;
}
}
package com.theory.bang.big;
import java.util.ArrayList;
public class Lepton implements Particle
{
ArrayList<String> typeList;
/**
* Constructor for objects of class Lepton
*/
public Lepton()
{
typeList = new ArrayList<String>();
typeList.add("electron");
typeList.add("electron neutrino");
typeList.add("muon");
typeList.add("muon neutrino");
typeList.add("tau");
typeList.add("tau neutrino");
}
public ArrayList<String> getTypes()
{
return typeList;
}
@Override
public int processParticle(Particle p)
{
System.out.println("In processParticle(Lepton)");
return 0;
}
}
package com.theory.bang.big;
import java.lang.reflect.*;
class ParticleVisitor
{
public void visit( Quark q )
{
System.out.println("Quark:[" + q.getFlavors() + "]");
}
public void visit( Lepton l )
{
System.out.println("Lepton:[" + l.getTypes() + "]");
}
public void visit( Object e ) throws Exception
{
Method m = getClass().getMethod
( "visit", new Class[]{e.getClass()} );
m.invoke( this, new Object[]{e} );
}
}
package com.theory.bang.big;
import java.io.File;
public class Accelerate implements Particle
{
/**
* Constructor for objects of class Accelerate
*/
public Accelerate(Particle p)
{
processParticle(p);
}
//@Override
public int processParticle(Particle p)
{
try {
ParticleVisitor pv = new ParticleVisitor();
pv.visit(p);
} catch (Exception x) {
System.out.println(x);
}
return 0;
}
}
package com.theory.bang.big;
import java.io.File;
import java.util.Scanner;
public class Physics
{
public static void main(String[] args)
{
boolean done = false;
while (!done) {
System.out.print("Enter the particle [Quark or Lepton]: ");
Scanner in = new Scanner(System.in);
String input = in.next();
if (input.equals("Quark")) {
System.out.println("Quark");
Quark q = new Quark();
new Accelerate(q);
} else if (input.equals("Lepton")) {
System.out.println("Lepton");
Lepton l = new Lepton();
new Accelerate(l);
} else {
done = true;
}
}
}
}
目前,我可以通過訪問方法來打印Quark風味和Lepton類型,但我需要的是能夠為Accelerate中的各個對象執行(待實現)getter / setter(例如getSpin(),setSpin(double s))。 ()。 我想念什么? 還是有更好的方法來實現這一目標?
非常感謝您的寶貴時間。
沃爾特
對於您的具體示例,您可以丟棄所有這些東西,並按參數類型使用重載:
public class Physics {
public static void processParticle( Quark q ) {
System.out.println("Quark:[" + q.getFlavors() + "]");
}
public static void processParticle( Lepton l ) {
System.out.println("Lepton:[" + l.getTypes() + "]");
}
public static void main(String[] args) {
boolean done = false;
while (!done) {
System.out.print("Enter the particle [Quark or Lepton]: ");
Scanner in = new Scanner(System.in);
String input = in.next();
if (input.equals("Quark")) {
System.out.println("Quark");
Quark q = new Quark();
processParticle(q);
} else if (input.equals("Lepton")) {
System.out.println("Lepton");
Lepton l = new Lepton();
processParticle(q);
} else {
done = true;
}
}
如果要在編譯器不知道粒子確切類型的情況下調用processParticle(),請使用雙調度模式:
// add method processParticle
public interface Particle{
...
void processParticle();
}
class Quark implements Particle {
void processParticle() {
Physics.processParticle(this);
}
}
class Lepton extends Particle {
void processParticle() {
Physics.processParticle(this);
}
}
public class Physics {
public static void main(String[] args) {
for (;;) {
System.out.print("Enter the particle [Quark or Lepton]: ");
Scanner in = new Scanner(System.in);
String input = in.next();
Particle p;
if (input.equals("Quark")) {
System.out.println("Quark");
p = new Quark();
} else if (input.equals("Lepton")) {
System.out.println("Lepton");
p = new Lepton();
} else {
break;
}
p.processParticle();
}
}
}
然后,您可以演變為真正的訪客模式,但是在此可以並且應該避免反射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.