Liste mit Attribut Abstract vererben

computersport

Aktives Mitglied
Moinsens,

Ich baue zurzeit eine Klasse wo ich die Attribute per Liste und nicht
mit den Getter und Setter Methoden angesprochen werden. Nun ist die Frage
ob es möglich ist diese Liste mit Vererbung zu erstellen, also diese Automatisch für jede
Klasse zu erstellen oder ich die wirklich bei jeder Klasse wo ich diese Liste benötige per Hand
eingeben muss. Ich habe überlegt das ich das mit Reflection mache.. bin mir da nich ganz sicher.

Hat jemand von euch evtl. ein paar Ideen wie man das Lösen kann?
Ich beziehe mich hier auf die Methode "getAttributList()".

Hier mal die Klasse:
Java:
package beispieldbanwendung;

import java.util.ArrayList;
import java.util.List;

public class TestKlasse
{

  private String nName;
  private String vName;

  public TestKlasse()
  {
  }

  public List getAttributList()
  {
    List liste = new ArrayList();
    liste.add(getnName());
    liste.add(getvName());
    return liste;
  }

  public String getnName()
  {
    return nName;
  }

  public void setnName(String nName)
  {
    this.nName = nName;
  }

  public String getvName()
  {
    return vName;
  }

  public void setvName(String vName)
  {
    this.vName = vName;
  }
}
 
Hi
Vielleicht so?

Java:
public class TestKlasse {
	
	
	private Map<String, String> _attribute;
	
	
	
	
	public List<String> getAttributList(){
		return new ArrayList<String>(_attribute.keySet());
	}
}

Nachtrag: ich würde noch extra Klasse Attribut anlegen, als Key könnte man enum nehmen...
 
Zuletzt bearbeitet:
Hmm hätte ich mit erwähnen müssen die Attribute müssen so stehen bleiben...

Ich arbeite mit dem Framework Hibernate und das braucht die Attribute so in der Klasse da
diese die Spalten in der Tabelle darstellen.

Deine ist aber aufjedenfall ein Ansatz wenn ich die Attribute nicht auf diese Art bräuchte...
 
Erben die Klassen voneinander? Oder sind es tatsächlich Klassen, die völlig unabhängig voneinander sind?

Falls du hier vererbst, kannst du auf der abstraktesten Ebene anfangen und die Attribute genau so zurückgeben, wie du gezeigt hast. Falls eine Klasse dann von dieser erbt, aber noch zusätzliche Attribute hat, dann kannst du einfach die Methode überschreiben, mit einem super-Aufruf die Liste der abstrakteren Klasse zusammenbauen lassen und die neuen Attribute hinzufügen.
 
Es ist so das es ganze Viele Objekte dieser TestKlasse gibt.

Die haben alle verschiedene Attribute. Und ich will jetzt nicht in jeder einzelnen Klasse
diese Attributliste von Hand eingeben müssen sondern diese Methode per Vererbung in jeder Klasse
zur Verfügung stellen.
 
Hmm hätte ich mit erwähnen müssen die Attribute müssen so stehen bleiben...

Ich arbeite mit dem Framework Hibernate und das braucht die Attribute so in der Klasse da
diese die Spalten in der Tabelle darstellen.

Deine ist aber aufjedenfall ein Ansatz wenn ich die Attribute nicht auf diese Art bräuchte...

Dann sollte die Hibernate Klasse nur set- und get- Methoden enthalten, nichts anderes soweit ich weiss. Du bräuchtest dann eine extra "Hüllklasse" die die Hibernate Klasse repraesentiert.
Diese kannst du dann nach belieben anpassen und ändern.
 
Es ist so das es ganze Viele Objekte dieser TestKlasse gibt.

Die haben alle verschiedene Attribute. Und ich will jetzt nicht in jeder einzelnen Klasse
diese Attributliste von Hand eingeben müssen sondern diese Methode per Vererbung in jeder Klasse
zur Verfügung stellen.

Du meinst sicher nicht Objekte, oder? Wenns Objekte einer Klasse wären, dann hätten die alle genau die gleichen Attribute. Und du müsstest es ja auch nur an einer Stelle ändern.

Ansonsten fällt mir da jetzt auch nich mehr ein, könntest höchstens mal ein Interface machen, aber implementieren musst du es dann in jeder Klasse doch wieder.
 
Du meinst sicher nicht Objekte, oder? Wenns Objekte einer Klasse wären, dann hätten die alle genau die gleichen Attribute. Und du müsstest es ja auch nur an einer Stelle ändern.

Ansonsten fällt mir da jetzt auch nich mehr ein, könntest höchstens mal ein Interface machen, aber implementieren musst du es dann in jeder Klasse doch wieder.

Ups hab mich verschrieben das sind verschiedene Klassen...
 
