Bagaimana cara menghentikan metode pemanggilan objek kelas anak dari kelas induk meskipun metode yang sama juga ada di kelas anak

Saya memiliki objek bertipe ElectronicProduct yang memperluas Produk, saya mencoba memanggil metode loadFromFile() dari dalam kelas anak, memberikan nama dan tipe argumen yang tepat, namun objek kelas anak malah memanggil loadFromFile() dari kelas induk. Bagaimana cara menghentikan ini?

Kodenya adalah sebagai berikut:

ElectronicProduct eProduct = new ElectronicProduct();
eProduct.loadFromFile(eProduct,bin); 

namun itu memanggil metode di kelas induk di bawah ini:

public Product loadFromFile(Product aProduct, BufferedReader bin) throws IOException, ParseException{ 

   //some code 

}

alih-alih kelas anak yang ditunjukkan di bawah ini:

public ElectronicProduct loadFromFile(Product aProduct, BufferedReader bin) throws IOException, ParseException{

// Some code

}

Saya memang mencoba menggunakan @Override dalam metode kelas anak, tetapi karena yang satu mengembalikan produk dan yang lain mengembalikan produk elektronik, penggantian tersebut sepertinya tidak berhasil. Bantuan apa pun akan sangat dihargai.

Sunting

Ini sangat aneh karena sekarang sudah mulai berfungsi sesuai keinginan saya, tanpa mengubah apa pun. Skenario yang berbeda tetapi hal serupa terjadi sebelumnya yang memberikan peringatan kesalahan, saya menghapus kode dan menulis hal yang persis sama, dan kemudian berfungsi. Saya tidak ingin hal ini terjadi secara acak karena ini adalah tugas yang dinilai. Tidak mau keluar topik tapi harus berkaitan. Mohon sarannya jika ada yang tahu apa yang baru saja terjadi?

EDIT*2

Menanggapi komentar dari Tiffado, alasan objek Produk diteruskan dan bukan objek Produk Elektronik, adalah karena dalam metode kelas anak, objek Produk diteruskan ke kelas induk. Jika saya memasukkan objek kelas anak ke dalam metode anak yang kemudian meneruskan objek tersebut ke metode induk, itu mungkin tidak berfungsi, karena saya telah mengetahui bahwa kelas induk tidak 'melihat' kelas anak. Harap perbaiki saya jika ini salah.

public ElectronicProduct loadFromFile(Product aProduct, BufferedReader bin) throws IOException, ParseException{


ElectronicProduct eProduct = new ElectronicProduct();

eProduct = (ElectronicProduct)super.loadFromFile(aProduct,bin);

eProduct.setGuarunteeDuration(Integer.valueOf(bin.readLine()));

return eProduct;

}

person InitialisingAttributes    schedule 05.02.2020    source sumber
comment
Metode penggantian diperbolehkan untuk mengembalikan tipe yang lebih spesifik (sejak Java 5). Kami tidak tahu apa yang Anda lakukan sebelumnya, jadi kami tidak bisa mengatakan kesalahan apa yang Anda lakukan.   -  person Holger    schedule 05.02.2020


Jawaban (2)


Tidak ada cara bagi kompiler untuk mengetahui perbedaan antara kedua metode Anda: Anda perlu menentukan urutan parameter yang berbeda pada tanda tangan metode, jumlah parameter, tetapi tidak ada tipe parameter subkelas atau tipe pengembalian subkelas yang akan membuat perbedaan:

Metode:

public Product loadFromFile(Product aProduct, BufferedReader bin) throws IOException, ParseException{ 

Sama saja dengan

public ElectronicProduct loadFromFile(Product aProduct, BufferedReader bin) throws IOException, ParseException{

karena tipe pengembalian (Produk Elektronik) adalah subkelas Produk, jadi penggunaan polimorfisme bukan bagian dari tanda tangan metode.

Lihat juga: "Tanda tangan metode Java hanya mengambil nama metode dan nomor serta jenis parameter", tersedia di: https://docs.Oracle.com/javase/tutorial/java/javaOO/methods.html

Silakan lihat contoh berikutnya, yang mana, dengan mengesampingkan aturan, akan memanggil metode anak, namun karena ada panggilan hardcode ke induk, metode tersebut juga akan memanggil induk:

public class Product {

  static int productIdentifier = 0;
  static int electronicProductIdentifier = 0;

    public Product loadFromFile( Product aProduct ) {

    System.out.println("Call loadFromFile from Product");
        Product product = new Product();
        return product;

    }

  public Product ()  {
    System.out.println("Creating a Product with ID " + 
            ( ++ productIdentifier ) );
  }

}


public class ElectronicProduct extends Product {

    public ElectronicProduct loadFromFile( Product aProduct ) {

    System.out.println("Call loadFromFile from ElectronicProduct");
        ElectronicProduct eProduct = new ElectronicProduct();
    super.loadFromFile( eProduct ); // Hardcoded call to parent!
        return eProduct;

    }

  public ElectronicProduct ()  {
    System.out.println("Creating an ElectronicProduct with ID " + 
            ( ++ electronicProductIdentifier ) );
  }

}

Product p = new Product();
ElectronicProduct ep = new ElectronicProduct();
ep.loadFromFile( ep );

Keluaran:

Creating a Product with ID 1
Creating a Product with ID 2
Creating an ElectronicProduct with ID 1
Call loadFromFile from ElectronicProduct
Creating a Product with ID 3
Creating an ElectronicProduct with ID 2
Call loadFromFile from Product
Creating a Product with ID 4

(Ada panggilan loadFromFile() dari produk, karena dipanggil secara eksplisit dari ElectronicProduct.loadFromFile() )

Jika Anda mengomentari saluran yang memanggil super.loadFromFile(), Anda tidak akan melihat panggilan ke Product.loadFromFile():

Creating a Product with ID 1
Creating a Product with ID 2
Creating an ElectronicProduct with ID 1
Call loadFromFile from ElectronicProduct
Creating a Product with ID 3
Creating an ElectronicProduct with ID 2
person Victor Polo De Gyves Montero    schedule 05.02.2020
comment
Terima kasih atas wawasan ini, namun menurut saya kompiler secara otomatis memilih metode kelas anak jika diberi pilihan. apakah ini salah? - person InitialisingAttributes; 05.02.2020
comment
Anda benar. karena ini adalah penggantian metode, maka subkelas akan selalu dipanggil (metode instance yang diganti akan diutamakan). Saya punya pertanyaan bodoh, tetapi Anda telah melakukan hardcode panggilan ke super.loadFromFile() di dalam ElectronicProduct, jadi Anda memaksa panggilan ke Product.loadFromFile(), jadi memang benar jika mengharapkan untuk melihat Product.loadFromFile() dipanggil. Akan mengubah jawaban saya untuk memberi Anda sebuah contoh. - person Victor Polo De Gyves Montero; 05.02.2020
comment
Menurut saya tidak benar melihat Product.loadFromFile() dipanggil, meskipun sudah di-hardcode ke ElectronicProduct.loadFromFile(), karena mereka memiliki badan metode yang berbeda, dan mengembalikan objek yang berbeda, tetapi orang lain mungkin perlu memverifikasi ini. - person InitialisingAttributes; 05.02.2020
comment
Tipe pengembalian bukan bagian dari tanda tangan metode. Inilah sebabnya mengapa ini adalah contoh penggantian metode, dan ini akan selalu memanggil instance metode ElectronicProduct alih-alih Produk, lihat: docs.Oracle.com/javase/tutorial/java/IandI/override.html - person Victor Polo De Gyves Montero; 05.02.2020

Mungkin Anda harus menggunakan metode seperti ini:

public ElectronicProduct loadFromFile(ElectronicProduct aProduct, BufferedReader bin) throws IOException, ParseException{

Karena perbedaan utamanya adalah objek yang Anda masukkan ke dalam parameter, Anda harus menentukannya.

person Tiffado    schedule 05.02.2020
comment
Saya telah mengedit pertanyaan, jika saya meneruskan objek anak mungkin tidak berfungsi karena .super digunakan untuk meneruskannya ke metode induk, yang tidak dapat 'melihat' objek anak. - person InitialisingAttributes; 05.02.2020