C’è un modo per creare un’istanza di una classe di bambini con genitori oggetto in java?

Ho una classe base dire

class A {
   private String name;
   private String age;

   //setters and getters for same
}

e una classe di bambini dire

class B extends A {
 private String phone;
 private String address;

  //setters and getters for same
}

ora ho un’istanza di A e oltre a questo devo impostare i campi in B, come pure, in modo che il codice sarebbe come,

A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());

posso creare un’istanza di B con data Una, ma non voglio fare in questo modo,

B constructBFrom(A instanceOfA) {
  final B instanceOfB = new B();
  instanceOfB.setName(instanceOfA.getName());
  instanceOfB.setPhone(instanceOfA.getAge());

  return B;
}

piuttosto quello che mi piacerebbe avere qualche utilità, con la funzione che è sufficientemente generico per costruire l’oggetto come in

public class SomeUtility {

   public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {

      T2 instatnceOfT2 = null;

      try {
         instatnceOfT2 = className.newInstance();
         /*
         * Identifies the fields in instanceOfT1 which has same name in T2
         * and sets only these fields and leaves the other fields as it is.
         */
      } catch (InstantiationException | IllegalAccessException e) {
         //handle exception
      }          

      return instatnceOfT2;
   }
}

in modo che posso usare come,

B constructBFrom(A instanceOfA) {
   return SomeUtility.constructFrom(instanceOfA, B.class);
}

Inoltre, in caso di utilizzo non sarà limitato solo ai genitori-figli delle classi, piuttosto questa funzione di utilità può essere utilizzato per l’uso dell’adattatore casi.

PS – A e B sono classi di terza parte che ho per utilizzare queste classi solo così non posso fare modifiche
in A e B.

  • Dichiarare una B costruttore che accetta un A.
  • Che cosa si aspetta la conseguente B a guardare come? Semplicemente una copia dell’istanza di A con i campi di B impostato a null?
  • suona come un XY problema per me… qual’è il vero problema che si sta tentando di risolvere? Non riesco a immaginare alcun decente caso di utilizzo per cercare di fare questo.
  • un decente caso d’uso può essere ad esempio la creazione di una specifica XXXList basato sul generico List. Anche se sono probabilmente ragione, sto anche abbastanza sospetti circa l’OP motivazione 🙂
  • Non c’è modo di impostare il nome e l’età di un B comunque senza chiamare in modo esplicito setName e setAge, poiché, come scritto B non ha un costruttore che prende il nome e l’età come parametri. A proposito, instanceOfA.getPhone() è un errore di compilazione, in quanto A non ha phone o getPhone.
  • Se A e B sono la festa di 3 classi, e non c’è modo ovvio per la conversione tra i due, questo è quasi certamente da disegno, e a meno che non si dispone di un’intima familiarità con la biblioteca, si dovrebbe essere attenti a manipolare la struttura dell’oggetto.
  • vedere modifica alla mia risposta qui sotto. Ci dicono che COSA volete che il vostro trucco PER. Sembra sporco, dall’inizio alla fine.

InformationsquelleAutor shelly | 2014-07-07



3 Replies
  1. 10

    La buona pratica è quello di avere un fabbrica classe che “produce” le istanze di B.

    public class BFactory {
        public B createBFromA(A a) { ... }
    }

    Si devono scrivere il codice del metodo factory come non esiste un modo standard di creazione di una classe di bambini basato sulla sua classe padre. È sempre specifico e dipende dalla logica delle classi.

    Tuttavia, considerare se è davvero di che cosa avete bisogno. Ci sono non molti smart casi d’uso per la creazione di un’istanza di una classe basata su istanza del genitore. Un buon esempio è ArrayList(Collection c) costruisce una specifiche elenco (“bambino”) contenente gli elementi di generico raccolta (“base”).

    In realtà, per molti la situazione ci è un motivo per evitare tali strano costrutti. Sono consapevole che probabilmente non è applicabile al tuo caso specifico, come hai scritto che la tua Base e il Figlio sono la festa di 3 classi. Tuttavia il titolo della domanda è abbastanza generica quindi penso che si possono trovare utili seguenti.

    1. Creare un’interfaccia IBase
    2. Alla classe di Base implementare l’interfaccia
    3. Utilizzare la composizione invece di ereditarietà – let Child utilizzare Base invece di ereditare la
    4. Lasciare Child implementare IBase e delegare tutti i metodi di IBase all’istanza di Base

    Il codice sarà simile a questo:

    public interface IBase {
        String getName();
        int getAge();
    }
    
    public class Base implements IBase {
        private String name;
        private int age;
        //getters implementing IBase
    }
    
    public class Child implements IBase {
        //composition:
        final private IBase base;        
        public Child(IBase base) {
            this.base = base;
        }
        //delegation:
        public String getName() {
            return base.getName();
        }
        public int getAge() {
            return base.getAge();
        }
    }

    Dopo aver modificato la tua domanda, mi viene il dubbio ancora più forte che quello che vuoi è buono. La tua domanda appare più come un tentativo di hack, di violazione (o non conoscenza) dei principi di classe object oriented concetto. Mi sembra che qualcuno proveniente da JavaScript parola e cercando di mantenere la programmazione JavaScript stile e basta usare una diversa sintassi di Java, invece di adottare una diversa filosofia del linguaggio.

    Divertimento fatto: un’istanza di un oggetto figlio con il genitore oggetto è possibile in il prototipo, in base lingue, vedere l’esempio in JavaScript 1.8.5:

    var base = {one: 1, two: 2};
    var child = Object.create(base);
    child.three = 3;
    
    child.one;   //1
    child.two;   //2
    child.three; //3
    • questo presumendo che l’OP è necessario costruire è anche una buona idea, in primo luogo…
    • hai assolutamente ragione. Ho aggiunto una nota.
  2. 0

    A mio parere il modo in cui si vuole evitare è molto appropriato. Ci deve essere un pezzo di tale codice da qualche parte.

    Se non riesci a mettere che il metodo nella classe di destinazione solo metterlo da qualche altra parte (alcuni di fabbrica). Si dovrebbe inoltre rendere il vostro metodo static.

    Dare un’occhiata a Factory method pattern.

    2 ° opzione sarebbe estendere B e luogo, questo metodo di fabbrica metodo statico nella nuova classe. Ma questa soluzione sembra essere più complicato per me. Quindi si potrebbe chiamare NewB.fromA(A). Si dovrebbe essere in grado, quindi, utilizzare il vostro NewB invece di B quindi.

  3. 0

    Si potrebbe fare una riflessione:

    public static void copyFields(Object source, Object target) {
            Field[] fieldsSource = source.getClass().getFields();
            Field[] fieldsTarget = target.getClass().getFields();
    
            for (Field fieldTarget : fieldsTarget)
            {
                for (Field fieldSource : fieldsSource)
                {
                    if (fieldTarget.getName().equals(fieldSource.getName()))
                    {
                        try
                        {
                            fieldTarget.set(target, fieldSource.get(source));
                        }
                        catch (SecurityException e)
                        {
                        }
                        catch (IllegalArgumentException e)
                        {
                        }
                        catch (IllegalAccessException e)
                        {
                        }
                        break;
                    }
                }
            }
        }

    *Sopra il codice copiato da tutorial online

Lascia un commento