Es ist so das es ganze Viele Objekte dieser TestKlasse gibt.

Die haben alle verschiedene Attribute. Und ich will jetzt nicht in jeder einzelnen Klasse
diese Attributliste von Hand eingeben müssen sondern diese Methode per Vererbung in jeder Klasse
zur Verfügung stellen.


Kannst du auch per Reflection machen. Eine Utility Klasse anlegen die die Attribute als Liste extrahiert (entweder direkt über Feldzugriff oder über eine Getter Methode:

Java:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public final class Testen {

	public static void main(String[] args) {
		A a = new A();
		List<Object> fieldAttributes = getAttributesByField(a);
		for (Object o : fieldAttributes) {
			System.out.println(o);
		}
		
		List<Object> getterAttributes = getAttributesByGetter(a);
		for (Object o : getterAttributes) {
			System.out.println(o);
		}
	}

	public static List<Object> getAttributesByField(Object o) {

		List<Object> allAttributes = new ArrayList<Object>();
		Field[] fields = o.getClass().getDeclaredFields();
		for (Field f : fields) {
			try {
				allAttributes.add(f.get(o));
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return allAttributes;
	}

	public static List<Object> getAttributesByGetter(Object o) {

		List<Object> allAttributes = new ArrayList<Object>();
		Method[] methods = o.getClass().getDeclaredMethods();
		for (Method m : methods) {

			if (m.getName().startsWith("get")) {
				try {
					allAttributes.add(m.invoke(o, null));
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		return allAttributes;
	}

}

class A {
	String a = "Aa";
	String b = "Ab";
	int c = 1;

	public String getA() {
		return a;
	}

	public void setA(String a) {
		this.a = a;
	}

	public String getB() {
		return b;
	}

	public void setB(String b) {
		this.b = b;
	}

	public int getC() {
		return c;
	}

	public void setC(int c) {
		this.c = c;
	}
}
[/code]
 
Als Wrapper um Hibernate- Klassen? Bist du dir sicher, dass du nicht einfacher fährst, wenn du dir über JDBC ResultSets aus der DB holst? DIe haben dann getX(String name)- Methoden, wobei X der angeforderte Typ ist. Anders als in deinem Ansatz bekommst du die Sachen also sogar typisiert. Wenn du das Zeug in einer Liste brauchst, kannst du auch per Spaltennummer getX(int n) zugreifen. Falls das ResultSet keine Funktion hat, um die Anzahl der Spalten abzufragen, hat es ein Metadata- Objekt, dass diese Information sicher enthält.
Ich empfehle hier mal in die API zu gucken.

Einen Wrapper um Hibernate- Klassen brauchst du nur, wenn ein anderer Teil deiner Applikation diese tatsächlich "regulär" verendet, also nicht mit ResultSets klarkommen würde.
 
Moinsens,

das ist so das ich hier auf einem existierenden System aufbaue.
Dort hab ich auch die Namen der einzelnen Attribute usw. deswegen hab ich es jetzt einfach per Reflection gemacht. Das passt so in etwa zu dem was fassy gepostet hat.

Nochmals danke für die Hilfe.

Ganz kurzer einschub wie ich das gemacht habe:
Java:
  private Object getValueFromObject(String aFieldName)
  {
    Class clazz = this.getClass();

    if (clazz == null)
    {
      return null;
    }
    // Schmutzig aber WTF??? es laeuft doch :)
    aFieldName = aFieldName.toLowerCase();
    String ersterBuchstabe = aFieldName.substring(0, 1);
    String getterName = "get" + aFieldName.replaceFirst(aFieldName.substring(0, 1), ersterBuchstabe.toUpperCase());
    try
    {
      @SuppressWarnings("unchecked")
      Method method = clazz.getMethod(getterName);
      Object valueObject = method.invoke(this, (Object[]) null);
      return valueObject;
    }
    catch (Exception e)
    {
      System.out.println("Fehler: " + e);
      return null;
    }
  }

Da ich die Attributnamen und den Datentyp der Attribute habe brauch ich hier nur noch den Namen
einspeisen und krieg dann den Value den ich benötige 🙂.

Falls jemand nen besseren weg kennt den Attribut namen anzupassen nehm ich gerne an ^^.

greetz

compi
 
Falls jemand nen besseren weg kennt den Attribut namen anzupassen nehm ich gerne an ^^.

greetz

compi

Java:
String getterName = String.format("get%S"+aFieldName.substring(1), aFieldName.charAt(0))
oder
Java:
String getterName = String.format("%s%S%s", "get", aFieldName.charAt(0), aFieldName.substring(1))

Aber ob das besser ist?
 
Zuletzt bearbeitet von einem Moderator:

Neue Themen


Zurück
Oben