0

我正在创建将根据用户输入具有共同属性的对象,然后将对象传递给一个通用方法,该方法将根据对象类型采取适当的操作。我已经能够使用访问者类来完成这项工作,但这并不是我想要的。我希望能够确定通用方法中的对象类型,然后访问与该对象关联的方法。我不确定我是不是很接近并且只是错过了一些东西,或者我只是有一个糟糕的实现......或者两者兼而有之=)。这是我的(完整)代码:

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)) ()。我错过了什么?还是有更好的方法来实现这一点?

非常感谢您的宝贵时间。

-沃尔特

4

1 回答 1

0

对于您的具体示例,您可以丢弃所有这些东西并使用参数类型的重载:

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

然后你可以演变成真正的访问者模式,但是在这里可以而且应该避免反射。

于 2013-09-02T08:10:05.783 回答