簡體   English   中英

使用訪問者模式或反射的Java動態類轉換? 缺少步驟或執行不正確?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM