Malay (Melayu) translation by Rana Salsabiela (you can also view the original English article)
Java 8 adalah kemajuan yang besar untuk bahasa pemrograman dan sekarang, dengan dirilisnya Android Studio 3.0, pengembang Android akhirnya memiliki akses ke bawaan dukungan untuk beberapa fitur terpenting di Java 8.
Dalam seri ketiga bahagian ini, kami telah menjelajah Java 8 yang boleh digunakan oleh anda dalam projek Android anda hari ini . Dalam Kod Cleaner Dengan Expression Lambda , kami mengatur pengembangan kami untuk menggunakan Java 8 sokongan yang disediakan oleh toolchain bawaan Android, sebelum melihat lambda ekspresi secara mendalam
Di dalam siaran ini, kita akan melihat dua cara berbeza yang boleh anda deklarasikan kaedah yang tidak abstrak dalam interface anda (sesuatu yang tidak mungkin di versi sebelumnya Java). Kami juga akan menjawab soalan, sekarang antarmuka dapat menerapkan metode, apakah sebenarnya perbedaan antara kelas dan abstrak antarmuka?
Kami juga akan menyertakan ciri Java 8 yang memberikan anda kebebasan untuk menggunakan yang sama seperti yang anda inginkan di lokasi yang sama, sementara tetap kompatibel dengan versi sebelumnya Android.
Tetapi pertama-tama, mari kita lihat ciri Java 8 yang dirancang untuk digunakan bersama dengan lambda ekspresi yang kita lihat di posting sebelumnya .
Write Cleaner Lambda Expressions, Dengan Metode Rujukan
Dalam catatan terakhir, anda melihat bagaimana anda dapat menggunakan lambda ekspresi untuk menghapus banyak boilerplate kode dari aplikasi Android anda. Namun, ketika ekspresi lambda hanya memanggil satu metode yang sudah memiliki nama, Anda dapat memotong lebih banyak kode dari proyek Anda dengan menggunakan metode referensi.
Sebagai contoh, ekspresi lambda ini benar-benar hanya mengalihkan pekerjaan ke kaedah handleViewClick
yang ada:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(view -> handleViewClick(view)); } private void handleViewClick(View view) { }
Dalam skenario ini, kita boleh merujuk ke kaedah ini dengan nama, menggunakan metode rujukan operator::
. Anda membuat rujukan semacam ini, menggunakan format berikut:
Object/Class/Type::methodName
Dalam contoh Tombol Aksi Terapung kami, kami boleh menggunakan kaedah rujukan sebagai badan ekspresi lambda kami:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(this::handleViewClick); }
Perhatikan bahawa kaedah yang direferensikan harus mengambil parameter yang sama dengan antarmuka-dalam hal ini, itu adalah View
.
Anda boleh menggunakan kaedah rujukan pengendali ( ::
) untuk rujukan salah satu daripada yang berikut:
Statik kaedah
Jika anda mempunyai ekspresi lambda yang memanggil metode statis:
(args) -> Class.staticMethod(args)
Kemudian anda boleh mengubahnya menjadi rujukan rujukan:
Class::staticMethodName
Sebagai contoh, jika anda mempunyai kaedah static PrintMessage
dalam kelas MyClass
, maka rujukan anda akan kelihatan seperti ini:
public class myClass { public static void PrintMessage(){ System.out.println("This is a static method"); } } public static void main(String[] args) { Thread thread = new Thread(myClass::PrintMessage); thread.start(); } }
Contoh Objek Objek Khusus
Ini adalah contoh kaedah dari objek yang dikenali terlebih dahulu, membolehkan anda untuk menukar:
(arguments) -> containingObject.instanceMethodName(arguments)
Dengan:
containingObject::instanceMethodName
Jadi, jika anda mempunyai ekspresi lambda berikut:
MyClass.printNames(names, x -> System.out.println(x));
Kemudian memperkenalkan kaedah rujukan akan memberi anda perkara berikut:
MyClass.printNames(names,System.out::println);
Contoh Objek Arbitrase Objek Tipe Khusus
Ini adalah contoh kaedah dari objek sewenang-wenang yang akan diberikan kemudian, dan ditulis dalam format berikut:
ContainingType::methodName
Referensi Konstruktor
Referensi konstruktor mirip dengan kaedah rujukan, kecuali bahawa Anda menggunakan kata kunci new
untuk memohon konstruktor. Sebagai contoh, Button::new
adalah konstruktor rujukan untuk Button
kelas, walaupun betul-betul konstruktor yang dijalankan bergantung pada konteksnya.Menggunakan rujukan konstruktor, Anda dapat mengubah:
Menggunakan rujukan konstruktor, Anda dapat mengubah:
(arguments) -> new ClassName(arguments)
Kepada:
ClassName::new
Sebagai contoh, jika anda mempunyai antara muka MyInterface
berikut:
public Interface myInterface{ public abstract Student getStudent(String name, Integer age); }
Kemudian anda boleh menggunakan pembina rujukan untuk membuat contoh Student
baru:
myInterface stu1 = Student::new; Student stu = stu1.getStudent("John Doe", 27);
Ia juga boleh membuat pembina rujukan untuk jenis array. Sebagai contoh, pembina rujukan untuk pelbagai int
ialah int[]::new
.
Tambah Kaedah Lalai untuk Interface Anda
Sebelum Java 8, anda hanya boleh memasukkan kaedah abstrak pada antara muka anda (iaitu kaedah tanpa badan), yang menjadikannya sukar untuk membangunkan antara muka, selepas penerbitan.
Setiap kali anda menambah kaedah untuk definisi antara muka, setiap kelas yang melaksanakan antara muka ini tiba-tiba kehilangan pelaksanaan. Sebagai contoh, jika anda mempunyai antara muka ( MyInterface
) yang digunakan oleh MyClass
, kemudian menambah kaedah untuk MyInterface
akan merosakkan keserasian dengan MyClass
.
Dalam senario terbaik di mana anda bertanggungjawab untuk sebilangan kecil kelas menggunakanMyInterface
, tingkah laku ini akan menjengkelkan tetapi boleh dikendalikan - anda hanya perlu mengetepikan masa untuk mengemas kini kelas anda dengan pelaksanaan baru. Walau bagaimanapun, perkara boleh menjadi lebih rumit jika sebilangan besar kelas melaksanakan MyInterface
, atau jika antara muka digunakan dalam kelas yang anda tidak bertanggungjawab.
Walaupun terdapat beberapa penyelesaian untuk masalah ini, tiada yang ideal. Sebagai contoh, anda boleh memasukkan kaedah baru dalam kelas abstrak, tetapi ini masih memerlukan semua orang untuk mengemaskini kod mereka untuk mengembangkan kelas abstrak ini; dan, semasa anda bolehmengembangkan antara muka asal dengan antara muka baru, siapa saja yang ingin menggunakan kaedah baru ini kemudian perlu menulis semula semua rujukan antara muka yang sedia ada .
Dengan memperkenalkan kaedah lalai di Java 8, kini mungkin untuk mengisytiharkan kaedah bukan abstrak (iaitu kaedah dengan badan) di antara muka anda, supaya akhirnya anda boleh membuat aplikasi lalai untuk kaedah anda.
Apabila anda menambah kaedah ke antara muka anda sebagai kaedah lalai, setiap kelas yang melaksanakan antara muka ini tidak perlu menyediakan aplikasi sendiri, yang memberi anda cara untuk mengemas kini antara muka anda tanpa merosakkan keserasian. Jika anda menambah kaedah baru ke antara muka sebagai kaedah lalai , setiap kelas yang menggunakan antara muka ini tetapi tidak menyediakan aplikasi sendiri hanya akan mewarisi pelaksanaan kaedah lalai. Kerana kelas tidak kehilangan aplikasi, ia akan terus berfungsi seperti biasa.
Malah, pengenalan kaedah lalai adalah sebab Oracle dapat membuat sejumlah besar penambahan kepada Koleksi API di Java 8.
Collection
adalah antara muka biasa yang digunakan dalam banyak kelas yang berbeza, jadi menambah kaedah baru untuk antara muka ini mempunyai potensi untuk memecahkan garisan kod yang tak terhitung jumlahnya. Daripada menambah kaedah baru ke antara muka Collection
dan memecahkan setiap kelas yang diperolehi daripada antara muka ini, Oracle mencipta ciri kaedah lalai, dan kemudian menambah kaedah baru ini sebagai kaedah lalai. Jika anda melihat kaedah Collection.Stream () yang baru (yang akan kami pelajari secara terperinci di bahagian ketiga), anda akan melihat bahawa ia telah ditambahkan sebagai kaedah lalai:
default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
Buat kaedah lalai mudah - tambahkan pengubah default
kepada kaedah tandatangan anda:
public interface MyInterface { void interfaceMethod(); default void defaultMethod(){ Log.i(TAG,"This is a default method”); } }
Sekarang, jika MyClass
menggunakan MyInterface
tetapi tidak menyediakan pelaksanaan defaultMethod
sendiri, ia hanya akan mewarisi pelaksanaan lalai yang disediakan oleh MyInterface
. Sebagai contoh, kelas berikut masih akan disusun:
public class MyClass extends AppCompatActivity implements MyInterface { }
Kelas pelaksanaan boleh menggantikan pelaksanaan lalai yang disediakan oleh antara muka, jadi kelas masih dalam kendali sepenuhnya terhadap pelaksanaannya.
Walaupun kaedah lalai merupakan tambahan kepada pereka API, mereka kadang-kadang boleh menyebabkan masalah bagi pemaju yang cuba menggunakan pelbagai antara muka dalam kelas yang sama.
Bayangkan selain MyInterface
, anda mempunyai perkara berikut:
public interface SecondInterface { void interfaceMethod(); default void defaultMethod(){ Log.i(TAG,"This is also a default method”); } }
Kedua-dua MyInterface
dan SecondInterface
mengandungi kaedah lalai dengan tandatangan yang sama (defaultMethod
). Sekarang bayangkan anda cuba menggunakan kedua-dua antara muka dalam kelas yang sama:
public class MyClass extends AppCompatActivity implements MyInterface, SecondInterface { }
Pada ketika ini anda mempunyai dua pelaksanaan yang bertentangan dengan defaultMethod
, dan pengkompil tidak mengetahui kaedah yang digunakan, sehingga anda akan menemukan kesalahan kompilator.
Satu cara untuk mengatasi masalah ini adalah untuk menggantikan kaedah yang bertentangan dengan pelaksanaan anda sendiri:
public class MyClass extends AppCompatActivity implements MyInterface, SecondInterface { public void defaultMethod(){ } }
Penyelesaian lain adalah untuk menentukan versi defaultMethod
anda mahu gunakan, menggunakan format berikut:
<interface name>.super.<method name>();
Jadi jika anda mahu memanggil pelaksanaan MyInterface#defaultMethod()
, maka anda akan menggunakan yang berikut:
public class MyClass extends AppCompatActivity implements MyInterface, SecondInterface { public void defaultMethod(){ MyInterface.super.defaultMethod(); } }
Menggunakan Kaedah Statik dalam Antara Muka Java 8 anda
Sama seperti kaedah lalai, kaedah antara muka statik memberikan anda cara menentukan kaedah dalam antara muka. Walau bagaimanapun, tidak seperti kaedah lalai, kelas pelaksanaan tidak boleh menggantikan kaedah antara muka statik .
Sekiranya anda mempunyai kaedah statik yang khusus kepada antara muka, maka kaedah antara muka statik Java 8 memberikan anda cara untuk meletakkan kaedah ini dalam antara muka yang sesuai, dan bukannya menyimpannya dalam kelas yang berasingan.
Anda membuat kaedah statik dengan meletakkan kata kunci static
pada awal tandatangan kaedah, contohnya:
public interface MyInterface { static void staticMethod(){ System.out.println("This is a static method"); } }
Apabila anda melaksanakan antara muka yang mengandungi kaedah antara muka statik, kaedah statik masih merupakan antara muka dan tidak diwarisi oleh kelas yang menggunakannya, jadi anda mesti memulakan kaedah dengan nama antara muka, contohnya:
public class MyClass extends AppCompatActivity implements MyInterface { public static void main(String[] args) { MyInterface.staticMethod(); ... ... ...
Ini juga bermakna bahawa kelas dan antara muka boleh mempunyai kaedah statik dengan tandatangan yang sama. Sebagai contoh, menggunakan MyClass.staticMethod
dan MyInterface.staticMethod
dalam kelas yang sama tidak akan menyebabkan kesilapan masa penyusun.
Oleh itu, antaramuka pada dasarnya hanya kelas abstrak?
Penambahan kaedah antara muka statik dan kaedah lalai telah menyebabkan beberapa pemaju mempersoalkan sama ada antara muka Java lebih seperti kelas abstrak. Walau bagaimanapun, walaupun dengan penambahan kaedah antara muka lalai dan statik, masih terdapat beberapa perbezaan penting antara antara muka dan kelas abstrak:
- Kelas abstrak boleh mempunyai pembolehubah akhir, bukan akhir, statik dan bukan statik, manakala antara muka hanya boleh mempunyai pembolehubah statik dan akhir.
- Kelas abstrak membolehkan anda mengisytiharkan medan yang tidak statik dan muktamad, manakala medan antara muka pada dasarnya adalah statik dan muktamad.
- Dalam antara muka, semua kaedah yang anda perihalkan atau didefinisikan sebagai kaedah lalai adalah umum, manakala dalam kelas abstrak anda boleh menentukan kaedah awam, dilindungi, dan swasta.
- Kelas abstrak adalah kelas , dan oleh itu boleh mempunyai keadaan; Antara muka tidak boleh mempunyai status yang berkaitan dengannya.
- Anda boleh menentukan pembina dalam kelas abstrak, sesuatu yang tidak mungkin dalam antara muka Java.
- Java hanya membolehkan anda mengembangkan satu kelas (tanpa mengira sama ada ia abstrak), tetapi anda bebas untuk melaksanakan banyak antara muka yang anda perlukan. Ini bermakna bahawa antara muka biasanya mempunyai kelebihan apabila anda memerlukan banyak pusaka, walaupun anda perlu berhati-hati terhadap berlian berbahaya yang mematikan !
Memohon Anotasi yang Sama seperti Banyak Kali Yang Anda Mahu
Secara tradisinya, salah satu had anotasi Jawa adalah bahawa anda tidak boleh menggunakan anotasi yang sama lebih daripada sekali di lokasi yang sama. Cuba gunakan penjelasan yang sama beberapa kali, dan anda akan mengalami ralat masa penyusunan.
Bagaimanapun, dengan pengenalan penjelasan Java 8 berulang, anda kini bebas menggunakan banyak anotasi yang anda inginkan di lokasi yang sama.
Untuk memastikan kod anda tetap serasi dengan versi Java sebelumnya, anda mesti menyimpan anotasi berulang dalam anotasi kontena.
Anda boleh memberitahu compiler untuk mencipta bekas ini, dengan melengkapkan langkah berikut:
- Tandakan anotasi yang disebut sebagai Meta-anotasi
@Repeatable
(anotasi yang digunakan untuk memberi penjelasan anotasi). Sebagai contoh, jika anda mahu membuat anotasi@ToDo
berulang, anda akan menggunakan:@Repeatable(ToDos.class)
. Nilai dalam kurungan adalah jenis anotasi kontena yang akan dihasilkan oleh pengkompil. - Nyatakan jenis anotasi yang mengandungi. Ini mesti mempunyai atribut yang merupakan pelbagai jenis anotasi berulang, contohnya:
public @interface ToDos { ToDo[] value(); }
Cuba untuk menggunakan penjelasan yang sama beberapa kali tanpa terlebih dahulu menyatakan bahawa gelung akan menghasilkan ralat pada masa penyusunan. Walau bagaimanapun, selepas anda menyatakan bahawa ini adalah anotasi berulang, anda boleh menggunakan penjelasan ini beberapa kali di mana-mana lokasi yang anda gunakan anotasi standard.
Kesimpulannya
Di bahagian kedua siri kami di Java 8, kami melihat bagaimana anda boleh memotong kod boilerplate lebih daripada projek Android anda dengan menggabungkan ungkapan lambda dengan rujukan kaedah, dan bagaimana untuk meningkatkan antara muka anda dengan kaedah lalai dan statik.
Dalam peringkat ketiga dan terakhir, kita akan melihat Java 8 API baru yang membolehkan anda memproses sejumlah besar data dalam cara deklaratif yang lebih cekap, tanpa perlu risau tentang pengurusan kesukaran dan thread. Kami juga akan menggabungkan beberapa ciri yang berbeza yang telah dibincangkan sepanjang siri ini, dengan meneroka peranan yang mesti dimainkan Antara Fungsi Fungsian dalam ekspresi lambda, kaedah antara muka statik, kaedah lalai dan banyak lagi.
Dan akhirnya, walaupun kita masih menunggu Java 8 Date and Time API untuk tiba secara rasmi di Android, saya akan menunjukkan kepada anda bagaimana anda boleh menggunakan API baharu ini pada projek Android anda hari ini, dengan bantuan beberapa perpustakaan pihak ketiga.
Sementara itu, lihat beberapa jawatan kami yang lain tentang mengembangkan aplikasi Java dan Android!
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post