Apa itu "kelas abstrak" di Jawa?
Apa itu "kelas abstrak" di Jawa?
Jawaban:
Kelas abstrak adalah kelas yang tidak bisa dipakai. Kelas abstrak digunakan dengan membuat subclass warisan yang bisa dipakai. Kelas abstrak melakukan beberapa hal untuk subclass yang diwarisi:
Ini sebuah contoh:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
Perhatikan bahwa "abstractMethod ()" tidak memiliki tubuh metode apa pun. Karena itu, Anda tidak dapat melakukan hal berikut:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
Tidak ada metode yang mengimplementasikan abstractMethod()
! Jadi tidak ada cara bagi JVM untuk mengetahui apa yang seharusnya dilakukan ketika mendapat sesuatu new ImplementingClass().abstractMethod()
.
Ini benar ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
Perhatikan bahwa Anda tidak perlu mendefinisikan implementedMethod()
atau finalMethod()
. Mereka sudah didefinisikan oleh AbstractClass
.
Ini satu lagi yang benar ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
Dalam hal ini, Anda telah ditimpa implementedMethod()
.
Namun, karena final
kata kunci, yang berikut ini tidak mungkin.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
Anda tidak dapat melakukan ini karena implementasi finalMethod()
di AbstractClass
ditandai sebagai implementasi akhir dari finalMethod()
: tidak ada implementasi lain yang akan diizinkan.
Sekarang Anda juga dapat menerapkan kelas abstrak dua kali:
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
Sekarang di suatu tempat Anda bisa menulis metode lain.
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
Perhatikan bahwa meskipun kita menyatakan b
sebuah AbstractClass
jenis, itu menampilkan"Overriden!"
. Ini karena objek yang kita instantiasi sebenarnya adalah ImplementingClass
, yang implementedMethod()
tentu saja ditimpa. (Anda mungkin pernah melihat ini disebut sebagai polimorfisme.)
Jika kita ingin mengakses anggota yang spesifik untuk subkelas tertentu, kita harus memilih ke subkelas itu terlebih dahulu:
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
Terakhir, Anda tidak dapat melakukan hal berikut:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
Hanya satu kelas yang dapat diperpanjang sekaligus. Jika Anda perlu memperluas beberapa kelas, mereka harus berupa antarmuka. Kamu bisa melakukan ini:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
Berikut ini contoh antarmuka:
interface InterfaceA
{
void interfaceMethod();
}
Ini pada dasarnya sama dengan:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
Satu-satunya perbedaan adalah bahwa cara kedua tidak membuat kompiler tahu bahwa itu sebenarnya sebuah antarmuka. Ini bisa bermanfaat jika Anda ingin orang hanya mengimplementasikan antarmuka Anda dan tidak ada yang lain. Namun, sebagai aturan umum pemula, jika kelas abstrak Anda hanya memiliki metode abstrak, Anda mungkin harus membuatnya menjadi antarmuka.
Berikut ini adalah ilegal:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
Anda tidak dapat menerapkan metode dalam suatu antarmuka. Ini berarti bahwa jika Anda menerapkan dua antarmuka yang berbeda, metode yang berbeda di antarmuka tersebut tidak dapat bertabrakan. Karena semua metode dalam antarmuka adalah abstrak, Anda harus mengimplementasikan metode tersebut, dan karena metode Anda adalah satu-satunya implementasi dalam pohon warisan, kompiler tahu bahwa ia harus menggunakan metode Anda.
c.implementedMethod()
mencetak "Overriden!"? SecondImplementingClass
tidak menimpa implementedMethod()
.
Kelas Java menjadi abstrak dengan ketentuan sebagai berikut:
1. Setidaknya salah satu metode ditandai sebagai abstrak:
public abstract void myMethod()
Dalam hal ini kompiler memaksa Anda untuk menandai seluruh kelas sebagai abstrak.
2. Kelas ditandai sebagai abstrak:
abstract class MyClass
Seperti yang sudah dikatakan: Jika Anda memiliki metode abstrak kompiler memaksa Anda untuk menandai seluruh kelas sebagai abstrak. Tetapi bahkan jika Anda tidak memiliki metode abstrak, Anda masih dapat menandai kelas sebagai abstrak.
Penggunaan umum:
Penggunaan umum dari kelas abstrak adalah untuk memberikan garis besar kelas yang mirip dengan antarmuka. Tetapi tidak seperti antarmuka yang sudah dapat menyediakan fungsionalitas, yaitu beberapa bagian dari kelas diimplementasikan dan beberapa bagian hanya diuraikan dengan deklarasi metode. ("abstrak")
Kelas abstrak tidak bisa dipakaikan, tetapi Anda bisa membuat kelas konkret berdasarkan kelas abstrak, yang kemudian bisa dipakai. Untuk melakukannya, Anda harus mewarisi dari kelas abstrak dan mengganti metode abstrak, yaitu menerapkannya.
abstract
kata kunci adalah semua yang diperlukan untuk sebuah kelas menjadi abstrak. Tetapi kelas konkret tidak dapat berisiabstract
metode . Jadi, jika kelas Anda memiliki abstract
metode, itu harus dinyatakan sebagai abstract
kelas ke kompiler.
Kelas yang dideklarasikan menggunakan kata kunci abstrak dikenal sebagai abstract class
. Abstraksi adalah proses menyembunyikan detail implementasi data, dan hanya menunjukkan fungsionalitas kepada pengguna. Abstraksi memungkinkan Anda fokus pada apa yang dilakukan objek alih-alih bagaimana melakukannya.
Hal utama dari kelas abstrak
Kelas abstrak mungkin atau mungkin tidak mengandung metode abstrak. Mungkin ada metode non abstrak.
Metode abstrak adalah metode yang dideklarasikan tanpa implementasi (tanpa kawat gigi, dan diikuti oleh tanda titik koma), seperti ini:
mis: abstract void moveTo(double deltaX, double deltaY);
Jika suatu kelas memiliki setidaknya satu metode abstrak maka kelas itu harus abstrak
Kelas abstrak mungkin tidak dipakai (Anda tidak diizinkan membuat objek dari kelas Abstrak)
Untuk menggunakan kelas abstrak, Anda harus mewarisinya dari kelas lain. Berikan implementasi untuk semua metode abstrak di dalamnya.
Jika Anda mewarisi kelas abstrak, Anda harus menyediakan implementasi untuk semua metode abstrak di dalamnya.
Deklarasikan kelas abstrak
Menentukan abstract
kata kunci sebelum kelas selama deklarasi membuatnya abstrak. Lihat kode di bawah ini:
abstract class AbstractDemo{ }
Deklarasikan metode abstrak
Menentukan abstract
kata kunci sebelum metode selama deklarasi menjadikannya abstrak. Lihat kode di bawah ini,
abstract void moveTo();//no body
Mengapa kita perlu mengabstraksi kelas
Dalam aplikasi menggambar berorientasi objek, Anda dapat menggambar lingkaran, persegi panjang, garis, kurva Bezier, dan banyak objek grafik lainnya. Semua objek ini memiliki status tertentu (untuk ex -: posisi, orientasi, warna garis, warna isi) dan perilaku (untuk ex -: moveTo, rotate, resize, draw) secara umum. Beberapa status dan perilaku ini adalah sama untuk semua objek grafik (misalnya: mengisi warna, posisi, dan moveTo). Lainnya memerlukan implementasi yang berbeda (misalnya: mengubah ukuran atau menggambar). Semua objek grafis harus dapat menggambar atau mengubah ukuran sendiri, mereka hanya berbeda dalam cara mereka melakukannya.
Ini adalah situasi yang sempurna untuk superclass abstrak. Anda dapat mengambil keuntungan dari kesamaan, dan mendeklarasikan semua objek grafik untuk diwariskan dari objek induk abstrak yang sama (misalnya:GraphicObject
seperti yang ditunjukkan pada gambar berikut.
Pertama, Anda mendeklarasikan kelas abstrak GraphicObject
,, untuk memberikan variabel dan metode anggota yang sepenuhnya dibagikan oleh semua subclass, seperti posisi saat ini dan metode moveTo. GraphicObject
juga menyatakan metode abstrak, seperti menggambar atau mengubah ukuran, yang perlu diimplementasikan oleh semua subclass tetapi harus diimplementasikan dengan cara yang berbeda. ItuGraphicObject
kelas dapat terlihat seperti ini:
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
Penggunaan metode abstrak dalam sub-kelas
Setiap subclass non abstrak GraphicObject
, seperti Circle
dan Rectangle
, harus menyediakan implementasi untuk draw
dan resize
metode.
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
Di dalam main
metode Anda dapat memanggil semua metode seperti ini:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Cara untuk mencapai abstraksi di Jawa
Ada dua cara untuk mencapai abstraksi di java
Kelas abstrak dengan konstruktor, anggota data, metode, dll
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
Keluaran:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
Ingat dua aturan:
Jika kelas memiliki beberapa metode abstrak dan beberapa metode konkret, nyatakanlah sebagai abstract
kelas.
Jika kelas hanya memiliki metode abstrak, nyatakan sebagai interface
.
Referensi:
Ini adalah kelas yang tidak dapat dipakai, dan memaksa menerapkan kelas untuk, mungkin, menerapkan metode abstrak yang diuraikan.
Secara sederhana, Anda dapat menganggap kelas abstrak seperti Antarmuka dengan kemampuan sedikit lebih.
Anda tidak dapat membuat instance Antarmuka, yang juga berlaku untuk kelas abstrak.
Pada antarmuka Anda, Anda bisa mendefinisikan header metode dan SEMUA pelaksana dipaksa untuk menerapkan semuanya . Pada kelas abstrak Anda juga dapat menentukan header metode Anda, tetapi di sini - untuk perbedaan antarmuka - Anda juga dapat menentukan tubuh (biasanya implementasi default) dari metode ini. Terlebih lagi ketika kelas lain memperpanjang (perhatikan, bukan implementasikan dan karena itu Anda juga dapat memiliki hanya satu kelas abstrak per kelas anak) kelas abstrak Anda, mereka tidak dipaksa untuk menerapkan semua metode Anda dari kelas abstrak Anda, kecuali jika Anda menentukan metode abstrak ( dalam kasus seperti itu berfungsi seperti untuk antarmuka, Anda tidak dapat mendefinisikan tubuh metode).
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
Kalau tidak untuk metode normal dari kelas abstrak, "pewaris" dapat menggunakan perilaku default atau menimpanya, seperti biasa.
Contoh:
public abstract class MyAbstractClass{
public int CalculateCost(int amount){
//do some default calculations
//this can be overriden by subclasses if needed
}
//this MUST be implemented by subclasses
public abstract void DoSomething();
}
Dari dokumentasi oracle
Metode dan Kelas Abstrak:
Kelas abstrak adalah kelas yang dinyatakan abstrak — mungkin atau tidak termasuk metode abstrak
Kelas abstrak tidak bisa dipakai, tetapi mereka bisa subkelas
Metode abstrak adalah metode yang dideklarasikan tanpa implementasi (tanpa kawat gigi, dan diikuti oleh tanda titik koma), seperti ini:
abstract void moveTo(double deltaX, double deltaY);
Jika suatu kelas menyertakan metode abstrak, maka kelas itu sendiri harus dinyatakan abstrak, seperti pada:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
Ketika kelas abstrak disubclass, subclass biasanya menyediakan implementasi untuk semua metode abstrak di kelas induknya. Namun, jika tidak, maka subkelas juga harus dinyatakan abstrak .
Karena abstract classes
dan interfaces
terkait, lihat pertanyaan SE di bawah ini:
Apa perbedaan antara antarmuka dan kelas abstrak?
Bagaimana seharusnya saya menjelaskan perbedaan antara Interface dan kelas Abstrak?
Dapatkan jawaban Anda di sini:
Kelas abstrak vs Antarmuka di Jawa
Bisakah kelas abstrak memiliki metode final?
BTW - itu adalah pertanyaan yang Anda tanyakan baru-baru ini. Pikirkan tentang pertanyaan baru untuk membangun reputasi ...
Edit:
Baru sadar, bahwa poster-poster ini dan pertanyaan yang direferensikan memiliki nama yang sama atau setidaknya mirip tetapi user-id selalu berbeda. Jadi, ada masalah teknis, bahwa keyur memiliki masalah masuk lagi dan menemukan jawaban atas pertanyaannya atau ini adalah semacam permainan untuk menghibur komunitas SO;)
Sedikit tambahan untuk semua posting ini.
Kadang-kadang Anda mungkin ingin mendeklarasikan kelas tetapi belum tahu cara mendefinisikan semua metode yang termasuk kelas itu. Sebagai contoh, Anda mungkin ingin mendeklarasikan kelas yang disebut Writer dan memasukkan di dalamnya metode anggota yang disebut write () . Namun, Anda tidak tahu cara menulis kode () karena berbeda untuk setiap jenis perangkat Writer. Tentu saja, Anda berencana untuk menangani ini dengan menurunkan subclass dari Writer, seperti Printer, Disk, Network dan Console.
Kelas abstrak tidak bisa langsung dipakai, tetapi harus diturunkan dari agar dapat digunakan. Kelas HARUS abstrak jika berisi metode abstrak: baik secara langsung
abstract class Foo {
abstract void someMethod();
}
atau secara tidak langsung
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
Namun, suatu kelas dapat abstrak tanpa mengandung metode abstrak. Ini cara untuk mencegah instan directation, mis
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
Gaya terakhir dari kelas abstrak dapat digunakan untuk membuat kelas "seperti antarmuka". Tidak seperti antarmuka, kelas abstrak diizinkan untuk berisi metode non-abstrak dan variabel instan. Anda dapat menggunakan ini untuk menyediakan beberapa fungsionalitas dasar untuk memperluas kelas.
Pola lain yang sering adalah untuk mengimplementasikan fungsi utama di kelas abstrak dan menentukan bagian dari algoritma dalam metode abstrak untuk diimplementasikan oleh kelas yang diperluas. Contoh bodoh:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
public abstract class Place {
String Name;
String Postcode;
String County;
String Area;
Place () {
}
public static Place make(String Incoming) {
if (Incoming.length() < 61) return (null);
String Name = (Incoming.substring(4,26)).trim();
String County = (Incoming.substring(27,48)).trim();
String Postcode = (Incoming.substring(48,61)).trim();
String Area = (Incoming.substring(61)).trim();
Place created;
if (Name.equalsIgnoreCase(Area)) {
created = new Area(Area,County,Postcode);
} else {
created = new District(Name,County,Postcode,Area);
}
return (created);
}
public String getName() {
return (Name);
}
public String getPostcode() {
return (Postcode);
}
public String getCounty() {
return (County);
}
public abstract String getArea();
}
Kelas abstrak adalah kelas yang dinyatakan abstrak - mungkin atau mungkin tidak termasuk metode abstrak. Kelas abstrak tidak bisa dipakai, tetapi mereka bisa subkelas.
Dengan kata lain, kelas yang dideklarasikan dengan kata kunci abstrak, dikenal sebagai kelas abstrak di java. Itu dapat memiliki metode abstrak (metode tanpa tubuh) dan non-abstrak (metode dengan tubuh).
Catatan Penting: - Kelas abstrak tidak dapat digunakan untuk instantiate objek, mereka dapat digunakan untuk membuat referensi objek, karena pendekatan Java terhadap run-time Polymorphism diimplementasikan melalui penggunaan referensi superclass. Dengan demikian, harus dimungkinkan untuk membuat referensi ke kelas abstrak sehingga dapat digunakan untuk menunjuk ke objek subclass. Anda akan melihat fitur ini dalam contoh di bawah ini
abstract class Bike{
abstract void run();
}
class Honda4 extends Bike{
void run(){
System.out.println("running safely..");
}
public static void main(String args[]){
Bike obj = new Honda4();
obj.run();
}
}
Kelas abstrak adalah kelas yang tidak sepenuhnya diimplementasikan tetapi menyediakan cetak biru untuk subclass. Ini dapat diimplementasikan sebagian karena mengandung metode konkret sepenuhnya, tetapi juga dapat menampung metode abstrak. Ini adalah metode dengan tanda tangan tetapi tidak ada badan metode. Subkelas apa pun harus mendefinisikan suatu badan untuk setiap metode abstrak, jika tidak, ia juga harus dinyatakan abstrak. Karena kelas abstrak tidak dapat dipakai, mereka harus diperluas oleh setidaknya satu subclass agar dapat digunakan. Pikirkan kelas abstrak sebagai kelas generik, dan subkelas ada di sana untuk mengisi informasi yang hilang.
Tidak melakukan apa-apa, cukup sediakan template umum yang akan dibagikan untuk subkelasnya