Abstrakte Typen und Schnittstellen

Louis12

Aktives Mitglied
Hallo Java Community,
könnt ihr mir bitte Helfen ?
Im Enum Priority, habe ich folgende Konstanten hinzugefügt:
STANDARD, EXPRESS, EARLY_MORNING, EVENING

Im Enum TransportService habe ich folgende Konatanten hinzugefügt: TRANSPORT_INSURANCE, REDIRECTION, PREFERRED_DAY, CASH_ON_DELIVERY

Und zwar geht es um folgende Aufgabe.

Letter: Implementieren Sie alle geforderten Methoden.

Bei einem Brief soll eine nachträgliche Änderung des Empfängers nicht möglich sein, die entsprechende Methode soll die Lieferung also nie verändern und stets false zurückgeben.

Fügen Sie außerdem einen zusätzlichen Konstruktor ein, bei dem zusätzlich eine Priorität übergeben werden kann.

Versuchen Sie durch geschickte Aufrufe so wenig Quelltext wie möglich zu duplizieren.

Der bisherige Konstruktor soll Briefe mit Standardpriorität erzeugen.


Ich habe es folgender maßen versucht.
Code:
ackage de.tuberlin.mcc.prog1.logistics.deliveries;

import Prog1Tools.IOTools;
import de.tuberlin.mcc.prog1.logistics.DeliveryManager;
import de.tuberlin.mcc.prog1.logistics.Location;
import de.tuberlin.mcc.prog1.logistics.utils.Priority;

public class Letter extends Delivery { // Ich glaube hier fehlen noch die implemtierten Methoden

    private final boolean registeredLetter;
  
    /**
     * Creates Letter
     * @param sender - sender of letter
     * @param receiver - receiver of letter
     * @param weight - weight of letter
     * @param registeredLetter - true, if registered
     * @param priority die Priorität vom Brief
     */
    public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority) {
        super(sender, receiver, weight, priority.STANDARD);
        this.registeredLetter = registeredLetter;
      
        if (weight < 0.2) {
            postage = 70;
        } else {
            if (weight < 0.5) {
                postage = 200;
            } else {
                postage = 400;
            }
        }
        if (registeredLetter) {
            postage += 300;
        }
    }
  
    @Override
    public String toString() {
        String result = "Letter " + super.toString() + ", " + postage + "ct postage";
        if (registeredLetter) {
            result += ", registered letter";
        }
        return result;
    }
  
    /**
     * Creates Letter from user input
     * @return created letter or null (invalid parameters)
     */
    public static Letter createLetterFromUserInput() {
        System.out.println("Creating new letter...");
        int sender = IOTools.readInt("LocationID of sender:");
        int receiver = IOTools.readInt("LocationID of receiver:");
        double weight = IOTools.readDouble("Weight of letter:");
        boolean registered = IOTools.readBoolean("Registered letter?:");
        Location loc_sender = DeliveryManager.getLocationById(sender);
        Location  loc_receiver = DeliveryManager.getLocationById(receiver);
      
          
        if (loc_sender != null && loc_receiver != null && weight >= 0) {
            return new Letter(loc_sender, loc_receiver, weight, registered); // Complier Fehlr :/


          
        }
        while(loc_receiver != loc_receiver ) { //
            return false;
        }
      
        return null;
    }
  
    /**
     * Returns true if letter is a registered letter
     * @return true if letter is a registered letter
     */
    public boolean isRegisteredLetter() {
        return registeredLetter;
    }
}



lG
Louis
 


Bei einem Brief soll eine nachträgliche Änderung des Empfängers nicht möglich sein, die entsprechende Methode soll die Lieferung also nie verändern und stets false zurückgeben.


wie schaffe ich es , dass die Methode weiß was Receiver ist, wenn sie sich ausserhalb der Methode createLetterFromUserInput() befindet ?

Angenommen ich hätte diese Methode, wäre dieser Ansatz generell falsch ?
Code:
public static boolean Recieverinputnichtändern(){
while(loc_receiver != loc_receiver ) {
            return false;
        }
}
wenn nein, bitte Tipps um weiter anzusetzen bzw. fortzugehen.
wenn ja, bitte sagen ebnfalls Tipps geben.


