Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmieren » Abstraktes Feld vererben
Autor
Universität/Hochschule Abstraktes Feld vererben
emmi82
Senior Letzter Besuch: im letzten Quartal
Dabei seit: 06.05.2013
Mitteilungen: 459
  Themenstart: 2022-01-26

Hi, um ein Problem mit abstrakten Feldern zu lösen, an dem ich zurzeit knabbere, habe ich es mal mit Alltagssprachcode nachgebaut. Ist leider auch ziemlich lang geworden, sorry :) Mein Plan Es geht um ein abstraktes Feld X, das ich anlegen und Eigenschaften des Felds X vorbereiten muss, um diese Eigenschaften gleichermaßen für zwei verschiedene vererbte Felder, A und B, zu verwenden. Aber diese Eigenschaften allesamt sollen nur einmal in Codezeilen ausgedrückt werden. Rahmenbedingung Das Gefüge der Klassen X, A und B bzw. Human usw. ist vorgegeben (eigentlich handelt es sich um Java-Objekte). An den Auto-Klassen hingegen kann ich Änderungen vornehmen. Nachbau Um das nachzubauen, wird X hier repräsentiert durch "Human", A durch "Cousin" und B durch "Employee", die als Felder in den Auto-Klassen vorkommen. Gemeinsame Eigenschaften sind "name" und "birthyear". Hinzu kommt bei B die Eigenschaft "position". Die Klassen, die diese Felder dann beinhalten, sind im zweiten Block durch "car" usw. dargestellt. Man stellt sich also vor, wir legen die Eigenschaften eines "Human" fest, wenn auch abstrakt, und dieser soll dann sowohl als Employee als auch als Cousin auftreten, mit den gleichen Eigenschaften, versteht sich. Als solcher gleicher Mensch bekommt er erst ein Privatauto und dann ein Dienstfahrzeug. Teil 1 \sourceon Java package app; abstract class Human { String name; int birthyear; public Human(String name, int birthyear) { this.name=name; this.birthyear = birthyear; } public void setName(String newname) { this.name = newname; } } class Cousin extends Human { public Cousin(String name, int birthyear) { super(name, birthyear); init(); } public Cousin(String name, String nick) { super(name); } } class Employee extends Human { String position = ""; public Employee(String name, int birthyear, String position) { super(name, birthyear); this.position = position; } public Employee(String name) { super(name, 0); this.position = "Elektriker"; } //getPosition available public String getPosition() { return position; } } \sourceoff Teil 2 \sourceon Java package app; abstract class newcar { String name; String typ; String[] Handschuhfach; //hiermit hakt es Human Besitzer; public newcar(String name, String typ, String owner) { this.name = name; this.typ = typ; this.Besitzer.setName(owner); //gern auch this.Besitzer.setBirthyear(1971); //eben hier sollen sämtliche gemeinsame Einstellungen angelegt werden. } public String anrede() { return "Hallo " +this.Besitzer.name + "!"; } public void present() { System.out.println(String.format("Wir haben einen %s %s für Sie.", typ, name)); } public void unpack() { System.out.println("Sie nehmen mit:\r\n "+ String.join(", ", Handschuhfach)); } public void pack(String[] args) { Handschuhfach = args; } } public class car extends newcar { Employee owner; public car(Employee colleague, String[] things) { super("Sprinter", "VW", colleague.name); this.owner = colleague; pack(things); } public car(String coll, String[] things) { super("Sprinter", "VW", coll); this.owner = new Employee(coll); pack(things); } } class privcar extends newcar { Cousin owner; public privcar(Cousin pal, String[] things) { super("Corsa", "Opel", pal.name); this.owner = pal; pack(things); } } \sourceoff Dann in der Main: \sourceon Java package app; public class Application { public static void main(String[] args) { Employee mensch = new Employee("Gerd", 1978, "Elektriker"); System.out.println("Hallo "+mensch.name); Employee mitarbeiter = (Employee) mensch; System.out.println("Herzlich willkommen als "+mitarbeiter.getPosition()+"!"); System.out.println("Draußen steht Ihr neues Auto:"); //Hier geht es schief. car dienstwagen = new car(mitarbeiter, new String[] {"Thermobecher", "Messschieber", "Stadtplan"} ); dienstwagen.present(); dienstwagen.unpack(); } } \sourceoff Ergebnis: Laufzeitfehler "Cannot invoke "app.Human.setName(String)" because "this.Besitzer" is null" Mir ist schon klar, warum der Fehler kommt, aber nicht, wie ich das löse, um trotzdem meinen Plan (s.o.) zu erfüllen. Da hoffe ich auf eure Hilfe :) Gruß emmi


   Profil
tactac
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 15.10.2014
Mitteilungen: 2437
  Beitrag No.1, eingetragen 2022-01-26

Hallo emmi82, man kann Felder nicht vererben. Jedenfalls nicht so, wie du es vorhast, mit Überschreiben des Felds an sich. Es ist auch seltsam, warum gerade im Konstruktor von newcar der Name des Besitzers gesetzt werden soll. Aber sei's drum. Etwas ähnliches geht zum Beispiel so: \sourceon Java class X { void setData(String data) { /* ... */ } } class A extends X {} class B extends X {} abstract class Holder { protected T thing; Holder(T thing, String data) { this.thing = thing; thing.setData(data); } } class AHolder extends Holder { AHolder(String data) { super(new A(), data); } // hier gibt's jetzt außerdem das Feld A thing } class BHolder extends Holder { BHolder(String data) { super(new B(), data); } // hier gibt's jetzt außerdem das Feld B thing } \sourceoff


   Profil
emmi82
Senior Letzter Besuch: im letzten Quartal
Dabei seit: 06.05.2013
Mitteilungen: 459
  Beitrag No.2, vom Themenstarter, eingetragen 2022-01-27

Hi, das in #1 kann ich bei mir so nicht machen, da bei mir die Klasse X abstrakt sein muss. Dachte ich! Es geht doch: \sourceon Java package app; abstract class X { String data; void setData(String data) { this.data = data; } public String getData() {return data;} } class A extends X {} class B extends X {} abstract class Holder { protected T thing; Holder(T thing, String data) { this.thing = thing; thing.setData(data); } } class AHolder extends Holder { AHolder(String data) { super(new A(), data); } // hier gibt's jetzt außerdem das Feld A thing } class BHolder extends Holder { BHolder(String data) { super(new B(), data); } // hier gibt's jetzt außerdem das Feld B thing } \sourceoff Frage nun: Wieso kommt "this.Besitzer ist null", aber das mit dem X hier oben wirft keinen Fehler aus? emmi


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 3104
  Beitrag No.3, eingetragen 2022-01-27

Du rufst erst den Construktor der Superklasse auf und weist dort dem Besitzer einen Namen zu und danach(!) übergibst bzw. erzeugst du überhaupt das Besitzerobjekt. Daher wirft der Konstruktor der Superklasse eine Nullpointerausnahme.


   Profil
emmi82
Senior Letzter Besuch: im letzten Quartal
Dabei seit: 06.05.2013
Mitteilungen: 459
  Beitrag No.4, vom Themenstarter, eingetragen 2022-01-27

Hi nochmal, tja, hab alles versucht, genauso nachzubauen wie in #2, wo es ja funktioniert hat. Ich sehe einfach nicht, worin besteht der Unterschied im Vorgehen von #3 zu #2, der verursacht, dass wieder dieser Null-Fehler kommt? \sourceon Java package app; abstract class newcar { String name; String typ; String[] Handschuhfach; protected T Besitzer; public newcar(String name, String typ, String owner) { this.name = name; this.typ = typ; this.Besitzer.setName(owner);//Warum Problem hier? } //(...) } (...) public class car extends newcar { public car(Employee colleague, String[] things) { super("Sprinter", "VW", colleague.name); pack(things); } public car(String coll, String[] things) { super("Sprinter", "VW", coll); pack(things); } } \sourceoff emmi [Die Antwort wurde nach Beitrag No.2 begonnen.]


   Profil
emmi82
Senior Letzter Besuch: im letzten Quartal
Dabei seit: 06.05.2013
Mitteilungen: 459
  Beitrag No.5, vom Themenstarter, eingetragen 2022-01-27

\quoteon(2022-01-27 11:16 - DerEinfaeltige in Beitrag No. 3) Du rufst erst den Construktor der Superklasse namens ____ auf und weist dort dem Besitzer einen Namen zu und danach(!) übergibst bzw. erzeugst du überhaupt das Besitzerobjekt. Daher wirft der Konstruktor der Superklasse eine Nullpointerausnahme. \quoteoff # Sorry dass ich nochmals nachfrage, aber ich verstehe das nicht, weil ich nciht weiß, welche Klasse, x, newcar, Human, oder was, da gemeint ist, Bitte das nachtragen.


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 3104
  Beitrag No.6, eingetragen 2022-01-27

\sourceon Java \numberson abstract class newcar { String name; String typ; String[] Handschuhfach; protected T Besitzer; public newcar(String name, String typ, String owner) { this.name = name; this.typ = typ; this.Besitzer.setName(owner);//Warum Problem hier? // this.Besitzer ist hier null. // Du musst ERST den Besitzer zuweisen, dann modifizieren } \sourceoff Das Problem hat eigentlich nichts mit Vererbung zu tun. Ohne Vererbung würde ganz genau das Gleiche passieren. \sourceon Java \numberson class MyClass{ Object myField; // Falsche Reihenfolge MyClass(Object field){ myField.doSomething(); // Fehler myField = field; } // Richtige Reihenfolge MyClass(Object field){ myField = field; myField.doSomething(); } } \sourceoff


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 3104
  Beitrag No.7, eingetragen 2022-01-27

Hier nochmal ein Schema, das ohne Generics auskommt. \sourceon Java \numberson public class Klassen { static abstract class Pet{ String petName; Pet(String name){ petName = name; } abstract String makeNoise(); } static class Dog extends Pet{ Dog(String name) { super(name); } @Override String makeNoise(){ return "Wooff!!"; } } static class Cat extends Pet{ Cat(String name) { super(name); } @Override String makeNoise(){ return "Meoww!!"; } } static abstract class Human{ String myName; Pet myPet; Human(String name, Pet pet){ myName = name; myPet = pet; } abstract String representYourself(); } static class Man extends Human{ Man(String name, Dog dog) { super(name, dog); } Man (String name, String petName, String petClass){ super(name, petClass.equals("Dog") ? new Dog(petName) : new Cat(petName)); } @Override String representYourself(){ return new StringBuilder("I am ") .append(myName) .append(", I am male and this is my dog ") .append(myPet.petName) .append("! ") .append(myPet.makeNoise()) .toString(); } } static class Woman extends Human{ Woman(String name, Cat cat) { super(name, cat); } Woman (String name, String petName, String petClass){ super(name, petClass.equals("Dog") ? new Dog(petName) : new Cat(petName)); } @Override String representYourself(){ return new StringBuilder("I am ") .append(myName) .append(", I am female and this is my cat ") .append(myPet.petName) .append("! ") .append(myPet.makeNoise()) .toString(); } } public static void main(String[] args){ var ruffy = new Dog("Ruffy"); var fluffy = new Cat("Fluffy"); var roger = new Man("Roger",ruffy); var frieda = new Woman("Frieda", fluffy); var chris = new Man("Chris","Cerberus","Dog"); var bessy = new Woman("Bessy","Bastet","Cat"); System.out.println(roger.representYourself()); System.out.println(frieda.representYourself()); System.out.println(chris.representYourself()); System.out.println(bessy.representYourself()); } } I am Roger, I am male and this is my dog Ruffy! Wooff!! I am Frieda, I am female and this is my cat Fluffy! Meoww!! I am Chris, I am male and this is my dog Cerberus! Wooff!! I am Bessy, I am female and this is my cat Bastet! Meoww!! \sourceoff


   Profil
emmi82 hat die Antworten auf ihre/seine Frage gesehen.

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2022 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]