Thursday, March 29, 2018

7. Kelas Java Tingkat Lanjut Bagian Tiga



Membebani Metode dan Konstruktor
Anda akan melanjutkan untuk memperbaiki kelas Pecahan. Jika diberikan kelas Pecahan seperti pada bentuk sekarang, bagaimana sebuah programer klien mengekspresikan ekspresi matematik berikut?

f3  = 2/3 + 9;

Satu cara adalah dengan mengkonversi integer 9 menjadi sebuah pecahan (9/1) dan kemudian menggunakan metode jumlah():

Pecahan f1, f2, f3;

f1 = new Pecahan(2, 3);
f2 = new Pecahan(9, 1);

f3 = f1.jumlah(f2)

Memang hal itu tidak buruk, tetapi akan lebih baik jika Anda menuliskan seperti ini:

Pecahan f1, f2;

f1 = new Pecahan(2, 3);
f3 = f1.jumlah(9);

Dengan kata lain, Anda tidak melewatkan sebuah objek Pecahan, tetapi hanya melewatkan sebuah nilai integer. Tentu, dengan kelas Pecahan saat ini, statemen:

f3 = f1.jumlah(9);

akan menyebabkan error karena tidak ada metode yang cocok yang didefinisikan di dalam kelas. Jadi, apa yang Anda inginkan di sini adalah memiliki dua versi metode jumlah(), satu yang menerima sebuah objek Pecahan sebagai argumennya dan satu lagi yang menerima sebuah integer sebagai argumennya. Berikut adalah kedua definisi tersebut:

//Versi 1
public Pecahan jumlah(Pecahan pecah) {
   //sama seperti sebelumnya
}

//Versi 2
public Pecahan jumlah(int bilangan) {
   Pecahan jum;
   int a, b, c, d;

   a = getNumerator();
   b = getDenominator();

   c = bilangan;
   d = 1;

   jum = new Pecahan(a*d + c*b, b*d);

   return jum;
}

Jadi, Anda bisa mengujinya dengan kelas berikut:

//Menguji pembebanan metode
public class UjiPecahanPembebananMetode {
   public static void main(String args[]) {
      Pecahan f1, f3;
      
      f1 = new Pecahan(2, 3);
      f3 = f1.jumlah(9);
    
      System.out.println(f1.toString() + " + 9 = " + f3.toString());
   }
}

Keluaran dari program ini diberikan berikut:

2/3 + 9 = 29/3

Dengan metode jumlah() yang kedua, Anda sekarang memiliki dua metode di dalam kelas Pecahan yang memiliki nama sama. Ini bukanlah masalah sepanjang beberapa aturan dipenuhi. Metode-metode yang memiliki nama sama disebut dengan metode-metode terbeban.

Sejumlah nama dapat memiliki nama sama sepanjang salah satu dari dua aturan ini dipenuhi:
  1. Memiliki jumlah parameter berbeda.
  2. Parameter berbeda tipe data ketika jumlah parameter sama.
Kedua metode jumlah() dari kelas Pecahan memenuhi aturan kedua. Berikut adalah sebuah contoh dimana kedua metode memenuhi aturan pertama:

public void metodeKu(int x, int y) { ... }
public void metodeKu(int x) { ... }

Lebih formal dapat dikatakan bahwa dua metode dapat dibebani jika keduanya tidak memiliki sidik yang sama. Sidik metode merujuk pada nama metode dan banyak dan tipe data parameternya. Kedua metode metodeKu memiliki sidik berbeda karena banyak parameter yang dimiliki berbeda.

Dua metode tidak bisa dibebani bila hanya tipe data dari nilai balik metode yang berbeda karena itu berarti kedua metode memiliki sidik yang sama. Sebagai contoh, dua metode berikut tidak bisa didefinisikan pada kelas yang sama:

public double getInfo(String item) { ... }
public int getInfo(String item) { ... }

Sekarang, lihat kembali metode jumlah() yang kedua. Daripada mendefinisikannya seperti sebelumnya, Anda dapat mendefinisikannya dengan memanggil metode jumlah() yang pertama:

//Versi 2 yang lebih ringkas
public Pecahan jumlah(int bilangan) {
   Pecahan pecah = new Pecahan(bilangan, 1);
   Pecahan jum = jumlah(pecah); //memanggil metode jumlah() versi 1

   return jum;
}

