Isi
- Perkenalan
- Antarmuka
- Penanda antarmuka
- Antarmuka fungsional, metode statis, dan metode default
- Kelas abstrak
- Kelas yang tidak dapat diubah (permanen).
- Kelas anonim
- Visibilitas
- Warisan
- Warisan berganda
- Warisan dan komposisi
- Enkapsulasi
- Kelas dan metode terakhir
- Apa berikutnya
- Unduh kode sumber
1. PERKENALAN
Apa pun bahasa pemrograman yang Anda gunakan (tidak terkecuali Java), mengikuti prinsip desain yang baik adalah kunci untuk menulis kode yang bersih, mudah dipahami, dan dapat diverifikasi; dan juga membuatnya berumur panjang dan mudah mendukung penyelesaian masalah. Pada bagian tutorial ini, kita akan membahas elemen dasar yang disediakan oleh bahasa Java dan memperkenalkan beberapa prinsip desain dalam upaya membantu Anda membuat keputusan desain yang lebih baik. Lebih khusus lagi, kita akan membahas antarmuka dan antarmuka menggunakan metode default (fitur baru di Java 8), kelas abstrak dan final, kelas yang tidak dapat diubah, pewarisan, komposisi, dan meninjau kembali aturan visibilitas (atau aksesibilitas) yang telah kita bahas secara singkat di dalam Bagian 1 pelajaran
"Cara membuat dan menghancurkan benda" .
2. ANTARMUKA
Dalam pemrograman berorientasi objek , konsep antarmuka menjadi dasar pengembangan kontrak . Singkatnya, antarmuka menentukan sekumpulan metode (kontrak) dan setiap kelas yang memerlukan dukungan untuk antarmuka spesifik tersebut harus menyediakan implementasi metode tersebut: sebuah ide yang cukup sederhana namun kuat. Banyak bahasa pemrograman memiliki antarmuka dalam satu atau lain bentuk, tetapi Java khususnya menyediakan dukungan bahasa untuk ini. Mari kita lihat definisi antarmuka sederhana di Java.
package com.javacodegeeks.advanced.design;
public interface SimpleInterface {
void performAction();
}
Dalam cuplikan di atas, antarmuka yang kita panggil
SimpleInterface
, hanya mendeklarasikan satu metode yang disebut
performAction
. Perbedaan utama antara antarmuka dan kelas adalah bahwa antarmuka menguraikan kontak yang seharusnya (mereka mendeklarasikan suatu metode), tetapi tidak menyediakan implementasinya. Namun, antarmuka di Java bisa lebih kompleks: antarmuka dapat mencakup antarmuka bersarang, kelas, jumlah, anotasi, dan konstanta. Misalnya:
package com.javacodegeeks.advanced.design;
public interface InterfaceWithDefinitions {
String CONSTANT = "CONSTANT";
enum InnerEnum {
E1, E2;
}
class InnerClass {
}
interface InnerInterface {
void performInnerAction();
}
void performAction();
}
Dalam contoh yang lebih kompleks ini, ada beberapa batasan yang diterapkan tanpa syarat oleh antarmuka pada konstruksi bersarang dan deklarasi metode, dan ini diterapkan oleh kompiler Java. Pertama-tama, meskipun tidak dideklarasikan secara eksplisit, setiap deklarasi metode dalam antarmuka bersifat
publik (dan hanya dapat bersifat publik). Jadi deklarasi metode berikut ini setara:
public void performAction();
void performAction();
Perlu disebutkan bahwa setiap metode dalam antarmuka secara implisit dideklarasikan
abstract , dan bahkan deklarasi metode ini pun setara:
public abstract void performAction();
public void performAction();
void performAction();
Sedangkan untuk bidang konstanta yang dideklarasikan, selain bersifat
public , bidang tersebut juga secara implisit
static dan ditandai
final . Oleh karena itu, deklarasi berikut juga setara:
String CONSTANT = "CONSTANT";
public static final String CONSTANT = "CONSTANT";
Terakhir, kelas, antarmuka, atau jumlah yang disarangkan, selain bersifat
public , juga secara implisit dideklarasikan
static . Misalnya, deklarasi ini juga setara dengan:
class InnerClass {
}
static class InnerClass {
}
Gaya yang Anda pilih adalah preferensi pribadi, namun mengetahui properti antarmuka sederhana ini dapat menyelamatkan Anda dari pengetikan yang tidak perlu.
3. Penanda antarmuka
Antarmuka penanda adalah jenis antarmuka khusus yang tidak memiliki metode atau konstruksi bersarang lainnya. Bagaimana perpustakaan Java mendefinisikannya:
public interface Cloneable {
}
Penanda antarmuka bukanlah kontrak semata, tetapi merupakan teknik yang berguna untuk "melampirkan" atau "mengaitkan" beberapa sifat tertentu dengan suatu kelas. Misalnya, sehubungan dengan
Cloneable , kelas ditandai sebagai dapat dikloning, namun cara penerapannya bukan merupakan bagian dari antarmuka. Contoh penanda antarmuka lain yang sangat terkenal dan banyak digunakan adalah
Serializable
:
public interface Serializable {
}
Antarmuka ini menandai kelas yang sesuai untuk serialisasi dan deserialisasi, dan sekali lagi, antarmuka ini tidak menentukan bagaimana hal ini dapat atau harus diimplementasikan. Penanda antarmuka memiliki tempatnya dalam pemrograman berorientasi objek, meskipun penanda tersebut tidak memenuhi tujuan utama antarmuka sebagai kontrak.
4. ANTARMUKA FUNGSIONAL, METODE DEFAULT DAN METODE STATIS
Sejak rilis Java 8, antarmuka telah memperoleh beberapa fitur baru yang sangat menarik: metode statis, metode default, dan konversi otomatis dari lambda (antarmuka fungsional). Di bagian antarmuka, kami menekankan fakta bahwa antarmuka di Java hanya dapat mendeklarasikan metode, tetapi tidak menyediakan implementasinya. Dengan metode default, segalanya berbeda: antarmuka dapat menandai metode dengan kata kunci
default dan menyediakan implementasinya. Misalnya:
package com.javacodegeeks.advanced.design;
public interface InterfaceWithDefaultMethods {
void performAction();
default void performDefaulAction() {
}
}
Berada di tingkat instance, metode default dapat ditimpa oleh setiap implementasi antarmuka, namun antarmuka sekarang juga dapat menyertakan metode
statis , misalnya: package com.javacodegeeks.advanced.design;
public interface InterfaceWithDefaultMethods {
static void createAction() {
}
}
Dapat dikatakan bahwa menyediakan implementasi di antarmuka menggagalkan seluruh tujuan pemrograman kontrak. Namun ada banyak alasan mengapa fitur-fitur ini diperkenalkan ke dalam bahasa Java dan betapapun berguna atau membingungkannya, fitur-fitur tersebut tersedia untuk Anda dan Anda gunakan. Antarmuka fungsional memiliki cerita yang berbeda dan telah terbukti menjadi tambahan yang sangat berguna pada bahasa ini. Pada dasarnya, antarmuka fungsional adalah antarmuka yang hanya mendeklarasikan satu metode abstrak di dalamnya.
Runnable
Antarmuka perpustakaan standar adalah contoh yang sangat bagus dari konsep ini.
@FunctionalInterface
public interface Runnable {
void run();
}
Kompiler Java memperlakukan antarmuka fungsional secara berbeda dan dapat mengubah fungsi lambda menjadi implementasi antarmuka fungsional jika masuk akal. Mari kita perhatikan deskripsi fungsi berikut:
public void runMe( final Runnable r ) {
r.run();
}
Untuk memanggil fungsi ini di Java 7 dan di bawahnya, implementasi antarmuka harus disediakan
Runnable
(misalnya menggunakan kelas anonim), namun di Java 8 cukup menyediakan implementasi metode run() menggunakan sintaks lambda:
runMe( () -> System.out.println( "Run!" ) );
Selain itu, anotasi
@FunctionalInterface (anotasi akan dibahas secara rinci di Bagian 5 tutorial) mengisyaratkan bahwa kompiler dapat memeriksa apakah suatu antarmuka hanya berisi satu metode abstrak, sehingga perubahan apa pun yang dilakukan pada antarmuka di masa mendatang tidak akan melanggar asumsi ini .
5. KELAS ABSTRAK
Konsep menarik lainnya yang didukung oleh bahasa Java adalah konsep kelas abstrak. Kelas abstrak agak mirip dengan antarmuka di Java 7 dan sangat mirip dengan antarmuka metode default di Java 8. Tidak seperti kelas biasa, kelas abstrak tidak dapat dipakai, tetapi dapat dibuat subkelasnya (lihat bagian Warisan untuk lebih jelasnya). Lebih penting lagi, kelas abstrak dapat berisi metode abstrak: jenis metode khusus tanpa implementasi, seperti antarmuka. Misalnya:
package com.javacodegeeks.advanced.design;
public abstract class SimpleAbstractClass {
public void performAction() {
}
public abstract void performAnotherAction();
}
Dalam contoh ini, kelas
SimpleAbstractClass
dideklarasikan sebagai
abstrak dan berisi satu metode abstrak yang dideklarasikan. Kelas abstrak sangat berguna; sebagian besar atau bahkan beberapa bagian dari detail implementasi dapat dibagikan ke banyak subkelas. Meskipun demikian, mereka tetap membiarkan pintunya terbuka dan memungkinkan Anda untuk menyesuaikan perilaku yang melekat pada setiap subkelas menggunakan metode abstrak. Perlu disebutkan bahwa tidak seperti antarmuka, yang hanya dapat berisi deklarasi
publik , kelas abstrak dapat menggunakan kekuatan penuh aturan aksesibilitas untuk mengontrol visibilitas metode abstrak.
6. KELAS SEGERA
Kekekalan menjadi semakin penting dalam pengembangan perangkat lunak saat ini. Munculnya sistem multi-inti telah menimbulkan banyak masalah terkait berbagi data dan paralelisme. Namun satu masalah pasti muncul: memiliki sedikit (atau bahkan tidak ada) keadaan yang dapat diubah akan menghasilkan ekstensibilitas (skalabilitas) yang lebih baik dan penalaran yang lebih mudah tentang sistem. Sayangnya, bahasa Java tidak memberikan dukungan yang layak untuk kekekalan kelas. Namun, dengan menggunakan kombinasi teknik, dimungkinkan untuk merancang kelas yang tidak dapat diubah. Pertama-tama, semua bidang kelas harus final (ditandai sebagai
final ). Ini merupakan awal yang baik, namun bukan jaminan.
package com.javacodegeeks.advanced.design;
import java.util.Collection;
public class ImmutableClass {
private final long id;
private final String[] arrayOfStrings;
private final Collection<String> collectionOfString;
}
Kedua, pastikan inisialisasi yang tepat: jika suatu bidang adalah referensi ke koleksi atau larik, jangan tetapkan bidang tersebut langsung dari argumen konstruktor, melainkan buatlah salinannya. Ini akan memastikan bahwa status koleksi atau larik tidak diubah di luarnya.
public ImmutableClass( final long id, final String[] arrayOfStrings,
final Collection<String> collectionOfString) {
this.id = id;
this.arrayOfStrings = Arrays.copyOf( arrayOfStrings, arrayOfStrings.length );
this.collectionOfString = new ArrayList<>( collectionOfString );
}
Dan terakhir, memastikan akses yang tepat (pengambil). Untuk koleksi, kekekalan harus disediakan sebagai pembungkus
Collections.unmodifiableXxx
: Dengan array, satu-satunya cara untuk memberikan kekekalan yang sebenarnya adalah dengan menyediakan salinan alih-alih mengembalikan referensi ke array. Hal ini mungkin tidak dapat diterima dari sudut pandang praktis, karena sangat bergantung pada ukuran susunan dan dapat memberikan tekanan yang sangat besar pada pengumpul sampah.
public String[] getArrayOfStrings() {
return Arrays.copyOf( arrayOfStrings, arrayOfStrings.length );
}
Bahkan contoh kecil ini memberikan gambaran bagus bahwa kekekalan belum menjadi warga negara kelas satu di Jawa. Segalanya bisa menjadi rumit jika kelas yang tidak dapat diubah memiliki bidang yang merujuk ke objek kelas lain. Kelas-kelas tersebut juga harusnya tidak dapat diubah, tetapi tidak ada cara untuk memastikan hal ini. Ada beberapa penganalisis kode sumber Java yang layak, seperti FindBugs dan PMD, yang dapat sangat membantu dengan memeriksa kode Anda dan menunjukkan kelemahan umum pemrograman Java. Alat-alat ini adalah teman baik bagi pengembang Java mana pun.
7. KELAS ANONIM
Di era sebelum Java 8, kelas anonim adalah satu-satunya cara untuk memastikan kelas ditentukan dengan cepat dan dipakai dengan segera. Tujuan dari kelas anonim adalah untuk mengurangi boilerplate dan menyediakan cara singkat dan mudah untuk mewakili kelas sebagai catatan. Mari kita lihat cara kuno untuk membuat thread baru di Java:
package com.javacodegeeks.advanced.design;
public class AnonymousClass {
public static void main( String[] args ) {
new Thread(
new Runnable() {
@Override
public void run() {
}
}
).start();
}
}
Dalam contoh ini, implementasi
Runnable
antarmuka disediakan langsung sebagai kelas anonim. Meskipun ada beberapa keterbatasan yang terkait dengan kelas anonim, kelemahan utama penggunaannya adalah sintaksis konstruksi yang sangat verbose yang diwajibkan oleh bahasa Java. Bahkan kelas anonim yang tidak melakukan apa pun memerlukan setidaknya 5 baris kode setiap kali ditulis.
new Runnable() {
@Override
public void run() {
}
}
Untungnya, dengan Java 8, lambda, dan antarmuka fungsional, semua stereotip ini akan segera hilang, dan akhirnya penulisan kode Java akan terlihat sangat ringkas.
package com.javacodegeeks.advanced.design;
public class AnonymousClass {
public static void main( String[] args ) {
new Thread( () -> { } ).start();
}
}
8. VISIBILITAS
Kita sudah membicarakan sedikit tentang aturan visibilitas dan aksesibilitas di Java di Bagian 1 tutorial. Pada bagian ini, kita akan meninjau kembali topik ini lagi, namun dalam konteks subkelas.
Visibilitas pada tingkat yang berbeda memungkinkan atau mencegah kelas melihat kelas atau antarmuka lain (misalnya, jika mereka berada dalam paket berbeda atau bersarang satu sama lain) atau subkelas melihat dan mengakses metode, konstruktor, dan bidang induknya. Di bagian selanjutnya, warisan, kita akan melihat cara kerjanya.
9. WARISAN
Warisan adalah salah satu konsep kunci pemrograman berorientasi objek, yang berfungsi sebagai dasar untuk membangun hubungan kelas. Dikombinasikan dengan aturan visibilitas dan aksesibilitas, pewarisan memungkinkan kelas dirancang menjadi hierarki yang dapat diperluas dan dipelihara. Pada tingkat konseptual, pewarisan di Java diimplementasikan menggunakan subkelas dan kata kunci
extends , bersama dengan kelas induk. Subkelas mewarisi semua elemen publik dan dilindungi dari kelas induk. Selain itu, subkelas mewarisi elemen paket-pribadi dari kelas induknya jika keduanya (subkelas dan kelas) berada dalam paket yang sama. Meskipun demikian, sangat penting, apa pun yang Anda coba desain, untuk tetap berpegang pada serangkaian metode minimum yang diekspos oleh suatu kelas secara publik atau pada subkelasnya. Misalnya, mari kita lihat kelas
Parent
dan subkelasnya
Child
untuk menunjukkan perbedaan tingkat visibilitas dan pengaruhnya.
package com.javacodegeeks.advanced.design;
public class Parent {
public static final String CONSTANT = "Constant";
private String privateField;
protected String protectedField;
private class PrivateClass {
}
protected interface ProtectedInterface {
}
public void publicAction() {
}
protected void protectedAction() {
}
private void privateAction() {
}
void packageAction() {
}
}
package com.javacodegeeks.advanced.design;
public class Child extends Parent implements Parent.ProtectedInterface {
@Override
protected void protectedAction() {
super.protectedAction();
}
@Override
void packageAction() {
}
public void childAction() {
this.protectedField = "value";
}
}
Warisan adalah topik yang sangat besar, dengan banyak detail khusus untuk Java. Namun, ada beberapa aturan yang mudah diikuti dan dapat membantu menjaga singkatnya hierarki kelas. Di Java, setiap subkelas dapat mengganti metode apa pun yang diwarisi dari induknya kecuali jika metode tersebut telah dinyatakan final. Namun, tidak ada sintaks atau kata kunci khusus untuk menandai suatu metode sebagai diganti, yang dapat menyebabkan kebingungan.
Inilah sebabnya mengapa anotasi @Override diperkenalkan : setiap kali tujuan Anda adalah mengganti metode yang diwariskan, harap gunakan anotasi
@Override untuk menunjukkannya secara ringkas. Dilema lain yang selalu dihadapi pengembang Java dalam desain adalah konstruksi hierarki kelas (dengan kelas konkret atau abstrak) versus implementasi antarmuka. Kami sangat menyarankan untuk memilih antarmuka daripada kelas atau kelas abstrak bila memungkinkan. Antarmuka lebih ringan, lebih mudah untuk diuji dan dipelihara, dan juga meminimalkan efek samping dari perubahan implementasi. Banyak teknik pemrograman tingkat lanjut, seperti membuat kelas proxy di perpustakaan standar Java, sangat bergantung pada antarmuka.
10. WARISAN GANDA
Tidak seperti C++ dan beberapa bahasa lainnya, Java tidak mendukung pewarisan berganda: di Java, setiap kelas hanya dapat memiliki satu induk langsung (dengan kelas
Object
berada di puncak hierarki). Namun, sebuah kelas dapat mengimplementasikan banyak antarmuka, dan dengan demikian penumpukan antarmuka adalah satu-satunya cara untuk mencapai (atau mensimulasikan) banyak warisan di Java.
package com.javacodegeeks.advanced.design;
public class MultipleInterfaces implements Runnable, AutoCloseable {
@Override
public void run() {
}
@Override
public void close() throws Exception {
}
}
Mengimplementasikan banyak antarmuka sebenarnya cukup ampuh, namun sering kali kebutuhan untuk menggunakan implementasi berulang kali mengarah pada hierarki kelas yang mendalam sebagai cara untuk mengatasi kurangnya dukungan Java untuk pewarisan berganda.
public class A implements Runnable {
@Override
public void run() {
}
}
public class B extends A implements AutoCloseable {
@Override
public void close() throws Exception {
}
}
public class C extends B implements Readable {
@Override
public int read(java.nio.CharBuffer cb) throws IOException {
}
}
Dan seterusnya... Rilis terbaru Java 8 mengatasi masalah dengan injeksi metode default. Karena metode default, antarmuka sebenarnya tidak hanya menyediakan kontrak, tetapi juga implementasi. Oleh karena itu, kelas yang mengimplementasikan antarmuka ini juga akan secara otomatis mewarisi metode yang diimplementasikan tersebut. Misalnya:
package com.javacodegeeks.advanced.design;
public interface DefaultMethods extends Runnable, AutoCloseable {
@Override
default void run() {
}
@Override
default void close() throws Exception {
}
}
public class C implements DefaultMethods, Readable {
@Override
public int read(java.nio.CharBuffer cb) throws IOException {
}
}
Ingatlah bahwa pewarisan berganda adalah alat yang sangat ampuh namun sekaligus berbahaya. Masalah Diamond of Death yang terkenal sering disebut-sebut sebagai kelemahan utama dalam penerapan pewarisan berganda, sehingga memaksa pengembang untuk merancang hierarki kelas dengan sangat hati-hati. Sayangnya, antarmuka Java 8 dengan metode default juga menjadi korban cacat ini.
interface A {
default void performAction() {
}
}
interface B extends A {
@Override
default void performAction() {
}
}
interface C extends A {
@Override
default void performAction() {
}
}
Misalnya, cuplikan kode berikut akan gagal dikompilasi:
interface E extends B, C {
}
Pada titik ini, wajar untuk mengatakan bahwa Java sebagai sebuah bahasa selalu berusaha menghindari kasus-kasus sudut pemrograman berorientasi objek, namun seiring dengan berkembangnya bahasa, beberapa kasus tersebut tiba-tiba mulai muncul.
11. WARISAN DAN KOMPOSISI
Untungnya, pewarisan bukanlah satu-satunya cara untuk mendesain kelas Anda. Alternatif lain yang diyakini banyak pengembang jauh lebih baik daripada warisan adalah komposisi. Idenya sangat sederhana: alih-alih membuat hierarki kelas, kelas harus terdiri dari kelas lain. Mari kita lihat contoh ini:
interface E extends B, C {
}
Kelasnya
Vehicle
terdiri dari mesin dan roda (ditambah banyak bagian lain yang dikesampingkan demi kesederhanaan). Namun dapat dikatakan bahwa suatu kelas
Vehicle
juga merupakan sebuah mesin, sehingga dapat dirancang dengan menggunakan pewarisan.
public class Vehicle extends Engine {
private Wheels[] wheels;
}
Solusi desain mana yang benar? Pedoman inti umum tersebut dikenal dengan prinsip IS-A (is) dan HAS-A (contains). IS-A adalah hubungan pewarisan: subkelas juga memenuhi spesifikasi kelas dari kelas induk dan variasi dari kelas induk. subkelas) memperluas induknya. Jika Anda ingin mengetahui apakah satu entitas memperluas entitas lainnya, lakukan uji kecocokan - IS -A (is).") Oleh karena itu, HAS-A adalah hubungan komposisi: kelas memiliki (atau berisi) objek yang Dalam kebanyakan kasus, prinsip HAS-A bekerja lebih baik daripada IS-A karena sejumlah alasan:
- Desain lebih fleksibel;
- Model ini lebih stabil karena perubahan tidak menyebar melalui hierarki kelas;
- Sebuah kelas dan komposisinya dipasangkan secara longgar dibandingkan dengan komposisi yang memasangkan erat induk dan subkelasnya.
- Alur pemikiran logis dalam sebuah kelas lebih sederhana, karena semua dependensinya disertakan di dalamnya, di satu tempat.
Terlepas dari itu, pewarisan mempunyai tempatnya dan menyelesaikan sejumlah masalah desain yang ada dengan berbagai cara, sehingga tidak boleh diabaikan. Harap ingat kedua alternatif ini saat merancang model berorientasi objek Anda.
12. ENKAPSULASI.
Konsep enkapsulasi dalam pemrograman berorientasi objek adalah menyembunyikan semua detail implementasi (seperti mode operasi, metode internal, dll.) dari dunia luar. Keuntungan enkapsulasi adalah pemeliharaan dan kemudahan perubahan. Implementasi internal kelas disembunyikan, bekerja dengan data kelas terjadi secara eksklusif melalui metode publik kelas (masalah nyata jika Anda mengembangkan perpustakaan atau kerangka kerja yang digunakan oleh banyak orang). Enkapsulasi di Java dicapai melalui aturan visibilitas dan aksesibilitas. Di Java, praktik terbaiknya adalah tidak pernah mengekspos bidang secara langsung, hanya melalui pengambil dan penyetel (kecuali bidang tersebut ditandai sebagai final). Misalnya:
package com.javacodegeeks.advanced.design;
public class Encapsulation {
private final String email;
private String address;
public Encapsulation( final String email ) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
}
Contoh ini mengingatkan pada apa yang disebut
JavaBeans dalam bahasa Java: kelas Java standar ditulis berdasarkan sekumpulan konvensi, salah satunya mengizinkan bidang diakses hanya menggunakan metode pengambil dan penyetel. Seperti yang sudah kami tekankan di bagian pewarisan, harap selalu mematuhi kontrak publisitas minimum di suatu kelas, dengan menggunakan prinsip enkapsulasi. Segala sesuatu yang tidak boleh bersifat publik harus menjadi pribadi (atau dilindungi/dipaketkan pribadi, tergantung pada masalah yang Anda pecahkan). Hal ini akan membuahkan hasil dalam jangka panjang dengan memberi Anda kebebasan mendesain tanpa (atau setidaknya meminimalkan) perubahan yang mengganggu.
13. KELAS DAN METODE AKHIR
Di Java, ada cara untuk mencegah suatu kelas menjadi subkelas dari kelas lain: kelas lain tersebut harus dinyatakan final.
package com.javacodegeeks.advanced.design;
public final class FinalClass {
}
Kata kunci
final yang sama dalam deklarasi metode mencegah subkelas menimpa metode tersebut.
package com.javacodegeeks.advanced.design;
public class FinalMethod {
public final void performAction() {
}
}
Tidak ada aturan umum untuk memutuskan apakah suatu kelas atau metode harus final atau tidak. Kelas dan metode akhir membatasi ekstensibilitas dan sangat sulit untuk berpikir ke depan apakah suatu kelas harus diwarisi atau tidak, atau apakah suatu metode harus ditimpa atau tidak di masa mendatang. Hal ini sangat penting bagi pengembang perpustakaan, karena keputusan desain seperti ini dapat membatasi penerapan perpustakaan secara signifikan. Perpustakaan Standar Java memiliki beberapa contoh kelas akhir, yang paling terkenal adalah kelas String. Pada tahap awal, keputusan ini dibuat untuk mencegah segala upaya pengembang untuk menemukan solusi mereka sendiri yang “lebih baik” untuk mengimplementasikan string.
14. APA SELANJUTNYA
Pada bagian pelajaran ini, kita membahas konsep pemrograman berorientasi objek di Java. Kami juga melihat sekilas pemrograman kontrak, menyentuh beberapa konsep fungsional dan melihat bagaimana bahasa tersebut berkembang seiring waktu. Di bagian selanjutnya dari pelajaran ini, kita akan bertemu dengan obat generik dan bagaimana obat generik mengubah cara kita mendekati keamanan tipe dalam pemrograman.
15. UNDUH KODE SUMBER
Anda dapat mengunduh sumbernya di sini -
advanced-java-part-3 Sumber:
Cara mendesain Kelas an
GO TO FULL VERSION