StigAL Skrevet 10. oktober 2013 Del Skrevet 10. oktober 2013 (endret) Heisann! Jeg holder på med en oppgave fra boken "Pogrammering i java", og står fast på en oppgave som jeg ikke helt forstår hvordan jeg skal løse. Oppgave Lag en klasse for å regne med brøk.Klassen skal ha to konstruktører: Den ene konstruktøren tar teller og nevner som argument. Hvis neveneren er 0, skal et unntaksobjekt av typen IllegalArgumentException kastes. Den andre konstruktøren tar kun telleren som argument. Da skal nevneren settes lik 1. Klassen skal ha get-metoder, men ikke set-metoder.Klassen skal ha metoder for å summere, subtrahere, multiplisere og dividere en brøk (this) med en annen brøk (parameter til metoden). Metodene har ikke returverdi, men etter at operasjonen er utført, ligger resultatet i this.Du kan se bort fra at resultatet av opersajonen bør forkortes.Lag en testklient som del av klassen.Ekstraoppgave: Sørg for å forkorte brøkene. De to setningene som forvirret meg mest var "Klassen skal ha metoder for å summere, subtrahere, multiplisere og dividere en brøk (this) med en annen brøk (parameter til metoden). Metodene har ikke returverdi, men etter at operasjonen er utført, ligger resultatet i this." Jeg skjønte ikke helt dette med "this". Kapittelet heter "Klasser som byggeklosser", så jeg er ikke på så veldig avansert nivå enda kode-messig. Er takknemmelig for all hjelp jeg kan få! Dette er hva jeg har gjort, vet ikke hvordan jeg skal gjøre dette helt: class Brok { private int nevner; private int teller; public Brok(int teller, int nevner) { this.teller = teller; this.nevner = nevner; } public Brok(int teller) { this.teller = teller; this.nevner = 1; } public void adder(..) { //?? } public void subtraher(..) { //?? } public void multipliser(..) { //?? } public void divider(..) { //?? } } Endret 10. oktober 2013 av BloodySquito Lenke til kommentar
BlueEAGLE Skrevet 10. oktober 2013 Del Skrevet 10. oktober 2013 "this" er navnet på et objekt. For eksempel om du instansierer en klasse som har en variabel x så kan du referer til den som this->x (eller er det this.x i Java?) Du vil da ha behov for en resultatvariabel som inneholder svaret i klassen. Tipper at det å returnere et brøkobjekt blir en oppgave i nær fremtid. Lenke til kommentar
Persn Skrevet 10. oktober 2013 Del Skrevet 10. oktober 2013 "this" er navnet på et objekt. For eksempel om du instansierer en klasse som har en variabel x så kan du referer til den som this->x (eller er det this.x i Java?) Blir this.x i java ja F.eks dette vil returnere klassobjektet. public Broek getBroek(){ return this; } Dette vil returnere variabelen teller innenfor klasseobjektet public int getTeller(){ return this.teller; } Lenke til kommentar
StigAL Skrevet 10. oktober 2013 Forfatter Del Skrevet 10. oktober 2013 (endret) Blir this.x i java ja F.eks dette vil returnere klassobjektet. public Broek getBroek(){ return this; } Dette vil returnere variabelen teller innenfor klasseobjektet public int getTeller(){ return this.teller; } Jeg vet sånn generelt hvordan this viker, tror bare ikke helt jeg skjønte den oppgaven helt. Jeg redigerte inn koden jeg har gjort til nå i innlegget mitt, ellers er jeg helt stuck Endret 10. oktober 2013 av BloodySquito Lenke til kommentar
Persn Skrevet 10. oktober 2013 Del Skrevet 10. oktober 2013 Din første konstruktør er mangefull, les litt på try-catch setninger så skjønner du hva som blir sagt i oppgaven. Du mangler get-metoder som sagt i oppgaveteksten. Skriv inn i alle regnemetodene at de skal ta inn en instans av klassen Broek. La meg hjelpe deg på vei i multiplikasjonen så se om du får til resten. Hva er det som skjer når du multipliserer to brøker? Du ganger tellerne med hverandre, og nevnerne med hverandre. Da er det ikke verre enn at du du gjør det samme i koden og lagrer resultatet i this. Eksempelkode på enkel tallmultiplikasjon: public void multiplyNumber(int newNumber){ this.number = this.number * newNumber; } Testkjøring: public static void main(String[] args){ HelloWorld hw = new HelloWorld(7); System.out.println(hw); // Skal gi utskrift på 7 hw.multiplyNumber(2); System.out.println(hw); // Skal gi utskrift på 14 } Lenke til kommentar
StigAL Skrevet 10. oktober 2013 Forfatter Del Skrevet 10. oktober 2013 Din første konstruktør er mangefull, les litt på try-catch setninger så skjønner du hva som blir sagt i oppgaven. Du mangler get-metoder som sagt i oppgaveteksten. Skriv inn i alle regnemetodene at de skal ta inn en instans av klassen Broek. La meg hjelpe deg på vei i multiplikasjonen så se om du får til resten. Hva er det som skjer når du multipliserer to brøker? Du ganger tellerne med hverandre, og nevnerne med hverandre. Da er det ikke verre enn at du du gjør det samme i koden og lagrer resultatet i this. Eksempelkode på enkel tallmultiplikasjon: public void multiplyNumber(int newNumber){ this.number = this.number * newNumber; } Testkjøring: public static void main(String[] args){ HelloWorld hw = new HelloWorld(7); System.out.println(hw); // Skal gi utskrift på 7 hw.multiplyNumber(2); System.out.println(hw); // Skal gi utskrift på 14 } Med mangelfull, mener du at IllegalArgumentException skal kastes? Ser jeg glemte å ta den med nå ja.. Men bør multiplikasjons-metoden inneholde 2 argumenter, en for teller og en for nevner? Skal se om jeg får fullført oppgaven i morgen, takk for hjelpen! Lenke til kommentar
Persn Skrevet 10. oktober 2013 Del Skrevet 10. oktober 2013 Med mangelfull, mener du at IllegalArgumentException skal kastes? Ser jeg glemte å ta den med nå ja.. Ja Men bør multiplikasjons-metoden inneholde 2 argumenter, en for teller og en for nevner? Nei. Se hva jeg skrev lengre opp, og hva som står i oppgaven. Metodene for regning skal ta inn en BRØK.(HintHint) Lenke til kommentar
jonny Skrevet 11. oktober 2013 Del Skrevet 11. oktober 2013 Her er et (totalt udokumentert) forslag til hvordan en slik klasse kan se ut. Det er gjort noen valg som bryter med oppgaveteksten, det viktigste er at klassen er immutable, slik at et objekt ikke kan endres etter at det er kreert. Dette er kjekt mtp. på bruk i flertrådete systemer. Klassen kan minne litt om klassene Integer, Long osv. Du kan sikkert få noen idéer ved å se på koden. public final class Fraction implements Comparable<Fraction> { private final int numerator; private final int denominator; private int gcd(int n, int d) { if (d == 0) { return n; } else { return gcd(d, n % d); } } public Fraction(int numerator) { this.numerator = numerator; this.denominator = 1; } public Fraction(int numerator, int denominator) { if (denominator == 0) { throw new IllegalArgumentException("Denominator cannot be zero"); } if (denominator < 0) { denominator *= -1; numerator *= -1; } if (numerator == 0) { denominator = 1; } else { int gcd = gcd(numerator, denominator); while (gcd > 1) { numerator /= gcd; denominator /= gcd; gcd = gcd(numerator, denominator); } } this.numerator = numerator; this.denominator = denominator; } public Fraction add(int number) { return new Fraction(numerator + number * denominator, denominator); } public Fraction add(Fraction fraction) { return new Fraction( numerator * fraction.denominator + fraction.numerator * denominator, denominator * fraction.denominator); } public Fraction subtract(int number) { return new Fraction(numerator - number * denominator, denominator); } public Fraction subtract(Fraction fraction) { return new Fraction( numerator * fraction.denominator - fraction.numerator * denominator, denominator * fraction.denominator); } public Fraction multiply(int number) { return new Fraction(numerator * number, denominator); } public Fraction multiply(Fraction fraction) { return new Fraction( numerator * fraction.numerator, denominator * fraction.denominator); } public Fraction divide(int number) { return new Fraction(numerator, denominator * number); } public Fraction divide(Fraction fraction) { return new Fraction( numerator * fraction.denominator, denominator * fraction.numerator); } public float floatValue() { return numerator / (float)denominator; } public double doubleValue() { return numerator / (double)denominator; } @Override public int hashCode() { return numerator + denominator * 37; } @Override public boolean equals(Object obj) { if (!(obj instanceof Fraction)) return false; Fraction other = (Fraction)obj; return ((subtract(other)).numerator == 0); } @Override public String toString() { return numerator + "/" + denominator; } @Override public int compareTo(Fraction o) { return (this.subtract(o)).numerator; } } Lenke til kommentar
StigAL Skrevet 11. oktober 2013 Forfatter Del Skrevet 11. oktober 2013 (endret) Her er et (totalt udokumentert) forslag til hvordan en slik klasse kan se ut. Det er gjort noen valg som bryter med oppgaveteksten, det viktigste er at klassen er immutable, slik at et objekt ikke kan endres etter at det er kreert. Dette er kjekt mtp. på bruk i flertrådete systemer. Klassen kan minne litt om klassene Integer, Long osv. Du kan sikkert få noen idéer ved å se på koden. private final int numerator; private final int denominator; private int gcd(int n, int d) { if (d == 0) { return n; } else { return gcd(d, n % d); } } public Fraction(int numerator) { this.numerator = numerator; this.denominator = 1; } public Fraction(int numerator, int denominator) { if (denominator == 0) { throw new IllegalArgumentException("Denominator cannot be zero"); } if (denominator < 0) { denominator *= -1; numerator *= -1; } if (numerator == 0) { denominator = 1; } else { int gcd = gcd(numerator, denominator); while (gcd > 1) { numerator /= gcd; denominator /= gcd; gcd = gcd(numerator, denominator); } } this.numerator = numerator; this.denominator = denominator; } public Fraction add(int number) { return new Fraction(numerator + number * denominator, denominator); } public Fraction add(Fraction fraction) { return new Fraction( numerator * fraction.denominator + fraction.numerator * denominator, denominator * fraction.denominator); } Jeg forstår det meste av koden, men nivået mitt er nok ikke like avansert. Men om man går tilbake til min kode (litt mindre avansert) så prøvde jeg ut dette: (Uten å forkorte brøken): public class Brok { private int teller; private int nevner; public Brok(int t, int n) { if (n == 0) { throw new IllegalArgumentException("Nevner kan ikke være 0"); } this.teller = t; this.nevner = n; } public Brok(int t) { teller = t; nevner = 1; } public int getNevner() { return nevner; } public int getTeller() { return teller; } public void multipliser(int nyTeller, int nyNevner){ this.nevner = nevner * nyNevner; this.teller = teller * nyTeller; } } Main-klassen: class brokTest { public static void main(String[] args) { Brok brok1 = new Brok(5,2); brok1.multipliser(5,2); int nevner = brok1.getNevner(); int teller = brok1.getTeller(); System.out.println("Resultat: " + teller + "/" + nevner ); } } Dette gikk jo, men er det greit å ha 2 parametere i multipliser-metoden? Jeg ser du bruker kun en parameter "int number" i den første metoden din. Tror det er der jeg faller ut. Jeg har en kontruktør som inneholder en parameter for nevner, og en for teller. Denne skal ganges med en annen brøk som har nevner og teller, da finner jeg ingen andre plasser å hente brøk nummer 2 fra enn utregningsmetoden Endret 11. oktober 2013 av BloodySquito Lenke til kommentar
jonny Skrevet 11. oktober 2013 Del Skrevet 11. oktober 2013 Jeg laget to multiply()-metoder, en for å gange brøken med et heltall, og en for å gange brøken med en annen brøk (den første metoden gjør det bare litt greiere å gange brøken med et heltall, man hadde jo oppnådd det samme med "fraction.multiply(new Fraction(number));"). Når du først har laget en Brok-klasse, synes jeg du bør bruke den som parameter når du skal gange to brøker med hverandre, slik som jeg gjorde. Se litt nærmere på koden, så ser du hvordan du kan gjøre det. Lenke til kommentar
StigAL Skrevet 11. oktober 2013 Forfatter Del Skrevet 11. oktober 2013 Når du først har laget en Brok-klasse, synes jeg du bør bruke den som parameter når du skal gange to brøker med hverandre, slik som jeg gjorde. Se litt nærmere på koden, så ser du hvordan du kan gjøre det. Jeg skal se på det! Det kommer nok sikkert i et av de nærmeste kapitlene i boken også. Uansett,takk for hjelpen! Lenke til kommentar
StigAL Skrevet 13. oktober 2013 Forfatter Del Skrevet 13. oktober 2013 Jeg kom til slutt i mål med oppgaven, men det er nok en god del ting som kan/bør endres, men jeg fikk i hvertfall riktig resultat på de testene jeg kjørte. Poster slutt-resultatet mitt her: Brok-klassen: public class Brok { private int teller; private int nevner; public Brok(int t, int n) { if (n == 0) { throw new IllegalArgumentException("Nevner kan ikke være 0"); } this.teller = t; this.nevner = n; } public Brok(int t) { teller = t; nevner = 1; } public int getNevner() { return nevner; } public int getTeller() { return teller; } public void multipliser(int teller, int nevner){ this.nevner = this.nevner * nevner; this.teller = this.teller * teller; } public void adder(int teller, int nevner) { if(this.nevner != nevner) { this.teller = this.teller * nevner + this.nevner*teller; this.nevner = this.nevner*nevner; } else { this.nevner = nevner; this.teller += teller; } } public void divider(int teller, int nevner) { this.teller *= nevner; this.nevner *= teller; } public void substraher(int teller, int nevner) { if(this.nevner != nevner) { this.teller = this.teller * nevner - this.nevner*teller; this.nevner = this.nevner*nevner; } else { this.nevner = nevner; this.teller -= teller; } } public void forkort() { if(teller > nevner) { //Finner ut om teller eller nevner er størst for(int i = nevner; i > 0; i--) { if(nevner % i == 0 && teller % i == 0) { this.nevner = this.nevner / i; this.teller = this.teller / i; } } } else { for(int i = teller; i > 0; i--) { if(teller % i == 0 && nevner % i == 0) { this.nevner = this.nevner / i; this.teller = this.teller / i; } } } } } Main-klassen: (InterruptedException var bare noe jeg testet ut fra noen oppgaver jeg så senere i boken). class brokTest { public static void main(String[] args) throws InterruptedException { Brok brok1 = new Brok(5,2); Brok brok2 = new Brok(4,2); Brok brok3 = new Brok(8,4); Brok brok4 = new Brok(18,2); brok1.multipliser(5,2); brok1.forkort(); brok2.adder(6,2); brok2.forkort(); brok3.divider(12,4); brok3.forkort(); brok4.substraher(6,4); brok4.forkort(); Thread.currentThread().sleep(2000); System.out.println("Antall tester: 4"); Thread.currentThread().sleep(1500); if(brok1.getNevner() == 4 && brok1.getTeller() == 25){ System.out.println("Test 1: Multiplisering Vellykket"); } else { System.out.println("Test 1: Misslykket\n\nTeller(4) ble " + brok1.getTeller() + "\nNevner(25) ble " + brok1.getNevner()); } Thread.currentThread().sleep(1500); if(brok2.getNevner() == 1 && brok2.getTeller() == 5) { System.out.println("Test 2: Addering Vellykket"); } else { System.out.println("Test 2: Addering misslykket\n\nTeller(5) ble " + brok2.getTeller() + "\nNevner(1) ble " + brok2.getNevner()); } Thread.currentThread().sleep(1500); if(brok3.getTeller() == 2 && brok3.getNevner() == 3) { System.out.println("Test 3: Dividering Vellykket"); } else { System.out.println("Test 3: Dividering misslykket:\n\nTeller(2) ble " + brok3.getTeller() + "\nNevner(3) ble " + brok3.getNevner()); } Thread.currentThread().sleep(1500); if(brok4.getTeller() == 15 && brok4.getNevner() == 2) { System.out.println("Test 4: Substrahering vellykket"); } else { System.out.println("Test 4: Substrahering misslykket:\n\nTeller(15) ble " + brok4.getTeller() + "\nNevner(2) ble " + brok4.getNevner()); } } } Da jeg prøvde å bruke konstruktøren som parameter på utregnings-metodene fikk jeg en kompileringsfeil. public void multipliser(Brok brok){ this.nevner = this.nevner * brok.nevner; this.teller = this.teller * brok.teller; } Dette gav denne kompileringsfeilen: java:10: error: method multipliser in class Brok cannot be applied to given types: brok1.multipliser(5,2); Required: Brok found: int, int reason: actual and formal argument lists differ in lenght 1 error Lenke til kommentar
Persn Skrevet 13. oktober 2013 Del Skrevet 13. oktober 2013 Litt usikker på hva du mener når du sier at du prøvde konstruktøren, men du kan ikke skrive brok1.multipliser(5,2); når metoden er public void multipliser(Brok brok){ Du har skrevet at du skal ta inn en brøk, så da må du lage en brøk og sette inn det. Lenke til kommentar
StigAL Skrevet 14. oktober 2013 Forfatter Del Skrevet 14. oktober 2013 public void multipliser(Brok brok){ Du har skrevet at du skal ta inn en brøk, så da må du lage en brøk og sette inn det. Hvordan bør jeg sette det opp i main-klassen for at det skal virke med (Brok brok) som parameter? Lenke til kommentar
jonny Skrevet 14. oktober 2013 Del Skrevet 14. oktober 2013 (endret) Noe slikt: Brok en = new Brok(1, 2); Brok to = new Brok(2); en.multipliser(to); Det kan kanskje se mer tungvint ut enn denne koden: Brok en = new Brok(1, 2); en.multipliser(2, 1); Men tanken er at når du bruker brøk-klassen aktivt, vil du ha flere brøk-objekter du vil regne med, da ser du fort hva som ser best ut: Brok x = ...; Brok y = ...; ... x.multipliser(y); // vs x.multipliser(y.getTeller(), y.getNevner()); Med koden min (der brøk-objektene ikke kan endres etter de er opprettet) hadde det forøvrig blitt noe slikt: Factor oneHalf = new Factor(1, 2); Factor two = new Factor(2); Factor one = oneHalf.multiply(two); Endret 14. oktober 2013 av jonny Lenke til kommentar
StigAL Skrevet 14. oktober 2013 Forfatter Del Skrevet 14. oktober 2013 Noe slikt: Brok en = new Brok(1, 2); Brok to = new Brok(2); en.multipliser(to); Med koden min (der brøk-objektene ikke kan endres etter de er opprettet) hadde det blitt noe slikt: Factor oneHalf = new Factor(1, 2); Factor two = new Factor(2); Factor one = oneHalf.multiply(two); Takk! Det gjorde koden min en god del ryddigere og lettere å lese! Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå