Melacak semua objek kelas

9

Saya baru mengenal pemrograman berorientasi objek, dan saya terus mengalami masalah ini. (Saya pemrograman di Jawa) Saya agak enggan bertanya tentang hal ini, karena sepertinya ini masalah mendasar, tapi saya tidak dapat menemukan informasi tentang itu, atau pertanyaan tentang hal itu di sini, dan tidak ada satupun buku teks yang telah saya baca (pada tingkat yang cukup mendasar tentu saja) telah menyentuh masalah ini:

Seringkali saya perlu melacak semua objek dari kelas yang telah dibuat, untuk beralih melalui mereka untuk berbagai keperluan. Mereka cara saya saat ini menulis program, banyak objek hanya direferensikan dari objek lain, artinya saya tidak memiliki array atau koleksi untuk referensi mereka semua.

Saya membayangkan bahwa, karena ini seperti kebutuhan yang sangat mendasar dalam OOP, harus ada cara yang cukup dilembagakan, dan sederhana, untuk melakukan ini? Apakah itu praktik biasa untuk menyimpan daftar yang terpisah dari semua objek kelas?

Saya berpikir tentang array statis atau koleksi, yang melalui konstruktornya, setiap objek baru yang dibuat akan ditambahkan. Namun ini tidak akan bekerja dengan subclass, karena konstruktor tidak diwarisi?

Saya menyadari pertanyaan ini mungkin tidak memiliki satu jawaban mudah; Saya hanya berharap seseorang dapat sedikit mencerahkan saya tentang hal ini. Saya merasa jika saya kurang memiliki pengetahuan utama di sini.

zxz
sumber
5
Contoh yang lebih spesifik dari yang dilacak dan pelacak mungkin membantu. Masalah ini ditangani dengan berbagai cara tergantung pada konteksnya, bagaimana mereka digunakan, dan sebagainya.
JustinC
2
Saya pikir Anda mungkin mendekati masalah dari ujung yang salah. Sangat tidak umum untuk membutuhkan daftar semua instance dari kelas yang diberikan, dan memiliki satu akan menyebabkan semua jenis masalah desain (karena sekarang bahkan instance yang dibuat dalam konteks yang sama sekali tidak terkait tergantung satu sama lain melalui daftar ini).
tdammers
1
"beralih melalui mereka untuk berbagai keperluan" ... seperti ...? Secara umum, sebuah objek memiliki satu 'pemilik' (bukan istilah formal, lebih dari sekadar pernyataan tentang semantik program), dan bukan untuk orang lain yang memiliki 'berbagai tujuan' dengan objek tersebut.
AakashM

Jawaban:

8

Saya tidak tahu mengapa Anda perlu menyimpan daftar semua instance kelas.

Itu akan menyebabkan kebocoran memori karena benda-benda itu tidak akan pernah dibuang, karena daftar masih akan merujuk mereka setelah tidak ada kelas lain yang melakukannya.

Tetapi jika Anda benar-benar ingin mengikuti rute itu:

  1. Gunakan pola Pabrik. Kelas pabrik dengan metode yang memicu kelas dan mengembalikan objek. Dengan begitu Anda memiliki titik sentralisasi untuk mengontrol instantiations.
  2. Gunakan pola Singleton untuk menyimpan daftar atau daftar yang menampung instance.
  3. Buat pabrik menempatkan setiap objek dari jenis tertentu dalam daftar setelah membuatnya.

Omong-omong: konstruktor diwarisi.

Tulains Córdova
sumber
Anda tentu saja dapat memberikan pabrik metode "buang" yang menghilangkan instance dari daftar instance yang dilacak. Tetapi tidak ada cara untuk secara eksplisit memintanya. Atau berikan contoh metode buang yang memicu metode buang di pabriknya, yang memiliki kelemahan yang sama tetapi sedikit lebih mungkin disebut sebagai lebih dekat dengan pengguna, lebih terlihat.
jwenting
@jwenting Tentu saja itu caranya. Tapi itu akan menciptakan dependensi yang jelek dan tidak perlu antara kelas dan pabrik. Kelas seharusnya tidak tahu apa-apa tentang pabrik yang membuatnya.
Tulains Córdova
karenanya memiliki pabrik melacak apa yang dibuatnya, daripada objek yang memberitahu pabrik untuk mendaftarkannya ...
jwenting
Satu singleton secara teknis akan menampung semua contoh kurasa. Satu contoh tunggal.
Rig
3