ist das richtig um den Brief als Standartpriorität zu erzeugen
Code:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority) {
        super(sender, receiver, weight, priority.STANDARD);
        this.registeredLetter = registeredLetter;

also das ich einfach priority.STANDARD schreiben kann
 
Zuletzt bearbeitet von einem Moderator:
Java:
public class RacingPigeon
{

    public static void main(String[] args)
    {
        Package letter = new Package(); //Default
        System.out.println(letter.getValue());
       
        Package fastAndBetterServiceLetter = new Package(Priority.EXPRESS, Service.SILVER);
        System.out.println(fastAndBetterServiceLetter.getValue());
       
        Package fastAndBestServiceLetter = new Package(Priority.EXPRESS, Service.GOLD);
        System.out.println(fastAndBestServiceLetter.getValue());
       
    }
   
}

public class Package
{

    private final Priority priority;
    private final Service service;

    public Package()
    {
        this.priority = PriorityFactory.getDefaultPriority();
        this.service = ServiceFactory.getDefaultService();
    }

    public Package(Priority priority, Service service)
    {
        this.priority = priority;
        this.service = service;
    }

    public int getValue()
    {
        return (this.priority.getImportance() + this.service.getValue());
    }

}

/** Output */
2
4
5
 
ist das richtig um den Brief als Standartpriorität zu erzeugen
Code:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority) {
        super(sender, receiver, weight, priority.STANDARD);
        this.registeredLetter = registeredLetter;

also das ich einfach priority.STANDARD schreiben kann

Nein, du willst nicht auf etwas des Parameters priority zugreifen, sondern auf den enum Priority.STANDARD.
Den Parameter verwirfst du da btw grad, das dürfe falsch sein.
 
Bei einem Brief soll eine nachträgliche Änderung des Empfängers nicht möglich sein, die entsprechende Methode soll die Lieferung also nie verändern und stets false zurückgeben.
Wenn Du in Deine Delivery-Klasse schaust, hast Du vermutlich eine Methode der Form "boolean setReceiver(Location receiver)". Die wird von Letter geerbt, würde also den Empfänger ändern. Da das bei einem Letter-Objekt nicht mehr möglich sein soll, überschreibst Du die Methode und gibst einfach false zurück.
 
Ach, und was die Konstruktoren betrifft: Du hast einmal einen Konstruktor ohne Priority-Parameter und einmal mit. Wird ein Letter-Objekt erzeugt, kann man also aussuchen, ob man eine Priorität angibt. Falls ja, soll natürlich die angegebene Priorität verwendet werden, falls nein, soll die Standard-Priorität gesetzt werden.
 
Hallo Leute,
Erstmal danke für alle Antworten 🙂, dadurch bin ich auf jeden Fall weiter. Ich habe herumprobiert und würde mich freuen wenn ihr meine Fragen beantworten könnt:



Wenn Du in Deine Delivery-Klasse schaust, hast Du vermutlich eine Methode der Form "boolean setReceiver(Location receiver)". Die wird von Letter geerbt, würde also den Empfänger ändern. Da das bei einem Letter-Objekt nicht mehr möglich sein soll, überschreibst Du die Methode und gibst einfach false zurück.

Dank der Beschreibung ist es denke ich gut gelaufen .

Ach, und was die Konstruktoren betrifft: Du hast einmal einen Konstruktor ohne Priority-Parameter und einmal mit. Wird ein Letter-Objekt erzeugt, kann man also aussuchen, ob man eine Priorität angibt. Falls ja, soll natürlich die angegebene Priorität verwendet werden, falls nein, soll die Standard-Priorität gesetzt werden.

Folgenden Code habe ich herausbekommen und zwar habe ich in der Klasse Delivery einen zweiten Konstruktor hinzugefügt, damit es keinen Compiler Fehler gibt. Die Frage: Muss man das?

Code:
protected Delivery(Location sender, Location receiver, double weight, Priority priority) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }
  
  
    protected Delivery(Location sender, Location receiver, double weight) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }

und in der Klasse Letter habe ich ebenfalls einen zweiten Konstruktor hinzugefügt mit switch case .Frage: wo muss das switch Case hin (im der emun klasse oder wo, und wie schaffe ich es ein Enum hier zu übergeben ?

Der Erste
Code:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter) {
        super(sender, receiver, weight);
        this.registeredLetter = registeredLetter;
       
       
        if (weight < 0.2) {
            postage = 70;
        } else {
            if (weight < 0.5) {
                postage = 200;
            } else {
                postage = 400;
            }
        }
        if (registeredLetter) {
            postage += 300;
        }


Der Zweite Konstruktor

Code:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter,Priority priority) {
        /*super(sender, receiver, weight, priority);
        this.registeredLetter = registeredLetter; */
      
        this(sender,receiver,weight,registeredLetter);
        //String    briefprio = IOTools.readString("Bitte geben sie die Priorität an");  
  
        switch(priority) {
      
        case "Express": priority= priority.EXPRESS;break;
        case "Early Morning": priority= priority.EARLY_MORNING;break;
        case "Evening": priority= priority.EVENING;break;
        default: priority = priority.STANDARD;break;
        {  
        }

Hier habe ich das folgendermaßen ergäntzt. Frage: Wie kann ich es hier übergeben also die Priorität in Kombi mit dem Konsstruktor?
Code:
public static Letter createLetterFromUserInput() {
        System.out.println("Creating new letter...");
        int sender = IOTools.readInt("LocationID of sender:");
        int receiver = IOTools.readInt("LocationID of receiver:");
        double weight = IOTools.readDouble("Weight of letter:");
        boolean registered = IOTools.readBoolean("Registered letter?:");
        String    priority = IOTools.readString("Bitte geben sie die Priorität an");
        Location loc_sender = DeliveryManager.getLocationById(sender);
        Location  loc_receiver = DeliveryManager.getLocationById(receiver);
      //  Priority [] prioritäten = Priority.class.getEnumConstants();
        System.out.println(prioritäten[0]);
          
        if (loc_sender != null && loc_receiver != null && weight >= 0) {
            return new Letter(loc_sender, loc_receiver, weight, registered);
          
        }
      
      
        return null;
    }



lG
Louis
 
Folgenden Code habe ich herausbekommen und zwar habe ich in der Klasse Delivery einen zweiten Konstruktor hinzugefügt, damit es keinen Compiler Fehler gibt. Die Frage: Muss man das?

Java:
protected Delivery(Location sender, Location receiver, double weight, Priority priority) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }
 
 
    protected Delivery(Location sender, Location receiver, double weight) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }

Wenn du Instanzen einer Klasse mit unterschiedlichen (Anzahl oder Typ) Parametern erzeugen möchtest, dann ist das der richtige Weg. Allerdings:

Du ignorierst zumindest im ersten Konstruktor den Parameter "priority", damit ist er überflüssig (das gilt natürlich auch für den zweiten Konstruktor, insofern du eine Standard-Priorität vorgeben möchtest.

Um Wiederholungen zu vermeiden kannst du innerhalb eines Konstruktors einen anderen Konstruktor aufrufen:
Java:
protected Delivery(Location sender, Location receiver, double weight, Priority priority) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
        // priority???
    }
 
protected Delivery(Location sender, Location receiver, double weight) {
        this(sender, receiver, weight, Priority.STANDARD);
    }
 
Folgenden Code habe ich herausbekommen und zwar habe ich in der Klasse Delivery einen zweiten Konstruktor hinzugefügt, damit es keinen Compiler Fehler gibt. Die Frage: Muss man das?
Nein. Du willst nicht Delivery um die Priorität erweitern sondern Letter. Funktioniert also genauso wie mit registeredLetter.

und in der Klasse Letter habe ich ebenfalls einen zweiten Konstruktor hinzugefügt
Das ist richtig.