Dengan cara yang sama, Anda bisa juga membebani metode bagi(), kali(), dan kurang() seperti berikut:

//Versi 2 bagi() yang ringkas
public Pecahan bagi(int bilangan) {
   Pecahan pecah = new Pecahan(bilangan, 1);
   Pecahan hasil = bagi(pecah); //memanggil metode bagi() versi 1

   return hasil;
}
   
//Versi 2 kali() yang ringkas
public Pecahan kali(int bilangan) {
   Pecahan pecah = new Pecahan(bilangan, 1);
   Pecahan hasil = kali(pecah); //memanggil metode kali() versi 1

   return hasil;
}

//Versi 2 kurang() yang ringkas
public Pecahan kurang(int bilangan) {
   Pecahan pecah = new Pecahan(bilangan, 1);
   Pecahan hasil = kurang(pecah); //memanggil metode kurang() versi 1

   return hasil;
}

Jika digunakan pada kelas penguji seperti berikut, Anda bisa merasakan manfaat dari pembebanan metode:

//Menguji pembebanan metode
public class UjiPecahanPembebananMetode {
   public static void main(String args[]) {
      Pecahan f1, f3;
      
      //Menguji pembebanan pada metode jumlah()
      f1 = new Pecahan(2, 3);
      f3 = f1.jumlah(9);
    
      System.out.println(f1.toString() + " + 9 = " + f3.toString());
      
      //Menguji pembebanan pada metode bagi()
      f1 = new Pecahan(2, 3);
      f3 = f1.bagi(9);
    
      System.out.println(f1.toString() + " / 9 = " + f3.toString());
      
      //Menguji pembebanan pada metode kali()
      f1 = new Pecahan(2, 3);
      f3 = f1.kali(9);
    
      System.out.println(f1.toString() + " * 9 = " + f3.toString());
      
      //Menguji pembebanan pada metode kurang()
      f1 = new Pecahan(2, 3);
      f3 = f1.kurang(9);
    
      System.out.println(f1.toString() + " - 9 = " + f3.toString());
   }
}

Jika dijalankan, program di atas akan menghasilkan keluaran berikut:

2/3 + 9 = 29/3
2/3 / 9 = 2/27
2/3 * 9 = 18/3
2/3 - 9 = -25/3


Membebani Konstruktor
Sampai saat ini, kelas yang telah didefinisikan hanya memuat satu konstruktor. Tetapi konstruktor juga merupakan metode, jadi, dapat pula dibebani. Bahkan, adalah hal yang sangat umum untuk mendefinisikan sejumlah konstruktor pada sebuah kelas. Aturan-aturan yang berlaku pada pembebanan metode juga berlaku pada pembebanan konstruktor. Pendefinisian sejumlah konstruktor untuk sebuah kelas memberikan fleksibilitas bagi programer dalam menciptakan objek-objek kelas. Programer klien dapat memilih salah satu dari beberapa konstruktor yang cocok dengan kebutuhannya. Berikut adalah empat konstruktor (termasuk satu konstruktor yang telah didefinisikan sebelumnya):

//Konstruktor tanpa parameter
public Pecahan() { //menciptakan objek Pecahan dengan nilai awal 0/1
   setNumerator(0);
   setDenominator(1);
}

//Konstruktor satu-parameter int
public Pecahan(int bilangan) { //menciptakan objek pecahan dengan nilai awali bilangan/1
   setNumerator(bilangan);
   setDenominator(1);
}

//Konstruktor satu-parameter objek Pecahan
public Pecahan(Pecahan pecah) { //konstruktor penyalin
   setNumerator(pecah.getNumerator());
   setDenominator(pecah.getDenominator());
}

//Konstruktor dua-parameter int
public Pecahan(int num, int denom) { //konstruktor yang telah didefinisikan sebelumnya
   setNumerator(num);
   setDenominator(denom);
}

Anda dapat menguji keempat konstruktor ini dengan kelas penguji sebagai berikut:

