[Java] interfejsy (drzewo binarnych poszukiwań)

Witam, mam problem z poniższym zadaniem, nie wiem za bardzo jak sie do niego zabrać. Za wszelkie podpowiedzi byłbym wdzięczny.

Zdefiniuj abstrakcyjną klasę bazową Wyrazenie, reprezentującą całkowitoliczbowe wyrażenie arytmetyczne. W klasie tej umieść deklarację abstrakcyjnej metody oblicz(), której zadaniem w klasach potomnych będzie obliczanie wyrażenia i przekazywanie wyniku jako wartości typu Long.

Następnie zdefiniuj klasy dziedziczące po klasie Wyrazenie, które będą reprezentowały kolejno liczbę, zmienną (zmienne pamiętaj w statycznej kolekcji TreeMap), operacje arytmetyczne (dwuargumentowe dodawanie, odejmowanie, mnożenie, dzielenie i modulo oraz jednoargumentowa operacja zmiany znaku), porównania (wynikiem porównania ma być jak w języku C liczba 0 albo 1 odpowiadająca wartościom logicznym false albo true), operacje logiczne (negacja, alternatywa i koniunkcja) i inne.

zad.th.gif

Klasy te powinny być tak zaprojektowane, aby można z nich było zbudować drzewo wyrażenia: obiekty klas Liczba lub Zmienna to liście, a operatory to węzły wewnętrzne w takim drzewie. W klasach potomnych zdefiniuj metody oblicz() oraz toString().

Na koniec napisz krótki program testowy, sprawdzający działanie obiektów tych klas. W swoim programie skonstruuj drzewa obliczeń, wypisz je metodą toString() a potem oblicz i wypisz ich wartość dla następujących wyrażeń:

* 7*11+2

* 13-x

* (x-3)/(x+3)

* ((x+1)*x)/2

* 2*x+10

* x%4==0x%100!=0||x%400==0

* !(|x-17|=0)

Na przykład wyrażenie (7-x)*2 należy zdefiniować następująco: Wyrazenie w =

new Mnozenie(

new Odejmowanie(

new Liczba(7),

new Zmienna(“x”)

),

new Liczba(2)

); Ustaw na początku programu testowego zmienną x na wartość –3. Pamiętaj też, aby złapać wyjątek przy próbie dzielenia przez 0.

http://download.oracle.com/javase/tutorial/java/javaOO/index.html

http://download.oracle.com/javase/tutorial/java/IandI/index.html

http://download.oracle.com/javase/tutorial/java/generics/index.html

Zacznij od stworzenia hierarchii klas, którą masz przedstawioną na obrazku.

EDIT: Zrobiłem część tego zadania w ramach treningu w języku C#. Jest on bardzo podobny do Javy, więc powinieneś się połapać co i jak.

Klasa Wyrazenie:

using System;


namespace wyrazenie

{

    public abstract class Wyrazenie

    {

        public abstract long Oblicz();

    }

}

Klasa Zmienna:

using System;

using System.Collections.Generic;


namespace wyrazenie

{

    public class Zmienna : Wyrazenie

    {

        private string nazwa;

        private static Dictionary wartosci = new Dictionary();


        public Zmienna(string nazwa)

        {

            this.nazwa = nazwa;

        }


        public string Nazwa

        {

            get { return nazwa; }

        }


        public static Dictionary Wartosci

        {

            get { return wartosci; }

        }


        public long Wartosc

        {

            get 

            {

                if (Wartosci.ContainsKey(Nazwa))

                    return Wartosci[Nazwa];

                throw new Exception("Zmienna o nazwie " + Nazwa + " nie ma przypisanej wartości.");

            }

        }


        public override long Oblicz()

        {

            return Wartosc;

        }


        public override string ToString()

        {

            return "new Zmienna(\"" + Nazwa + "\")";

        }

    }

}

Klasa Liczba:

using System;


namespace wyrazenie

{

    public class Liczba : Wyrazenie

    {

        private long wartosc;


        public Liczba(long wartosc)

        {

            this.wartosc = wartosc;

        }


        public long Wartosc

        {

            get { return wartosc; }

        }


        public override long Oblicz()

        {

            return Wartosc;

        }


        public override string ToString()

        {

            return "new Liczba(" + Wartosc.ToString() + ")";

        }

    }

}

Klasa Operator1Arg:

using System;


namespace wyrazenie

{

    public abstract class Operator1Arg : Wyrazenie

    {

        private Wyrazenie arg1;


        public Operator1Arg(Wyrazenie arg1)

        {

            this.arg1 = arg1;

        }


        public Wyrazenie Arg1

        {

            get { return arg1; }

        }

    }

}

Klasa WartBezwzgl:

using System;


namespace wyrazenie

{

    public class WartBezwzgl : Operator1Arg

    {

        public WartBezwzgl(Wyrazenie arg1)

            : base(arg1)

        {


        }


        public override long Oblicz()

        {

            long value = Arg1.Oblicz();

            return Math.Abs(value);

        }


        public override string ToString()

        {

            string value = Arg1.ToString();

            return "new WartBezwzgl(" + value + ")";

        }

    }

}

Klasa Operator2Arg:

using System;


namespace wyrazenie

{

    public abstract class Operator2Arg : Operator1Arg

    {

        private Wyrazenie arg2;


        public Operator2Arg(Wyrazenie arg1, Wyrazenie arg2)

            :base(arg1)

        {

            this.arg2 = arg2;

        }


        public Wyrazenie Arg2

        {

            get { return arg2; }

        }

    }

}

Klasa Odejmowanie:

using System;


namespace wyrazenie

{

    public class Odejmowanie : Operator2Arg

    {

        public Odejmowanie(Wyrazenie arg1, Wyrazenie arg2)

            : base(arg1, arg2)

        {


        }


        public override long Oblicz()

        {

            long value1 = Arg1.Oblicz();

            long value2 = Arg2.Oblicz();


            return value1 - value2;

        }


        public override string ToString()

        {

            string value1 = Arg1.ToString();

            string value2 = Arg2.ToString();


            return "new Odejmowanie(" + value1 + "," + value2 + ")";

        }

    }

}

Klasa Program (zawiera deklarację metody Main):

using System;

using wyrazenie;


namespace InheritanceApp

{

    class Program

    {

        static void Main(string[] args)

        {

            Zmienna.Wartosci.Add("x", 8);

            Wyrazenie wyr = new WartBezwzgl(new Odejmowanie(new Liczba(7), new Zmienna("x")));

            Console.WriteLine(wyr.Oblicz().ToString());

            Console.WriteLine(wyr.ToString());


            Console.ReadKey();

        }

    }

}

W wyniku uruchomienia powyższego przykładu otrzymamy:

1

new WartBezwzgl(new Odejmowanie(new Liczba(7),new Zmienna("x")))