wo muss das switch Case hin (im der emun klasse oder wo, und wie schaffe ich es ein Enum hier zu übergeben ?
Du brauchst überhaupt kein switch. Der übergebene Parameter ist entweder eine null-Referenz oder referenziert ein Objekt vom Typ Priority.

Was Du tun willst, wenn priority==null gilt, bleibt Dir überlassen (sofern in der Aufgabenstellung nichts dazu steht). Du kannst z. B. eine IllegalArgumentException werfen oder die Standard-Priorität setzen.

Java:
    public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority) {
        super(sender, receiver, weight);
        if (priority != null) {
            this.priority = priority;
        } else {
            this.priority = Priority.STANDARD;
            // oder z. B. throw new IllegalArgumentException("priority is mandatory");
        }
        // bzw. kurz:
        // this.priority = priority != null ? priority : Priority.STANDARD;

        this.registeredLetter = registeredLetter;    
       
        if (weight < 0.2) {
            postage = 70;
        } else {
            if (weight < 0.5) {
                postage = 200;
            } else {
                postage = 400;
            }
        }
        if (registeredLetter) {
            postage += 300;
        }
    }

Den Konstruktor ohne Priority kannst Du nun in der Form umschreiben, wie es @temi gezeigt hat:
Java:
    public Letter(Location sender, Location receiver, double weight, boolean registeredLetter) {
        this(sender, receiver, weight, registeredLetter, Priority.STANDARD);
    }
 
Hallo ,
Erstmal danke für die Antworten 🙂. Ich habe es umgesetzt wie beschrieben, habe leider trotzdem einen Compilerfehler und diesbezüglich Fragen.

Java:
protected Delivery(Location sender, Location receiver, double weight, Priority priority) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
        // priority???
    }

Das soll heißen das ich this.priority = priority; ergänzen soll ?

Java:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority) {
        super(sender, receiver, weight);
        if (priority != null) {
            this.priority = priority;
        } else {
            this.priority = Priority.STANDARD;
            // oder z. B. throw new IllegalArgumentException("priority is mandatory");
        }
        // bzw. kurz:
        // this.priority = priority != null ? priority : Priority.STANDARD;

        this.registeredLetter = registeredLetter; 
    
        if (weight < 0.2) {
            postage = 70;
        } else {
            if (weight < 0.5) {
                postage = 200;
            } else {
                postage = 400;
            }
        }
        if (registeredLetter) {
            postage += 300;
        }
    }
bei super(sender, receiver, weight); habe ich den Compiler und habe es nicht geschafft den wegzubekommen :/.
als ich die möglichen Optionen angewendet habe (Über den Cursor) bekomme den Compiler fehler an der Stelle.

Java:
public Letter(Location sender, Location receiver, double weight, boolean registeredLetter, Priority priority)



und ich habe die Instanzvariable priority auf protectet gesetzt in der Klasse Delivery anders könnte man ja nicht wie bei registedLetter die Variable erweitern( Frgae: ist das Richtig).


Ich würde mich wieder auf eure Antworten freuen 🙂

lG
Louis
 
In Delivery hast Du folgenden Konstruktor:
Java:
    protected Delivery(Location sender, Location receiver, double weight) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }

In Letter die beiden von mir oben genannten. Das wars.
 
In Delivery hast Du folgenden Konstruktor:
Java:
    protected Delivery(Location sender, Location receiver, double weight) {
        this.sender = sender;
        this.receiver = receiver;
        this.date = System.currentTimeMillis();
        this.weight = weight;
    }

In Letter die beiden von mir oben genannten. Das wars.

Danke hat funktioniert !
 
Hallo,
Nun bin ich an einer Aufgabe gestoßen, wo ich nicht genau weiß, ob alles was ich gecodet habe, auch der Aufgabenstellung entspricht bzw. etwas fehlt oder nicht stimmt, deswegen würde ich mich wieder freuen, wenn ihr mir meine Fragen beantworten könntet .

Folgende Aufgabenstellung

Parcel
Statt in einem Array werden die zusätzlichen Transportdienste nun im Konstruktor als Varargs übergeben und in der Instanzvariable services gespeichert.

Implementieren Sie, wie bereits in der Klasse Letter realisiert, einen zusätzlichen Konstruktor, bei dem auch eine Priorität übergeben werden kann.

Implementieren Sie anschließend die Methode isTransportService, welche überprüft, ob ein gegebener Dienst gebucht wurde oder nicht.