//Menguji pembebanan Konstruktor
public class UjiPembebananKonstruktor {
   public static void main(String args[]) {
      Pecahan f1, f2, f3, f4;
        
      //Memanggil konstruktor tanpa parameter
      f1 = new Pecahan();
      System.out.println("Isi dari objek f1 = " + f1.toString());
      
      //Memanggil konstruktor satu-parameter int
      f2 = new Pecahan(7);
      System.out.println("Isi dari objek f2 = " + f2.toString());
      
      //Memanggil konstruktor penyalin satu-parameter objek Pecahan
      f3 = new Pecahan(f1);
      System.out.println("Isi dari objek f3 = f1 = " + f3.toString());
      
      //Memanggil konstruktor dua-parameter int
      f4 = new Pecahan(3,7);
      System.out.println("Isi dari objek f1 = " + f4.toString());
   }
}

Jika dijalankan, program di atas akan menghasilkan keluaran berikut:

Isi dari objek f1 = 0/1
Isi dari objek f2 = 7/1
Isi dari objek f3 = f1 = 0/1
Isi dari objek f1 = 3/7

Sintaksis untuk memanggil sebuah konstruktor dari konstruktor lain pada kelas yang sama adalah:

this(<daftar-parameter>);

Konstruktor dengan daftar parameter yang cocok akan dipanggil. Anda dapat menambahkan statemen-statemen lain setelah statemen ini di dalam sebuah konstruktor, tetapi bukan sebelumnya. Dengan kata lain, pemanggilan terhadap this pada sebuah konstruktor harus menjadi statemen pertama dari konstruktor.

Berikut merupakan keempat konstruktor yang telah didefinisikan di atas dengan versi menggunakan katakunci this:

//Konstruktor tanpa parameter
public Pecahan() { //menciptakan objek Pecahan dengan nilai awal 0/1
   this(0,1); //memanggil konstruktor dua-parameter int
}

//Konstruktor satu-parameter int
public Pecahan(int bilangan) { //menciptakan objek pecahan dengan nilai awali bilangan/1
   this(bilangan,1); //memanggil konstruktor dua-parameter int
}

//Konstruktor satu-parameter objek Pecahan
public Pecahan(Pecahan pecah) { //konstruktor penyalin
   //memanggil konstruktor dua-parameter int
   this(pecah.getNumerator(), pecah.getDenominator());
}

//Konstruktor dua-parameter int
public Pecahan(int num, int denom) { //konstruktor yang telah didefinisikan sebelumnya
   setNumerator(num);
   setDenominator(denom);
}

Anda bisa menguji keempat konstruktor ini dengan kelas penguji yang sama untuk mendapatkan keluaran program yang persis sama.


SOAL DAN JAWABAN:
Apakah ada konflik pada ketiga konstruktor berikut untuk KelasX?:

public KelasX(int X) {
   ...
}

public KelasY(float X) {
   ...
}

public KelasX(int Y) {
   ...
}

JAWAB:
Ya, karena terdapat dua konstruktor KelasX yang memiliki sidik sama, yaitu konstrukor yang memiliki satu parameter int.



Definisikanlah sebuah kelas Siswa. Kelas ini memiliki anggota data nama. Definisikanlah dua konstruktor, satu tanpa argumen apapun dan konstruktor lain dengan nama siswa sebagai argumennya. Inisialisasi nama dengan nilai default “Tidak dikenal” untuk konstruktor tanpa argumen.

JAWAB:
Berikut adalah kelas Siswa yang memiliki dua konstruktor seperti yang diinginkan. Satu konstruktor tidak memiliki argumen apapun dan konstruktor lain memiliki nama siswa sebagai argumennya. Inisialisasi nama dengan nilai default “Tidak dikenal” untuk konstruktor tanpa argumen. Kelas ini juga dilengkapi dengan sebuah aksesor dan sebuah mutator. Kelas ini juga mendefinisikan ulang metode toString():

class Siswa {
   private String nama;
   
   // Aksesor
   public String getNama( ) {
      return nama;
   }
   
   // Mutator
   public void setNama(String nama) {
      this.nama = nama;
   }
   
   //Konstruktor tanpa-parameter
   public Siswa() {
  this("Tidak Dikenali");  
   }
   
   //Konstruktor satu-parameter
   public Siswa(String nama) {
    setNama(nama);
   }
   
   public String toString( ) {
      return this.nama;
   }
}

Anda bisa menuliskan kelas pengujinya sebagai berikut:

public class UjiSiswa {
   public static void main(String args[]) {
      Siswa s1, s2;
      
      //Menguji konstruktor tanpa-parameter
      s1 = new Siswa();
      System.out.println("Nama siswa = " + s1.toString());
      
      //Menguji konstruktor satu-parameter
      s2 = new Siswa("Vivian");
      System.out.println("Nama siswa = " + s2.toString());
   }
}

Ketika program di atas dijalankan, keluaran program yang dihasilkan adalah berikut:

Nama siswa = Tidak Dikenali
Nama siswa = Vivian


Tulis-ulanglah konstruktor-konstruktor berikut, sehingga konstruktor pertama memanggil konstruktor kedua:

public class KelasSatu {
   private int alfa, beta;
 
   public KelasSatu(int alfa) {
      this.alfa = alfa;
      this.beta = 0;
   }
  
   public KelasSatu(int alfa, int beta) {
      this.alfa = alfa;
      this.beta = beta;
   }
}

JAWAB:
Berikut adalah versi KelasSatu dimana konstruktor pertama memanggil konstruktor keduanya:

public class UjiKelasSatu {
   public static void main(String args[]) {
      KelasSatu k1, k2;
        
      //Menguji konstruktor tanpa-parameter
      k1 = new KelasSatu(7);
      System.out.println(k1.toString());
        
      //Menguji konstruktor satu-parameter
      k2 = new KelasSatu(3,5);
      System.out.println(k2.toString());
   }
}

Ketika program di atas dijalankan, keluaran program yang dihasilkan adalah berikut:

Nilai dari alfa dan beta = 7 dan 0
Nilai dari alfa dan beta = 3 dan 5







7. Kelas Java Tingkat Lanjut Bagian Dua



Penggunaan katakunci this sebenarnya opsional. Jika Anda tidak mencantumkannya secara eksplisit, maka kompilator akan menyisipkannya untuk Anda. Sebagai contoh, jika Anda menuliskan:

class Contoh {
   public void m1( ) {
   ...
   }

   public void m2( ) {
      m1();
   }
}

maka kompilator akan menginterpretasikan definisi di atas sebagai:

class Contoh {
   public void m1( ) {
   ...
   }

   public void m2( ) {
      this.m1();
   }
}

Inilah alasan mengapa Anda memanggil sebuah metode dari metode lain pada kelas yang sama tanpa menggunakan notasi atau operasi dot.

Metode untuk ketiga operasi aritmatika lain didefinisikan dengan cara yang sama:

public Pecahan bagi(Pecahan pecah) {
   int a, b, c, d;
   Pecahan sisa;

   a = this.getNumerator();
   b = this.getDenominator();

   c = pecah.getNumerator();
   d = pecah.getDenominator();

   sisa = new Pecahan(a*d, b*c);

   return sisa;
}

public Pecahan kali(Pecahan pecah) {
   int a, b, c, d;
   Pecahan hasil;

   a = this.getNumerator();
   b = this.getDenominator();

   c = pecah.getNumerator();
   d = pecah.getDenominator();

   hasil = new Pecahan(a*c, b*d);

   return hasil;
}

public Pecahan kurang(Pecahan pecah) {
   int a, b, c, d;
   Pecahan selisih;

   a = this.getNumerator();
   b = this.getDenominator();

   c = pecah.getNumerator();
   d = pecah.getDenominator();

   selisih = new Pecahan(a*d  b*c, b*d);

   return selisih;
}

Anda bisa saja mendefinisikan empat metode aritmatika sebagai metode void, tidak menghasilkan nilai balik berupa objek Pecahan. Tetapi, dengan melakukannya, Anda tidak memiliki fleksibilitas. Karena metode yang didefinisikan adalah metode penghasil-objek, maka Anda dapat menuliskan:

f3 = f1.jumlah(f2); 

yang merefleksikan ekspresi matematik secara natural:

f3 = f1 + f2

Selain itu, karena metode jumlah() menghasilkan sebuah objek Pecahan sebagai hasil penjumlahannya, Anda bisa menuliskan statemen untuk penjumlahan jamak. Misalnya, ekspresi matematik:

f4 = f1 + f2 + f3

dapat dituliskan sebagai:

f4 = f1.jumlah(f2.jumlah(f3));

dimana penjumlahan atas f2 dan f3 dilewatkan sebagai argumen kepada metode jumlah() dari objek f1. Anda dapat pula menuliskan ekspresi tersebut dengan:

f4 = f1.jumlah(f2).jumlah(f3);

karena f1.jumlah(f2) mereferensi ke sebuah objek Pecahan tak-bernama, dan Anda bisa memanggil metode jumlah() dari objek tak-bernama ini dengan objek f3 sebagai argumennya.

Anda bisa menguji keempat operasi aritmatika tersebut dengan cara berikut:

//Menguji kelas Pecahan untuk keempat operasi aritmatika
public class UjiPecahan3 {
   public static void main(String args[]) {
      Pecahan f1, f2, f3;
    
      f1 = new Pecahan(1, 2);
      f2 = new Pecahan(1, 4);
      
      //Menguji operasi penjumlahan
      f3 = f1.jumlah(f2);
   
      System.out.println("Penjumlahan atas " + f1.toString() + " dan " +
    f2.toString() + " adalah " + f3.toString());
      
      //Menguji operasi perkalian
      f3 = f1.kali(f2);
   
      System.out.println("Perkalian atas " + f1.toString() + " dan " +
    f2.toString() + " adalah " + f3.toString());

      //Menguji operasi pembagian
      f3 = f1.bagi(f2);
   
      System.out.println("Pembagian atas " + f1.toString() + " dengan " +
    f2.toString() + " adalah " + f3.toString());

      //Menguji operasi pengurangan
      f3 = f1.kurang(f2);
   
      System.out.println("Selisih " + f1.toString() + " dari " +
    f2.toString() + " adalah " + f3.toString());            
 }
}

Jika dijalankan, program di atas menghasilkan keluaran berikut:

Penjumlahan atas 1/2 dan 1/4 adalah 6/8
Perkalian atas 1/2 dan 1/4 adalah 1/8
Pembagian atas 1/2 dengan 1/4 adalah 4/2
Selisih 1/2 dari 1/4 adalah 2/8

Anda juga bisa menguji keempat operasi matematika tersebut untuk operasi-operasi jamak sebagai berikut:

//Menguji kelas Pecahan untuk keempat operasi aritmatika
public class UjiPecahan3 {
   public static void main(String args[]) {
      Pecahan f1, f2, f3, f4;
    
      f1 = new Pecahan(1, 2);
      f2 = new Pecahan(1, 4);
      f3 = new Pecahan(2, 3);
      
      //Menguji operasi penjumlahan jamak
      f4 = f1.jumlah(f2).jumlah(f3);
   
      System.out.println("Penjumlahan atas " + f1.toString() + " dan " +
    f2.toString() + " dan dijumlah lagi dengan " + f3.toString() + " dan " + 
          f4.toString());
           
      //Menguji operasi perkalian jamak
      f4 = f1.kali(f2).kali(f3);
   
      System.out.println("Perkalian atas " + f1.toString() + " dan " +
         f2.toString() + " dan dikali lagi " + f3.toString() + " dan " + f4.toString());

      //Menguji operasi pembagian
      f4 = f1.bagi(f2).bagi(f3);
   
      System.out.println("Pembagian atas " + f1.toString() + " dibagi oleh " +
         f2.toString() + " dan dibagi lagi oleh " + f3.toString() + " adalah " + 
         f4.toString());

      //Menguji operasi pengurangan jamak
      f4 = f1.kurang(f2).kurang(f3);
   
      System.out.println("Pengurangan atas " + f1.toString() + " dari " +
         f2.toString() + " dan dikurangi lagi dari " + f3.toString() + " adalah " + 
         f4.toString());           
   }
}

Jika dijalankan, program di atas menghasilkan keluaran berikut:

Penjumlahan atas 1/2 dan 1/4 dan dijumlah lagi dengan 2/3 dan 34/24
Perkalian atas 1/2 dan 1/4 dan dikali lagi 2/3 dan 2/24
Pembagian atas 1/2 dibagi oleh 1/4 dan dibagi lagi oleh 2/3 adalah 12/4
Pengurangan atas 1/2 dari 1/4 dan dikurangi lagi dari 2/3 adalah -10/24


