Problem mit Interfaces!



  • Hallo Hallo, der Javanoob is wieder da :xmas1:

    Folgendes:

    Habe ein Interface:
    Expression.java

    interface Expression {
    
    	public int getValue();	//public wird von Compiler ergänzt, falls nicht explizit angegeben
    
    }
    

    Dieses Interface wird von der Klasse Binary u. a. implementiert:
    Binary.java

    class Binary implements Expression {
    
    		private int value;	//Wert des zusammengestzten Ausdrucks
    		private Operator operator;
    		private Expression expOne;
    		private Expression expTwo;
    
    		//Konstruktor für einen zusammengesetzten Ausdruck
    		Binary(Operator operator, Expression expOne, Expression expTwo)
    		{	
    			this.operator = operator;
    
    			this.expOne = expOne;
    
    			this.expTwo = expTwo;
    
    			if ( operator == Operator.Add )
    				value = expOne.getValue() + expTwo.getValue();
    
    			if ( operator == Operator.Sub )
    				value = expOne.getValue() - expTwo.getValue();
    
    			if ( operator == Operator.Mult )
    				value = expOne.getValue() * expTwo.getValue();
    
    			if ( operator == Operator.Div )
    				if ( expTwo.getValue() == 0 )
    					return;
    				else
    					value = expOne.getValue() / expTwo.getValue();				
    		} 
    
    		//Getter für value
    		public int getValue()
    		{
    			return value;
    		}
    
    		//toInfix() liefert die lesbare Form eines Ausdrucks als String
    		String toInfix()
    		{
    			String result;
    
    			result = "(";
    
    			if ( expOne instanceof Binary )
    				result += expOne.toInfix();
    			else				
    				result += expOne.getValue();
    
    			if ( operator == Operator.Add )
    				result += " + ";
    			if ( operator == Operator.Sub )
    				result += " - ";
    			if ( operator == Operator.Mult )
    				result += " * ";
    			if ( operator == Operator.Div )
    				result += " / ";
    
    			if ( expTwo instanceof Binary )
    				result += expTwo.toInfix();
    			else
    				result += expTwo.getValue();
    
    			result += ")";
    
    			return result;
    		}	
    }
    

    Die Funktion toInfix() ist ja nur in der Klasse Binary.java definiert und
    wird auch nur dort gebraucht! Liegt es an der Rekursion, das ich folgenden
    Fehler erhalte?

    michi@Mobileblub:~/LAGER/JavaPraktikum/Aufgaben_8$ javac test.java
    ./Binary.java:67: cannot find symbol
    symbol  : method toInfix()
    location: interface Expression
                                    result += expOne.toInfix();
                                                    ^
    ./Binary.java:83: cannot find symbol
    symbol  : method toInfix()
    location: interface Expression
                                    result += expTwo.toInfix();
                                                    ^
    2 errors
    

    Testen tu ich das ganze so:

    class test {
    
    	public static void main(String... args)
    	{
    
    		Variable v = new Variable("x");
    		v.setValue(4);
    
    		Binary e = new Binary(Operator.Add, new Binary(Operator.Mult, v, new Numeral(2)), new Binary(Operator.Mult, new Numeral(3), new Numeral(3)));
    
    		System.out.println(e.toInfix());	
    
    		System.out.println(e.getValue());
    
    	}
    }
    

    Wenn ich die Funktion toInfix() ins Interface mit aufnehme funktioniert´s.
    Warum nicht ohne Interfacefunktion?

    Danke für alle Antworten 👍

    michi



  • ähm ja

    du gibts dir grade selber die antwort und deine lösung. wenn du eine expresion hast.

    private Expression expOne;
            private Expression expTwo;
    

    dann kennen die auch nur die Methoden die in Expression deklarirt wurden.

    interface Expression {
    
        public int getValue();    //public wird von Compiler ergänzt, falls nicht explizit angegeben
    
    }
    

    somit sind die aufrure

    if ( expOne instanceof Binary )
                    result += expOne.toInfix();
        ...
        if ( expTwo instanceof Binary )
                    result += expTwo.toInfix();
    

    natürlich nicht gültig.

    versuchs mal mit nem cast

    if ( expOne instanceof Binary )
                    result += ((Binary )expOne).toInfix();
        ...
        if ( expTwo instanceof Binary )
                    result += ((Binary )expTwo).toInfix();
    

    dann sollte das tun

    gruss



  • mit instanceof testest du zwar, dass es ein Binary ist, aber die VM weiss davon ja nichts.

    du musst also folgendes machen:

    if ( expTwo instanceof Binary )
    {
      Binary temp=(Binary)expTwo;
      result += temp.toInfix();
    }
    else
      result += expTwo.getValue();
    

    die VM macht ja keine logische analyse des codes, sondern nur eine syntaktische. und eine Expression hat halt kein toInfix() du musst der VM also explizit sagen: das ist jetzt ein Binary



  • Danke an Euch beide!
    Ich denke, dass ichs verstanden hab. (Thema dynamisches Binden)
    Der Compiler kann ja zur Compilezeit nicht wissen, das expOne ein BinaryObjekt ist
    und die Methode toInfix() besitzt, da der statische Typ ja ein ExpressionObjekt ist und nur das vom Compiler nach der Methode to toInfix() durchsucht wird.
    Ein expliziter Cast lässt ihn dann aber doch schweigen!

    Hab ich etwas falsch beschrieben?

    Danke 👍



  • curry-king schrieb:

    Hab ich etwas falsch beschrieben?

    Nein, alles korrekt 👍


Anmelden zum Antworten