Implementieren Sie letztlich alle restlichen geforderten Methoden.
Ein Empfänger eines Pakets soll nur geändert werden, wenn der entsprechende Dienst gebucht wurde (nutzen Sie für diese Überprüfung die Methode isTransportService).

Wurde der Empfänger verändert, soll true zurückgegeben werden, false andernfalls


Statt in einem Array werden die zusätzlichen Transportdienste nun im Konstruktor als Varargs übergeben und in der Instanzvariable services gespeichert.

Also hier muss man nicht mehr diesbezüglich ergänzen?

Code:
public Parcel(Location sender, Location receiver, double weight, int[] size, TransportService... services) {
        super(sender, receiver, weight);
        this.services = services;
        int len = size[0] + size[1] + size[2];
        int vol = size[0] * size[1] * size[2];
       
        if (weight < 1 && len <= 80) {
            category = 'S';
            postage = 300;
        } else {
            if (weight < 4 && vol <= 64000) {
                category = 'M';
                postage = 500;
            } else {
                category = 'L';
                postage = 700;
            }
        }
       
        if (isTransportService(TransportService.PREFERRED_DAY)) {
            postage += 500;
        }
        if (isTransportService(TransportService.TRANSPORT_INSURANCE)) {
            postage += 600;
        }
        if (isTransportService(TransportService.REDIRECTION)) {
            postage += 700;
        }
        if (isTransportService(TransportService.CASH_ON_DELIVERY)) {
            postage += 800;
        }
    }

Implementieren Sie, wie bereits in der Klasse Letter realisiert, einen zusätzlichen Konstruktor, bei dem auch eine Priorität übergeben werden kann.
Ist das Richtig, wenn nein bitte sagen warum ?

Code:
public Parcel(Location sender, Location receiver, double weight,Priority priority, int[] size,TransportService... services) {
    this(sender,receiver,weight,size,services);
    if (priority != null) {
        this.priority = priority;
    } else {
        this.priority = Priority.STANDARD;


Implementieren Sie anschließend die Methode isTransportService, welche überprüft, ob ein gegebener Dienst gebucht wurde oder nicht.
so in etwa ?
Code:
    public boolean isTransportService(TransportService service) {


Implementieren Sie letztlich alle restlichen geforderten Methoden.
Ein Empfänger eines Pakets soll nur geändert werden, wenn der entsprechende Dienst gebucht wurde (nutzen Sie für diese Überprüfung die Methode isTransportService).

Wurde der Empfänger verändert, soll true zurückgegeben werden, false andernfalls

Ist das Anstatzweise Richtig, wenn nein Bitte Grund nennen.

Code:
public boolean isTransportService(TransportService service) {
        //To implement
       
        switch(service) {
       
        case TRANSPORT_INSURANCE : return true;
        case REDIRECTION : return true;
        case PREFERRED_DAY : return true;
        case CASH_ON_DELIVERY : return true;

       
        }
        if(service != null) {
            setReceiver(receiver);
        }
       
       
        return false;
    }



lG
Louis
 
Also hier muss man nicht mehr diesbezüglich ergänzen?
Richtig.
Ist das Richtig, wenn nein bitte sagen warum ?
Jein. Wenn ich den Parcel-Konstruktor ohne Priorität aufrufe, wird die Priorität nicht gesetzt. Daher greift man normalerweise in den allgemeineren Konstruktoren auf die spezielleren zurück, Du machst es umgekehrt.

Ja.

Ist das Anstatzweise Richtig, wenn nein Bitte Grund nennen.
Nein. Die Methode isTransportService soll lediglich zurückgeben, ob der gegebene TransportService ein Element des Arrays services ist.

In der Aufgabenbeschreibung fehlt mir die Methode zum Ändern des Empfängers. Das dürfte eine Methode sein, die eine Location als Parameter erwartet und ein boolean zurückgibt. In dieser Methode musst Du vorab prüfen, ob der betreffende TransportService gebucht ist. Falls nicht, gibst Du einfach false zurück. Falls doch, setzt Du den Empfänger und gibst true zurück.
 

Zurück
Oben