Perlu dicatat bahwa referensi yang lemah dapat digunakan dalam kombinasi dengan solusi lain yang diberikan untuk memungkinkan pengumpul sampah untuk membuang benda yang dilacak ketika mereka tidak lagi dirujuk di tempat lain. Ini menghilangkan kebocoran memori tanpa memerlukan kode di tempat lain untuk secara manual membuang objek, atau peduli bahwa mereka sedang dilacak. Anda dapat memberikan ReferenceQueue untuk menerima pemberitahuan referensi ke objek yang telah dibebaskan.

Saya berpikir tentang array statis atau koleksi, yang melalui konstruktornya, setiap objek baru yang dibuat akan ditambahkan. Namun ini tidak akan bekerja dengan subclass, karena konstruktor tidak diwarisi?

Konstruktor kelas dasar dipanggil sebelum konstruktor kelas turunan. Setiap kelas memiliki setidaknya satu konstruktor dan konstruktor tidak dapat ditimpa.

pengguna2313838
sumber
2

Saat membuat game, terkadang orang menginginkan koleksi "swakelola" dari setiap jenis objek game.

Satu implementasi terlihat seperti ini:

public class Car {

    static ArrayList<Car> list = new ArrayList<Car>();

    public Car() {
        list.add(this);
    }

    void kill() {
        list.remove(this);
    }

    static public void updateAll()
    {
        for (int i = list.size() - 1; i >= 0; i--)
        {
                list.get(i).update();
        }
    }

    public void update()
    {
        //update logic
    }
}

Dengan cara ini, metode yang memanipulasi koleksi dapat dinyatakan statis, sedangkan metode non-statis memanipulasi instance (updateAll vs. update).

Meskipun bagus untuk skenario yang sangat sederhana, bahkan dengan kompleksitas moderat biasanya terbaik untuk membuat kelas manajer terpisah.

Kelly Thomas
sumber
1
Anda dapat langsung menulis dan static ArrayList<ListeStatic> list = new ArrayList<ListeStatic>();menekan statc {..}
cl-r
2
Dalam nama metode Java dimulai dengan huruf kecil:uptdateAll(){..;}
cl-r
oops ... sudah agak lama sejak saya menayangkan java saya di depan umum
Kelly Thomas
@KellyThomas Sebuah mobil menambahkan dirinya ke daftar, mereka menghapus sendiri darinya. Kedengarannya tidak wajar.
Tulains Córdova
1
@ CayetanoGonçalves sebagai bidang statis, ini adalah satu daftar yang dibagikan oleh semua instance.
Kelly Thomas
2

Cobalah untuk memikirkan konteksnya. Saat Anda membuat objek, Anda melakukannya dalam konteks tertentu. Misalnya, jika game Anda tentang menembak alien, aplikasi Anda akan membuat objek Alien baru setiap saat. Mereka akan ditampilkan di bidang yang disebut Space (yang bisa menjadi kelas yang mewakili UI utama).

Sangat wajar bagi Space untuk memiliki properti bernama currentAliens, yang akan menjadi array, tempat Anda menambahkan setiap alien baru yang Anda buat. Jika Anda ingin mengizinkan pengguna untuk merobek jalinan ruangwaktu dan menghancurkan semua alien sekaligus, Anda akan beralih melalui koleksi itu dan menghancurkan setiap objek.

Jika Anda ingin memiliki akses ke koleksi alien ini dari dalam bagian lain aplikasi Anda (katakanlah, dari halaman Pengaturan, di mana Anda mungkin ingin membolehkan pengguna untuk menghapus jenis alien tertentu dalam satu gerakan), konteks Pengaturan Anda akan perlu diberi akses ke objek Space.

Wytze
sumber