|
Autor |
Abstraktes Feld vererben |
|
emmi82
Senior  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  Dabei seit: 15.10.2014 Mitteilungen: 2437
 | Beitrag No.1, eingetragen 2022-01-26
|
Profil
|
emmi82
Senior  Dabei seit: 06.05.2013 Mitteilungen: 459
 | Beitrag No.2, vom Themenstarter, eingetragen 2022-01-27
|
Profil
|
DerEinfaeltige
Senior  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  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  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  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  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. |
|
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]
|