Penggunaan Lain dari Operator this
Perhatikan deklarasi kelas berikut:

class CDMusik {
   private String artis;
   private String judul;
   private String id;

   public CDMusik(String nama1, String nama2) {
      artis = nama1;
      judul = nama2;
      id = artis.substring(0,2) + "-" + judul.substring(0,9);
   }

   ...
}

Konstruktor memiliki dua argumen String, satu untuk artis dan satu lagi untuk judul. Anggota id untuk objek CDMusik ditetapkan dua huruf pertama dari nama artis yang diikuti dengan tanda-hubung dan sembilan huruf pertama dari judul.

Sekarang, perhatikan apa yang terjadi jika Anda mencantumkan (katakanlah, secara tidak sengaja) sebuah deklarasi lokal untuk pengenal id seperti ini:

public CDMusik(String nama1, String nama2) {
   String id;
      
   artis = nama1;
   judul = nama2;

   id = artis.substring(0,2) + "-" + judul.substring(0,9);
}

Karena ada deklarasi lokal yang cocok untuk id, pengenal itu merujuk ke variabel lokal, bukan anggota data ketiga dari kelas lagi. Ketika sebuah pengenal dijumpai pada suatu metode, aturan-aturan berikut berlaku:

  1. Jika ada deklarasi variabel atau parameter yang cocok, maka pengenal merujuk ke variabel lokal atau parameter.
  2. Jika tidak ada, dan jika ada deklarasi anggota data kelas yang cocok, maka pengenal merujuk ke anggota data tersebut.
  3. Jika aturan nomor 1 dan 2 tidak terjadi, maka akan terjadi error kompilasi.

Mengapa kompilator Java tidak menangkap error semacam itu? Mengapa seseorang ingin menggunakan pengenal sama untuk anggota data kelas dan variabel lokal atau parameter lokal? Anda direkomendasikan untuk tidak melakukannya. Anda sebaiknya menggunakan pengenal berbeda untuk anggota data kelas dan untuk variabel lokal. Tetapi ada situasi dimana Anda ingin menggunakan pengenal yang sama untuk anggota data kelas dan untuk variabel lokal. Pada konstruktor CDMusik, Anda mendeklarasikan nama1 dan nama2 untuk menghindari konflik penamaan. Untuk menghindari konflik penamaan, Anda bisa memanfaatkan katakunci this sebagai berikut:

public CDMusik(String artis, String judul) {
   this.artis = artis;
   this.judul = judul;
   id = artis.substring(0,2) + "-" + judul.substring(0,9);
}

Dengan mengikuti aturan-aturan yang telah dijelaskan di atas, pengenal artis merujuk ke parameter metode. Untuk mereferensi anggota data artis dari dalam konstruktor ini, Anda mengawali pengenal artis dengan katakunci this, menggunakan notasi dot, sebagai this.artis. Pada konstruktor modifikasi tersebut, Anda tidak menggunakan katakunci this untuk mereferensi anggota data id karena itu tidak diperlukan. Penggunaannya opsional, jadi Anda bisa saja menuliskannya dengan:

this.id = artis.substring(0,2) + "-" + judul.substring(0,9);

untuk membuat kode tampak konsisten. Katakunci this dapat selalu dipakai untuk mereferensi anggota-anggota data dari objek penerima, meskipun tidak ada konflik penamaan.


SOAL DAN JAWABAN:
Tuliskan sebuah statemen tunggal dan implementasikan dalam sebuah kelas uji untuk mengekspresikan operasi pecahan berikut, menggunakan metode-metode dari kelas Pecahan:

f5 = (f1 + f2) / (f3  f4)

JAWAB:
Berikut adalah program untuk menguji ekspresi di atas:

//Menguji kelas Pecahan
public class UjiPecahan {
   public static void main(String args[]) {
      Pecahan f1, f2, f3, f4, f5;
   
      f1 = new Pecahan(1, 2);
   f2 = new Pecahan(1, 3);
   f3 = new Pecahan(2, 3);
   f4 = new Pecahan(2, 11);
   
   //Jawaban
   f5 = (f1.jumlah(f2)).bagi(f3.kurang(f4));
  
      System.out.println("f5 = (f1 + f2) / (f3 – f4)" + " = " + f5.toString());
 }
}


