[ad_1]
Java kodunda ve hatta Java Development Kit’in (JDK) kendisinde soyut sınıflar ve arayüzler bol miktarda bulunur. Her kod öğesi temel bir amaca hizmet eder:
- Arayüzler bir çeşit kod sözleşmesisomut bir sınıf tarafından uygulanması gereken .
- soyut sınıflar içerebilecekleri farkla, normal sınıflara benzer soyut yöntemler, ki bunlar bedensiz yöntemlerdir. Soyut sınıflar somutlaştırılamaz.
Birçok geliştirici, arayüzlerin ve soyut sınıfların benzer olduğuna inanır, ancak aslında oldukça farklıdırlar. Aralarındaki temel farkları keşfedelim.
Bir arayüzün özü
Özünde, bir arayüz bir sözleşmedir, bu nedenle amacına hizmet edecek bir uygulamaya bağlıdır. bir arayüz asla bir devlet olamaz, bu nedenle değiştirilebilir örnek değişkenlerini kullanamaz. Bir arabirim yalnızca son değişkenleri kullanabilir.
Arayüzler ne zaman kullanılır
Arayüzler, kodu ayırmak ve polimorfizmi uygulamak için çok kullanışlıdır. JDK’da bir örnek görebiliriz, List
arayüz:
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean add(E e);
E remove(int index);
void clear();
}
Muhtemelen fark ettiğiniz gibi, bu kod kısa ve çok açıklayıcı. kolayca görebiliriz yöntem imzasısomut bir sınıf kullanarak arabirimdeki yöntemleri uygulamak için kullanacağız.
bu List
arabirim tarafından uygulanabilecek bir sözleşme içerir. ArrayList
, Vector
, LinkedList
ve diğer sınıflar.
Polimorfizmi kullanmak için, değişken türümüzü şu şekilde bildirebiliriz: List
ve ardından mevcut örneklemelerden herhangi birini seçin. İşte bir örnek:
List list = new ArrayList();
System.out.println(list.getClass());
List list = new LinkedList();
System.out.println(list.getClass());
İşte bu kodun çıktısı:
class java.util.ArrayList
class java.util.LinkedList
Bu durumda uygulama yöntemleri ArrayList
, LinkedList
ve Vector
hepsi farklıdır, bu da bir arayüz kullanmak için harika bir senaryodur. Birçok sınıfın aynı yöntem eylemlerine sahip ancak farklı davranışlara sahip bir üst sınıfa ait olduğunu fark ederseniz, bir arabirim kullanmak iyi bir fikirdir.
Şimdi, arayüzlerle yapabileceğimiz şeylerden birkaçına bakalım.
Bir arabirim yöntemini geçersiz kılma
Bir arabirimin, somut bir sınıf tarafından uygulanması gereken bir tür sözleşme olduğunu unutmayın. Arayüz yöntemleri dolaylı olarak soyuttur ve ayrıca somut bir sınıf uygulaması gerektirir.
İşte bir örnek:
public class OverridingDemo {
public static void main(String[] args) {
Challenger challenger = new JavaChallenger();
challenger.doChallenge();
}
}
interface Challenger {
void doChallenge();
}
class JavaChallenger implements Challenger {
@Override
public void doChallenge() {
System.out.println("Challenge done!");
}
}
İşte bu kodun çıktısı:
Challenge done!
Arayüz yöntemlerinin ayrıntılarına dikkat edin. dolaylı olarak soyut. Bu, onları açıkça soyut olarak beyan etmemize gerek olmadığı anlamına gelir.
sabit değişkenler
Hatırlanması gereken başka bir kural, bir arabirimin yalnızca sabit değişkenler içerebileceğidir. Bu nedenle, aşağıdaki kod iyidir:
public class Challenger {
int number = 7;
String name = "Java Challenger";
}
Her iki değişkenin de dolaylı olarak olduğuna dikkat edin. final
ve static
. Bu, sabit oldukları, bir örneğe bağlı olmadıkları ve değiştirilemeyecekleri anlamına gelir.
Değişkenleri değiştirmeye çalışırsak Challenger
arayüz, şöyle söyleyin:
Challenger.number = 8;
Challenger.name = "Another Challenger";
bunun gibi bir derleme hatası tetikleyeceğiz:
Cannot assign a value to final variable 'number'
Cannot assign a value to final variable 'name'
Varsayılan yöntemler
Java 8’de varsayılan yöntemler tanıtıldığında, bazı geliştiriciler bunların soyut sınıflarla aynı olacağını düşündüler. Ancak bu doğru değil, çünkü arayüzlerin durumu olamaz.
Varsayılan bir yöntemin bir uygulaması olabilir, oysa soyut yöntemlerin olamaz. Varsayılan yöntemler, lambdalar ve akışlarla ilgili büyük yeniliklerin sonucudur, ancak bunları dikkatli kullanmalıyız.
JDK’da varsayılan bir yöntem kullanan bir yöntem forEach()
parçası olan Iterable
arayüz. Herkese kod kopyalamak yerine Iterable
uygulama, basitçe yeniden kullanabiliriz forEach
yöntem:
default void forEach(Consumer<? super T> action) {
// Code implementation here…
Hiç Iterable
uygulanması kullanabilir forEach()
yeni bir yöntem uygulaması gerektirmeden yöntem. Ardından, kodu varsayılan bir yöntemle yeniden kullanabiliriz.
Kendi varsayılan yöntemimizi oluşturalım:
public class DefaultMethodExample {
public static void main(String[] args) {
Challenger challenger = new JavaChallenger();
challenger.doChallenge();
}
}
class JavaChallenger implements Challenger { }
interface Challenger {
default void doChallenge() {
System.out.println("Challenger doing a challenge!");
}
}
İşte çıktı:
Challenger doing a challenge!
Varsayılan yöntemler hakkında dikkat edilmesi gereken en önemli şey, her varsayılan yöntemin bir uygulamaya ihtiyaç duymasıdır. Varsayılan bir yöntem statik olamaz.
Şimdi soyut sınıflara geçelim.
Soyut bir sınıfın özü
Soyut sınıflar, örnek değişkenlerle duruma sahip olabilir. Bu, bir örnek değişkenin kullanılabileceği ve değiştirilebileceği anlamına gelir. İşte bir örnek:
public abstract class AbstractClassMutation {
private String name = "challenger";
public static void main(String[] args) {
AbstractClassMutation abstractClassMutation = new AbstractClassImpl();
abstractClassMutation.name = "mutated challenger";
System.out.println(abstractClassMutation.name);
}
}
class AbstractClassImpl extends AbstractClassMutation { }
İşte çıktı:
mutated challenger
Soyut sınıflarda soyut yöntemler
Tıpkı arayüzler gibi, soyut sınıfların da soyut yöntemleri olabilir. Bir soyut yöntem bedensiz bir yöntemdir. Arayüzlerden farklı olarak, soyut sınıflardaki soyut yöntemler, açıkça soyut olarak bildirilmelidir. İşte bir örnek:
public abstract class AbstractMethods {
abstract void doSomething();
}
Bir uygulama olmadan ve olmadan bir yöntem bildirmeye çalışmak abstract
anahtar kelime, bunun gibi:
public abstract class AbstractMethods {
void doSomethingElse();
}
şöyle bir derleme hatasıyla sonuçlanır:
Missing method body, or declare abstract
Soyut sınıflar ne zaman kullanılır?
Değişken durumu uygulamanız gerektiğinde soyut bir sınıf kullanmak iyi bir fikirdir. Örnek olarak, Java Koleksiyonları Çerçevesi şunları içerir: Özet Listesi değişkenlerin durumunu kullanan sınıf.
Sınıfın durumunu korumanızın gerekmediği durumlarda, genellikle bir arayüz kullanmak daha iyidir.
Soyut sınıflar ve arayüzler arasındaki farklar
Nesne yönelimli programlama perspektifinden, bir arayüz ile soyut bir sınıf arasındaki temel fark, bir arayüzün olumsuz durumu var, oysa soyut sınıf örnek değişkenlerle duruma sahip olabilir.
Diğer bir önemli fark, sınıfların birden fazla arabirim uygulayabilmeleri, ancak yalnızca bir soyut sınıfı genişletebilmeleridir. Bu, çoklu kalıtımın (birden fazla sınıfı genişletme) kod kilitlenmelerine neden olabileceği gerçeğine dayanan bir tasarım kararıdır. Java’nın mühendisleri bundan kaçınmaya karar verdi.
Diğer bir fark, arayüzlerin sınıflar tarafından uygulanabilmesi veya arayüzler tarafından genişletilebilmesi, ancak sınıfların yalnızca genişletilebilmesidir.
Lambda ifadelerinin yalnızca işlevsel bir arabirimle (yani yalnızca bir yöntemle bir arabirimle) kullanılabileceğini, yalnızca bir soyut yöntemle soyut sınıfların kullanılabileceğini not etmek de önemlidir. olumsuz lambda kullanın.
Tablo 1, soyut sınıflar ve arayüzler arasındaki farkları özetlemektedir.
Tablo 1. Arayüzleri ve soyut sınıfları karşılaştırma
Arayüzler |
soyut sınıflar |
---|---|
Yalnızca son statik değişkenlere sahip olabilir. Bir arayüz asla kendi durumunu değiştiremez. |
Değişken veya değiştirilemez herhangi bir örnek veya statik değişkene sahip olabilir. |
Bir sınıf birden çok arabirim uygulayabilir. |
Bir sınıf yalnızca bir soyut sınıfı genişletebilir. |
ile uygulanabilir. |
Sadece uzatılabilir. |
Yöntemler için yalnızca statik nihai alanlar, parametreler veya yerel değişkenler kullanabilir. |
Örnek değişken alanları, parametreleri veya yerel değişkenleri olabilir. |
Java’daki lambda özelliğini yalnızca işlevsel arabirimler kullanabilir. |
Yalnızca bir soyut yönteme sahip soyut sınıflar lambda kullanamaz. |
Yapıcı olamaz. |
yapıcısı olabilir. |
Soyut yöntemlere sahip olabilir. Varsayılan ve statik yöntemlere sahip olabilir (Java 8’de sunulmuştur). Uygulama ile özel yöntemlere sahip olabilir (Java 9’da sunulmuştur). |
Her türlü metoda sahip olabilir. |
Java kodu mücadelesine katılın!
Arayüzler ve soyut sınıflar arasındaki temel farkları bir Java kodu sorgulamasıyla keşfedelim. Aşağıdaki kod mücadelemiz var, yoksa yapabilirsiniz soyut sınıflar ve arayüzler mücadelesini bir video formatında görüntüleyin.
Aşağıdaki kodda, hem bir arabirim hem de bir soyut sınıf bildirilir ve kod ayrıca lambda’ları kullanır.
public class AbstractResidentEvilInterfaceChallenge {
static int nemesisRaids = 0;
public static void main(String[] args) {
Zombie zombie = () -> System.out.println("Graw!!! " + nemesisRaids++);
System.out.println("Nemesis raids: " + nemesisRaids);
Nemesis nemesis = new Nemesis() { public void shoot() { shoots = 23; }};
Zombie.zombie.shoot();
zombie.shoot();
nemesis.shoot();
System.out.println("Nemesis shoots: " + nemesis.shoots +
" and raids: " + nemesisRaids);
}
}
interface Zombie {
Zombie zombie = () -> System.out.println("Stars!!!");
void shoot();
}
abstract class Nemesis implements Zombie {
public int shoots = 5;
}
Bu kodu çalıştırdığımızda sizce ne olacak? Aşağıdakilerden birini seçin:
Seçenek A
Compilation error at line 4
B seçeneği
Graw!!! 0
Nemesis raids: 23
Stars!!!
Nemesis shoots: 23 and raids:1
C seçeneği
Nemesis raids: 0
Stars!!!
Graw!!! 0
Nemesis shoots: 23 and raids: 1
D seçeneği
Nemesis raids: 0
Stars!!!
Graw!!! 1
Nemesis shoots: 23 and raids:1
E seçeneği
Compilation error at line 6
Java kodu sorgulama videosu
Bu meydan okuma için doğru çıktıyı seçtiniz mi? Öğrenmek için videoyu izleyin veya okumaya devam edin.
Arayüzleri ve soyut sınıfları ve yöntemleri anlama
Bu Java kodu sorgulaması, arayüzler, soyut yöntemler ve daha fazlası hakkında birçok önemli kavramı gösterir. Kodu satır satır incelemek, çıktıda neler olduğu hakkında bize çok şey öğretecektir.
Kod sorgulamasının ilk satırı, aşağıdakiler için bir lambda ifadesi içerir: Zombie
arayüz. Bu lambdada statik bir alanı artırdığımıza dikkat edin. Burada bir örnek alanı da çalışır, ancak bir lambda dışında bildirilen yerel bir değişken çalışmaz. Bu nedenle, şimdiye kadar kod iyi derlenecek. Ayrıca lambda ifadesinin henüz yürütülmediğine dikkat edin, bu nedenle nemesisRaids
alan henüz artırılmayacak.
Bu noktada, yazdıracağız nemesisRaids
lambda ifadesi henüz çağrılmadığı için artırılmayan alan, yalnızca bildirildi. Bu nedenle, bu satırın çıktısı şöyle olacaktır:
Nemesis raids: 0
Bu Java kod mücadelesindeki bir başka ilginç kavram, bir anonim iç sınıf. Bu temel olarak, yöntemleri aşağıdakilerden uygulayacak herhangi bir sınıf anlamına gelir. Nemesis
soyut sınıf. gerçekten somutlaştırmıyoruz Nemesis
soyut sınıf çünkü aslında anonim bir sınıf. Ayrıca, ilk somut sınıfın, onları genişletirken her zaman soyut yöntemleri uygulamak zorunda kalacağına dikkat edin.
İçinde Zombie
arayüz, biz var zombie
static
Zombie
bir lambda ifadesi ile bildirilen arabirim. Bu nedenle, çağırdığımızda zombie shoot
yöntem, aşağıdakileri yazdırırız:
Stars!!!
Sonraki kod satırı, başlangıçta oluşturduğumuz lambda ifadesini çağırır. bu yüzden nemesisRaids
değişken artırılacaktır. Ancak, artırma sonrası operatörünü kullandığımız için, yalnızca bu kod ifadesinden sonra artırılacaktır. Bir sonraki çıktı şöyle olacaktır:
Graw!!! 0
Şimdi, çağıracağız shoot
yöntem nemesis
hangi onu değiştirecek shoots
örnek değişken 23
. Kodun bu bölümünün, bir arabirim ile soyut bir sınıf arasındaki en büyük farkı gösterdiğine dikkat edin.
Son olarak, değerini yazdırıyoruz nemesis.shoots
ve nemesisRaids
. Bu nedenle, çıktı olacaktır:
Nemesis shoots: 23 and raids: 1
Sonuç olarak, doğru çıktı C seçeneğidir:
Nemesis raids: 0
Stars!!!
Graw!!! 0
Nemesis shoots: 23 and raids: 1
Java hakkında daha fazla bilgi edinin
Bu hikaye, “Java’daki soyut sınıflara karşı arayüzler” orijinal olarak tarafından yayınlandı.
Telif Hakkı © 2022 IDG Communications, Inc.
[ad_2]
Kaynak : https://www.infoworld.com/article/2077421/abstract-classes-vs-interfaces-in-java.html#tk.rss_all