Java'da "soyut sınıf" nedir?
Java'da "soyut sınıf" nedir?
Yanıtlar:
Soyut bir sınıf, somutlaştırılamayan bir sınıftır. Soyut bir sınıf, devralınabilen bir alt sınıf oluşturarak kullanılır örneği. Soyut bir sınıf, miras kalan alt sınıf için birkaç şey yapar:
İşte bir örnek:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
"AbstractMethod ()" öğesinin herhangi bir yöntem gövdesi olmadığına dikkat edin. Bu nedenle, aşağıdakileri yapamazsınız:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
Uygulayan bir yöntem yok abstractMethod()
! Yani JVM'nin böyle bir şey olduğunda ne yapması gerektiğini bilmesi mümkün değilnew ImplementingClass().abstractMethod()
.
İşte doğru ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
implementedMethod()
Veya tanımlamak zorunda olmadığınıza dikkat edin finalMethod()
. Tarafından zaten tanımlanmışlardı AbstractClass
.
İşte başka bir doğru ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
Bu durumda, geçersiz kıldınız implementedMethod()
.
Ancak, final
anahtar kelime nedeniyle aşağıdakiler mümkün değildir.
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!"); }
}
Uygulanması çünkü bunu yapamaz finalMethod()
içinde AbstractClass
nihai uygulama olarak işaretlenir finalMethod()
: hayır diğer uygulamalar izin verilecektir, asla.
Şimdi yapabilirsiniz ayrıca iki kez soyut bir sınıf uygulamak:
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()"); }
}
Şimdi bir yere başka bir yöntem yazabilirsiniz.
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()"
}
b
Bir AbstractClass
tür bildirmiş olsak da , görüntülendiğine dikkat edin "Overriden!"
. Biz örneği nesne aslında bir oldu olmasıdır ImplementingClass
, kiminimplementedMethod()
elbette geçersiz kılınmış olmasıdır. (Bunun polimorfizm olarak adlandırıldığını görmüş olabilirsiniz.)
Belirli bir alt sınıfa özgü bir üyeye erişmek istiyorsak, önce o alt sınıfa inmeliyiz:
// 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();
Son olarak, aşağıdakileri yapamazsınız:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
Bir seferde yalnızca bir sınıf genişletilebilir. Birden fazla sınıfı genişletmeniz gerekiyorsa, bunlar arayüz olmalıdır. Bunu yapabilirsiniz:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
İşte bir örnek arayüz:
interface InterfaceA
{
void interfaceMethod();
}
Bu temel olarak aynıdır:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
Tek fark, ikinci yolun derleyicinin aslında bir arayüz olduğunu bilmemesidir. İnsanların yalnızca arayüzünüzü uygulamasını ve başkalarının uygulamasını istemiyorsanız bu yararlı olabilir. Bununla birlikte, genel bir başlangıç kuralı olarak, soyut sınıfınızda sadece soyut yöntemler varsa, muhtemelen bir arayüz yapmalısınız.
Aşağıdakiler yasa dışıdır:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
Bir arabirime yöntem uygulayamazsınız. Bu, iki farklı arabirim uygularsanız, bu arabirimlerdeki farklı yöntemlerin çarpışamayacağı anlamına gelir. Bir arabirimdeki tüm yöntemler soyut olduğundan, yöntemi uygulamanız gerekir ve yönteminiz kalıtım ağacındaki tek uygulama olduğundan, derleyici yönteminizi kullanması gerektiğini bilir.
c.implementedMethod()
"Overriden!" SecondImplementingClass
geçersiz kılmaz implementedMethod()
.
Bir Java sınıfı aşağıdaki koşullar altında soyut hale gelir:
1. Yöntemlerden en az biri soyut olarak işaretlenmiştir:
public abstract void myMethod()
Bu durumda derleyici sizi tüm sınıfı soyut olarak işaretlemeye zorlar.
2. Sınıf özet olarak işaretlenmiştir:
abstract class MyClass
Daha önce de belirtildiği gibi: Soyut bir yönteminiz varsa, derleyici sizi tüm sınıfı soyut olarak işaretlemeye zorlar. Ancak herhangi bir soyut yönteminiz olmasa bile, sınıfı yine de soyut olarak işaretleyebilirsiniz.
Genel kullanım:
Soyut sınıfların yaygın bir kullanımı, bir arayüze benzer bir sınıfın taslağını sağlamaktır. Ancak bir arayüzden farklı olarak zaten işlevsellik sağlayabilir, yani sınıfın bazı bölümleri uygulanır ve bazı bölümler sadece bir yöntem bildirimi ile özetlenir. ("Öz")
Soyut bir sınıf somutlaştırılamaz, ancak o zaman somutlaştırılabilecek bir soyut sınıfa dayalı somut bir sınıf oluşturabilirsiniz. Bunu yapmak için soyut sınıftan miras almanız ve soyut yöntemleri geçersiz kılmanız, yani bunları uygulamanız gerekir.
abstract
bir sınıfın soyut olması için gerekli olan tek şey anahtar kelimedir. Ancak bir beton sınıfı edilemez bir içeren abstract
bir yöntem . Bu nedenle, sınıfınızda bir abstract
yöntem varsa abstract
, derleyiciye bir sınıf olarak bildirilmelidir .
Abstract anahtar sözcüğü kullanılarak bildirilen bir sınıf olarak bilinir abstract class
. Soyutlama, veri uygulama ayrıntılarını gizleme ve kullanıcıya yalnızca işlevsellik gösterme işlemidir. Soyutlama, nesnenin nasıl yaptığı yerine ne yaptığına odaklanmanızı sağlar.
Soyut sınıfın ana şeyleri
Soyut bir sınıf soyut yöntemler içerebilir veya içermeyebilir.
Soyut bir yöntem, uygulama olmadan (parantez olmadan ve ardından noktalı virgül olmadan) bildirilen bir yöntemdir, şöyle:
ör .: abstract void moveTo(double deltaX, double deltaY);
Bir sınıfın en az bir soyut yöntemi varsa, o sınıf soyut olmalıdır
Soyut sınıflar somutlaştırılamaz (Soyut sınıf nesnesi oluşturmanıza izin verilmez)
Soyut bir sınıf kullanmak için başka bir sınıftan miras almanız gerekir. İçindeki tüm soyut yöntemlere uygulamalar sağlayın.
Soyut bir sınıfı miras alırsanız, içindeki tüm soyut yöntemlere uygulamalar sağlamanız gerekir.
Soyut sınıfabstract
bildirme Bildirim sırasında sınıftan önce anahtar sözcük
belirtilmesi onu soyut yapar. Aşağıdaki koda bir göz atın:
abstract class AbstractDemo{ }
Bildiri özeti yöntemi Bildiriabstract
sırasında yöntemden önce anahtar sözcük
belirtilmesi bunu özetler. Aşağıdaki koda bir göz atın,
abstract void moveTo();//no body
Neden soyut derslere ihtiyacımız var?
Nesneye yönelik bir çizim uygulamasında daireler, dikdörtgenler, çizgiler, Bezier eğrileri ve diğer birçok grafik nesnesini çizebilirsiniz. Bu nesnelerin hepsinde belirli durumlar (ex -: konum, yön, çizgi rengi, dolgu rengi için) ve ortak davranışlar (ex -: moveTo, rotate, resize, draw için) vardır. Bu durumlardan ve davranışlardan bazıları tüm grafik nesneleri için aynıdır (örneğin: dolgu rengi, konumu ve moveTo için). Diğerleri farklı uygulama gerektirir (ör: yeniden boyutlandırma veya çizim için). Tüm grafik nesneleri kendilerini çizebilmeli veya yeniden boyutlandırabilmelidir, sadece nasıl yaptıkları konusunda farklılık gösterirler.
Bu, soyut bir üst sınıf için mükemmel bir durumdur. Benzerliklerden faydalanabilir GraphicObject
ve aşağıdaki şekilde gösterildiği gibi, tüm grafik nesnelerini aynı soyut üst nesneden (örn. İçin ) miras alacağını bildirebilirsiniz .
İlk olarak, geçerli GraphicObject
değişken ve moveTo yöntemi gibi tüm alt sınıflar tarafından tamamen paylaşılan üye değişkenleri ve yöntemleri sağlamak için soyut bir sınıf bildirirsiniz. GraphicObject
ayrıca, tüm alt sınıflar tarafından uygulanması gereken, ancak farklı şekillerde uygulanması gereken, çizim veya yeniden boyutlandırma gibi soyut yöntemler bildirmiştir. GraphicObject
Sınıf böyle bir şey bakabilirsiniz:
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();
}
Alt sınıflarında soyut yöntemin kullanımı
her olmayan arka alt sınıfları GraphicObject
gibi, Circle
ve Rectangle
, için uygulamaları sağlamalıdır draw
ve resize
yöntemler.
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
}
}
main
Yöntemin içinde aşağıdaki gibi tüm yöntemleri çağırabilirsiniz:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Java'da soyutlama elde etmenin yolları
Java'da soyutlama elde etmenin iki yolu vardır
Yapıcılar, veri üyeleri, yöntemler vb. İle soyut sınıf
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);
}
}
Çıktı:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
İki kuralı hatırlayın:
Sınıfın çok az soyut yöntemi ve çok az somut yöntemi varsa, bunu abstract
sınıf olarak ilan edin .
Sınıfta yalnızca soyut yöntemler varsa, bunu bir interface
.
Referanslar:
Bu somutlaştırılamayan bir sınıftır ve uygulayan sınıfları, muhtemelen özetlediği soyut yöntemleri uygulamaya zorlar.
Basitçe söylemek gerekirse, soyut bir sınıfı biraz daha yetenekli bir Arayüz gibi düşünebilirsiniz.
Soyut bir sınıf için de geçerli olan bir Arabirim başlatamazsınız.
Arayüzünüzde sadece yöntem başlıklarını tanımlayabilirsiniz ve TÜM uygulayıcılar hepsini uygulamak zorunda kalırlar . Soyut bir sınıfta yöntem başlıklarınızı da tanımlayabilirsiniz, ancak burada - arayüzün farkına göre - ayrıca yöntemin gövdesini de (genellikle varsayılan bir uygulama) tanımlayabilirsiniz. Diğer sınıflar uzatmak Dahası (not uygulamıyor ve bu nedenle ayrıca sadece olabilir bir soyut sınıf bir belirtilmediği sürece sizin soyut sınıf alt sınıf başına), onlar, sizin soyut sınıfın senin yöntemlerin hepsi uygulamak zorunda değildir soyut yöntem ( bu durumda arayüzler gibi çalışır, yöntem gövdesini tanımlayamazsınız).
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
Aksi takdirde, soyut bir sınıfın normal yöntemleri için, "mirasçılar" her zamanki gibi varsayılan davranışı kullanabilir veya geçersiz kılabilir.
Misal:
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();
}
Oracle Belgelerinden
Soyut Yöntemler ve Sınıflar:
Soyut sınıf, soyut olarak adlandırılan bir sınıftır - soyut yöntemler içerebilir veya içermeyebilir
Soyut sınıflar örneklenemez, ancak alt sınıflara ayrılabilirler
Soyut bir yöntem, uygulama olmadan (parantez olmadan ve ardından noktalı virgül olmadan) bildirilen bir yöntemdir, şöyle :
abstract void moveTo(double deltaX, double deltaY);
Bir sınıf soyut yöntemler içeriyorsa, sınıfın kendisi aşağıdaki gibi soyut olarak bildirilmelidir:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
Bir soyut sınıf alt sınıflandığında, alt sınıf genellikle ana sınıfındaki tüm soyut yöntemlerin uygulamalarını sağlar. Ancak, bunu yapmazsa, alt sınıfın da soyut olarak bildirilmesi gerekir .
Yana abstract classes
ve interfaces
ilgili, SE soruları aşağıda bir göz:
Bir arayüz ile soyut sınıf arasındaki fark nedir?
Bir Interface ve Abstract sınıfı arasındaki farkı nasıl açıklamalıydım?
Yanıtlarınızı buradan alın:
Soyut bir sınıfın son bir yöntemi olabilir mi?
BTW - bunlar yakın zamanda sorduğunuz soru. İtibar oluşturmak için yeni bir soru düşünün ...
Düzenle:
Az önce fark ettim ki, bunun posterleri ve atıfta bulunulan sorular aynı veya en azından benzer bir isme sahip ancak kullanıcı kimliği her zaman farklı. Yani, ya teknik bir sorun var, keyur'un tekrar giriş yapma ve sorularının cevaplarını bulmada sorunları var ya da bu SO topluluğunu eğlendirmek için bir tür oyun;)
Tüm bu yayınlara küçük bir ek.
Bazen bir sınıf ilan etmek isteyebilir, ancak o sınıfa ait tüm yöntemleri nasıl tanımlayacağınızı bilmeyebilirsiniz. Örneğin, Writer adında bir sınıf bildirmek ve bu sınıfta write () adında bir üye yöntemi eklemek isteyebilirsiniz . Ancak, her Writer aygıtı türü için farklı olduğu için write () kodunun nasıl yazılacağını bilmiyorsunuz . Elbette, Yazıcı, Disk, Ağ ve Konsol gibi Yazar alt sınıfını türeterek bunu ele almayı planlıyorsunuz.
Soyut bir sınıf doğrudan somutlaştırılamaz, ancak kullanılabilir olmaktan türetilmelidir. Bir sınıf , soyut yöntemler içeriyorsa soyut olmalıdır ZORUNLU : ya doğrudan
abstract class Foo {
abstract void someMethod();
}
veya dolaylı olarak
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
Ancak, bir sınıf soyut yöntemler içermeden soyut olabilir. Doğrudan yerleştirmeyi önlemenin bir yolu, ör.
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
Soyut sınıfların ikinci stili "arayüz-benzeri" sınıflar oluşturmak için kullanılabilir. Arabirimlerin aksine, soyut bir sınıfın soyut olmayan yöntemler ve örnek değişkenleri içermesine izin verilir. Sınıfları genişletmek için bazı temel işlevsellik sağlamak için bunu kullanabilirsiniz.
Bir diğer sık rastlanan örüntü, soyut sınıftaki ana işlevselliği uygulamak ve algoritmanın bir kısmını genişletme sınıfı tarafından uygulanacak soyut bir yöntemde tanımlamaktır. Aptal örnek:
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();
}
Soyut sınıf, soyut olarak adlandırılan bir sınıftır - soyut yöntemler içerebilir veya içermeyebilir. Soyut sınıflar somutlaştırılamaz, ancak alt sınıflara ayrılabilirler.
Diğer bir deyişle, soyut anahtar sözcükle bildirilen bir sınıf, java'da soyut sınıf olarak bilinir. Soyut (bedensiz yöntem) ve soyut olmayan yöntemlere (vücut yöntemiyle) sahip olabilir.
Önemli Not: - Soyut sınıflar nesneleri örneklemek için kullanılamazlar, Java'nın çalışma zamanı polimorfizmine yaklaşımı üst sınıf referansları kullanılarak uygulandığından nesne referansları oluşturmak için kullanılabilirler. Bu nedenle, bir alt sınıf nesnesine işaret etmek için kullanılabilmesi için soyut bir sınıfa başvuru oluşturmak mümkün olmalıdır. Bu özelliği aşağıdaki örnekte göreceksiniz
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();
}
}
Soyut bir sınıf, tam olarak uygulanmayan ancak alt sınıflar için bir plan sağlayan bir sınıftır. Tamamen tanımlanmış somut yöntemler içerdiği için kısmen uygulanabilir, ancak soyut yöntemleri de tutabilir. Bunlar imzası olan ancak yöntem gövdesi olmayan yöntemlerdir. Herhangi bir alt sınıf, her soyut yöntem için bir gövde tanımlamalıdır, aksi takdirde soyut olarak da beyan edilmelidir. Soyut sınıflar somutlaştırılamadığından, kullanılabilmek için en az bir alt sınıf tarafından genişletilmelidirler. Soyut sınıfı genel sınıf olarak düşünün ve alt sınıflar eksik bilgileri doldurmak için oradalar.
Hiçbir şey yapmaz, sadece alt sınıfı için paylaşılacak ortak bir şablon sağlayın