Jika metode jumlah() didefinisikan sebagai berikut:

public void jumlah(Pecahan pecah) {
   int a, b, c, d;

   a = this.getNumerator();   //membaca num dan denom
   b = this.getDenominator(); //dari objek penerima

   c = pecah.getNumerator();   //membaca num dan denom
   d = pecah.getDenominator(); //dari objek pecah

   setNumerator(a*d + b*c); //memperbarui num dan denom
   setDenominator(b*d);    //dari objek penerima
}

Apa yang salah dengan memanggil metode sebagai berikut?


f3 = f1.jumlah(f2);

JAWAB:
Hasil dari f1.jumlah(f2) bukanlah objek Pecahan, jadi tidak bisa ditugaskan kepada objek f3. Jika ini dilakukan, maka akan dihasilkan error kompilasi.

Berikut adalah kelas Pecahan2 dimana di dalamnya metode jumlah() didefinisikan seperti yang diberikan pada soal ini:

//Mendemonstrasikan kelas Pecahan2
class Pecahan2 {
private int numerator;
private int denominator;

// Konstruktor dua-parameter
public Pecahan2(int num, int denom) {
   setNumerator(num);
   setDenominator(denom);
}
 
// Aksesor
public int getDenominator( ) {
   return denominator;
}
 
// Aksesor
public int getNumerator( ) {
   return numerator;
}
 
// Mutator
public void setDenominator(int denom) {
   if (denom == 0) {
      //Error fatal
      System.err.println("Error Fatal");
      System.exit(1);
   }
  
   denominator = denom;
}
  
// Mutator
public void setNumerator(int num) {
   numerator = num;
}
  
public String toString( ) {
   return getNumerator() + "/" + getDenominator();
}

public void jumlah(Pecahan2 pecah) {
    int a, b, c, d;

    a = this.getNumerator();   //membaca num dan denom
    b = this.getDenominator(); //dari objek penerima

    c = pecah.getNumerator();   //membaca num dan denom
    d = pecah.getDenominator(); //dari objek pecah

    setNumerator(a*d + b*c); //memperbarui num dan denom
    setDenominator(b*d);    //dari objek penerima
 }
}

Dengan definisi metode jumlah() seperti di atas, operasi penjumlahan pecahan dapat dilakukan seperti berikut:

//Menguji kelas Pecahan2
public class UjiPecahan2 {
   public static void main(String args[]) {
      Pecahan2 f1, f2, f3;
      int pemb, peny;
 
      f1 = new Pecahan2(1, 7);
      f2 = new Pecahan2(2, 3);
   
   //Dalam soal, error terjadi karena
      //jumlah() tidak menghasilkan nilai balik
      //berupa sebuah objek Pecahan
      //f3 = f1.jumlah(f2);
      
      //Jadi, yang dilakukan adalah memanggil metode jumlah() dari objek f1
      //dengan objek f2 sebagai argumennya. Hasil penjumlahan tersimpan
      //pada anggota data numerator dan denominator dari objek f1
      f1.jumlah(f2);
      
      //Sekarang, objek f1 menyimpan hasil penjumlahan tersebut dengan pembuktian ini
      pemb = f1.getNumerator();
      peny = f1.getDenominator();
      System.out.println("Pembilang dari f1" + " = " + pemb);
      System.out.println("Penyebut dari f1" + " = " + peny);
      
     //Untuk memberikan anggota data objek dari f1 kepada f3
     f3 = f1; 
     
     System.out.println("Pembilang dari f3" + " = " + f3.getNumerator());
     System.out.println("Penyebut dari f3" + " = " + f3.getDenominator());
 }
}


Tuliskanlah statemen-statemen untuk menugaskan penjumlahan atas pecahan f1 dan f2 kepada pecahan f3, menggunakan metode jumlah() yang didefinisikan pada nomor 2.

JAWAB:

f1.jumlah(f2);
//Cara kedua menugaskan anggota data f1 kepada f3 adalah:
f3.setDenominator(f1.getDenominator());
f3.setNumerator(f1.getNumerator());
     
System.out.println("Pembilang dari f3" + " = " + f3.getNumerator());
System.out.println("Penyebut dari f3" + " = " + f3.getDenominator());


Selanjutnya  >>>