Soyut sınıflar, arayüzler ve bunların ne zaman kullanılacağı arasındaki farklar nelerdir


15

Son zamanlarda başımı OOP etrafına sarmaya başladım ve şimdi soyut sınıflar ve arayüzler arasındaki farklar hakkında ne kadar çok okursam o kadar karışık hale geliyorum. Şimdiye kadar ikisi de somutlaştırılamaz. Arayüzler iskeleti belirleyen az ya da çok yapısal planlardır ve özetler kısmen kod uygulayarak farklıdır.

Özel durumum aracılığıyla bunlar hakkında daha fazla bilgi edinmek istiyorum. İşte biraz daha fazla arka plan bilgisi istiyorsanız ilk sorumun bağlantısı: Yeni sınıfım için iyi bir tasarım modeli nedir?

İşte oluşturduğum iki sınıf:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

Gördüğünüz gibi bu sınıflar neredeyse aynı. Değil Burada gösterilen, ancak diğer fonksiyonlar vardır like get_zip(), save_to_database()benim sınıfları arasında yaygındır. Ayrıca, tüm ortak yöntemlere ve elbette bu sınıflara özgü özelliklere (örneğin, kilometre, ağırlık) sahip diğer sınıflar Otomobil ve Evcil Hayvanlar da ekledim.

Şimdi DRY prensibini ihlal ettim ve aynı kodu birden fazla dosyada yönetiyorum ve değiştiriyorum. Tekneler, atlar ya da her neyse daha fazla ders almayı düşünüyorum.

Yani bir arayüz veya soyut bir sınıf kullanacağım yer burası mı? Soyut sınıflar hakkında anladığım kadarıyla, bir soyut sınıfı soyut sınıfa yerleştirilmiş tüm ortak unsurları içeren bir şablon olarak kullanır ve daha sonra sadece gelecekteki sınıflarda özellikle gerekli olan öğeleri eklerdim. Örneğin:

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

Yoksa bir arabirim mi kullanırım ve bunlar birbirine çok benzediğinden, alt sınıfların her birinin bütünlük nedenleriyle kullanmak zorunda kaldığı bir yapı oluşturmalı ve her sınıftan sorumlu olmak için bu sınıftan çıkan son geliştiriciye bırakmalı mıyım? ortak işlevlerin bile ayrıntıları. benim düşüncem, bazı 'ortak' işlevlerin gelecekte kendi sınıflarının ihtiyaçları için değiştirilmesinin gerekebileceğidir.

Yukarıdaki tüm bunlara rağmen, soyut sınıfların ve arayüzlerin neyi ve nedenini yanlış anladığımı düşünüyorsanız, elbette geçerli bir cevabın bu yönde düşünmeyi bırakmasını ve ilerlemenin doğru yolunu önermesini sağlayın!

Teşekkürler!


İnternette çok iyi örnekler var. Bence bu onlardan biri. javapapers.com/core-java/abstract-and-interface-core-java-2/…
Siva

Yanıtlar:


26

Layman'ın terimleriyle:

Arayüzler içindir "yapabileceği / olarak tedavi edilebilir" ilişkilerin türü.

Özet (yanı sıra beton) sınıfları içindir "bir olan" tür ilişkinin.

Şu örneklere bak:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, MosquitoVe Horse vardır Animals . İlişkilidir. Hayvan gibi ortak yöntemleri miras alırlar eat(), metabolize() and reproduce(). Belki bu yöntemleri geçersiz kılarlar, onlara biraz ekstra eklerler, ancak Animal gibi uygulanan varsayılan davranıştan yararlanırlar.metabolizeGlucose().

Planeile ilişkili değildir Bird, Mosquitoya da Horse.

FlightBirdve benzeri olmayan, ilgisiz sınıflar tarafından uygulanır Plane.

AccountableAssetPlaneve benzeri olmayan, ilgisiz sınıflar tarafından da uygulanır RaceHorse.

Horse Uçuş uygulamıyor.

Gördüğünüz gibi sınıflar (soyut veya somut) , bir hiyerarşi oluşturmanıza yardımcı olarak , kodu üst düzeylerden daha düşük düzeylere kadar devralmanıza izin verir. Teoride, hiyerarşide ne kadar düşük olursanız, davranışınız o kadar uzmanlaşır, ancak halihazırda ilgilenilen birçok şey hakkında endişelenmenize gerek yoktur.

Öte yandan, arayüzler hiyerarşi oluşturmaz, ancak hiyerarşiler arasında belirli davranışları homojenleştirmeye yardımcı olabilir, böylece bunları belirli bağlamlarda hiyerarşiden soyutlayabilirsiniz.

Örneğin bir programın bir grup değerini özetlemek olabilir AccountableAssetsbakılmaksızın varlığının RaceHorsesya Planes.


İnanılmaz. Arayüz, can do/can be treated assoyut sınıfların temel olarak nerede hareket ettiğini gösteren belirli bir işlevsellik bölümü sağlar !
Abhiroj Panwar

13

İkisi arasındaki farkların farkında gibi göründüğünüz için cevabı mantıklı bir şekilde çıkarabilirsiniz.

Arayüzler ortak bir sözleşme tanımlar. Tüm hayvanların Eat (), Move (), Attack () vb. Gibi işlevleri paylaştığı IAnimal adlı bir arayüz gibi, hepsi aynı işlevleri paylaşırken, hepsinin veya çoğunun farklı bir başarı (uygulama) yöntemi vardır. o.

Soyut sınıflar ortak bir uygulamayı ve isteğe bağlı olarak ortak sözleşmeleri tanımlar. Örneğin basit bir Hesap Makinesi, tüm temel mantıksal ve bitsel operatörleri uygulayan ve daha sonra ScientificCalculator, GraphicalCalculator ve benzeri tarafından genişletilen soyut bir sınıf olarak nitelendirilebilir.

Ortak bir uygulamanız varsa, elbette, işlevselliği soyut bir sınıfta genişletmek için kapsülleyin. Ben 0 PHP deneyimim var, ama sabit olmayan alanlar ile arayüzler oluşturabilirsiniz sanmıyorum. Alanlar örnek sınıflarınız arasında ortaksa, alıcılar ve ayarlayıcılar aracılığıyla bunlara erişimi tanımlamazsanız, bir Abstract sınıfı kullanmak zorunda kalırsınız.

Ayrıca, Google'da sonuç sıkıntısı yok gibi görünüyor.


3

Uzun lafın kısası. Soyut sınıflar Arayüzlere çok benzer, çünkü her ikisi de miras alan sınıfta hangi yöntemlerin olması gerektiğine dair bir şablon sağlar, ancak büyük farklılıklar vardır: - Arayüzler sadece kalıtsal bir sınıfta bulunması gereken isimleri / yöntem türlerini tanımlarken, sınıfların tam bir varsayılan kod kodu olabilir ve sadece ayrıntıların gereğinden fazla basması gerekebilir. - Arayüzlerde erişim değiştiricileri bulunamaz. - Arabirimlerde alan olamaz. - Sınıflar, birden çok arabirimi devralabilirken, sınıfların birden çok mirasına sahip olamaz. - Ayrıca, sınıflar bir hiyerarşi yapısı sağlar, böylece yalnızca belirli bir sınıftan türetilmiş sınıflar soyut sınıfın yönergelerini izlemelidir: nesne-> belirli nesne-> çok özel nesne. Diğer yandan arayüzler herhangi bir yerde herhangi bir kişi tarafından miras alınabilir.

Bence soyut sınıflar, kodun hemen varsayılan olarak uygulanmasını sağlayabildikleri için daha yaygındır, ancak belirli sınıfları standartlaştırmanız gereken büyük ölçekli projelerde arayüzler kullanışlı olabilir.

Umarım yardımcı olur, ancak bu çevrimiçi hakkında çok fazla bilgi var, Leo


2
Classes cannot have multiple inheritance- Java ve C # gibi diller için doğru, C ++ için doğru değil.
Robert Harvey

3

Öncelikle, hem bir arayüz hem de soyut bir sınıf sağlayacağınızı anlamalısınız. Bunun nedeni ve ikisi arasındaki temel fark, farklı kodları yeniden kullanmanıza ve böylece farklı sorunları çözmenize izin vermesidir.

Arabirimler, istemci kodunu farklı uygulamalarla yeniden kullanmanızı sağlar. Get_data ($ website) sınıfınızdaki bir müşteri $ title veya $ description öğelerini önemsemiyor. Sadece içeriğinize veri yüklemesi talimatını vermek istiyor. Bazıları $ açıklamasına ihtiyaç duyan ve bazıları gerektirmeyen farklı içerik türleriniz varsa, yalnızca alt sınıflarınızın imzasını belirten bir ContentInterface sınıfı sağlayabilirsiniz. Artık müşteri, nasıl çalıştığını tam olarak bilmeden herhangi bir sayıda farklı İçeriğe sahip olabilir. Liskov değiştirme prensibi bu fikri çalışma hakkında bilgi almak için iyi bir şeydir. Bob Amca'nın konuyla ilgili yazmasını da seviyorum . Arayüzler birim testi için çok önemlidir ve arayüzler oluşturmak iyi bir alışkanlıktır.

Soyut sınıflar, ortak bir atayı paylaşan bir grup sınıfta ortak uygulama ayrıntılarını yeniden kullanmanızı sağlar. Sorunuzda, uygulamayı soyut bir sınıftan neden miras alacağınız konusunda iyi bir ele sahip görünüyorsunuz. Bir temel sınıfın içlerine bağımlı olmak hala tehlikelidir - kapsüllemeyi ihlal etmek ve bir temel sınıfın belirli uygulama ayrıntılarına bağlı olan çocuklar oluşturmak çok kolaydır. İskelet Metodu şablonu kapsülleme zarar vermeden temel sınıfları nasıl kullanılacağına dair yaygın ve sağlıklı bir örneğini sağlar.

Bu nedenle, umduğum gibi, sınıf hiyerarşinizin istemcileri için genellikle arabirimler sağlarsınız, böylece istemci kodunu etkilemeden uygulamanızı güvenle değiştirebilirsiniz. Bu, istemcinin arabiriminizi devralan Mock Nesneleri kullanarak birim testleri yazmasına olanak tanır . Ayrıca, ortak mantığın yeniden kullanılmasına izin veren veya alt sınıflar için anlambilimi zorunlu kılan soyut sınıflar da sunacaksınız.


3

Fark ince ama net bir fark. Arayüz polimorfik davranışla ilgilidir. Soyut sınıf yeniden kullanım ve polimorfik davranışla ilgilidir.

Yeniden kullanım ve polimorfik davranışa vurgu yapmak istiyorsanız soyut sınıfı seçin. Örneğin, farklı tipteki çalışanların farklı hükümleri vardır, ancak hepsinin birkaç ortak hakkı vardır. Ortaklıklar bir baz soyut sınıf ifade edilebilir çünkü böylece, özet sınıfı temsil etmek üzere uygun olan Employeeve fark gibi türetilmiş sınıflar içinde uygulanabilir Managerveya Workervs.

Sadece polimorfik davranışa vurgu yapmak istiyorsanız arayüz seçin. Arayüz daha çok sözleşmeyle, yani belirli davranışlara uygun olduğunu söyleyen bir nesne veya hiyerarşi ile ilgilidir. Örneğin, tüm çalışanların izinli hükümleri vardır, ancak farklı çalışanların farklı hükümleri vardır. Bu nedenle, her farklı çalışan türü farklı bir izin hesaplayıcısı gerektirir. Burada arayüz iyi bir seçimdir çünkü her tür çalışan farklı LeaveCalculatorbir Calculate()davranışa sahip bir arayüz uygulayabilir .


-3
  1. Temel fark, bir Java arayüzünün yöntemlerinin dolaylı olarak soyut olması ve uygulamaları olamaz. Java soyut sınıfında, varsayılan davranışı uygulayan örnek yöntemler bulunabilir.
  2. Java arayüzünde bildirilen değişkenler varsayılan olarak son şeklindedir. Soyut bir sınıf, son olmayan değişkenler içerebilir.
  3. Java arabiriminin üyeleri varsayılan olarak herkese açıktır. Bir Java soyut sınıfı, özel, korumalı vb.Gibi sınıf üyelerinin olağan lezzetlerine sahip olabilir.
  4. Java arayüzü “implements” anahtar sözcüğü kullanılarak uygulanmalıdır; Bir Java soyut sınıfı, "extends" anahtar kelimesi kullanılarak genişletilmelidir.
  5. Bir arabirim başka bir Java arabirimini genişletebilir, yalnızca soyut bir sınıf başka bir Java sınıfını genişletebilir ve birden çok Java arabirimi uygulayabilir.
  6. Bir Java sınıfı birden çok arabirim uygulayabilir, ancak yalnızca bir soyut sınıfı genişletebilir.
  7. Arayüz kesinlikle soyuttur ve somutlaştırılamaz; Bir Java soyut sınıfı da somutlaştırılamaz, ancak bir main () varsa çağrılabilir.
  8. Java soyut sınıfları ile karşılaştırıldığında, java arayüzleri ekstra dolaylama gerektirdiğinden yavaştır.
  9. Java'daki arabirim ve soyut sınıf, arabirimde soyut olmayan bir yöntem oluşturamazsınız, arabirimdeki her yöntem varsayılan olarak soyuttur, ancak soyut sınıfta soyut olmayan bir yöntem oluşturabilirsiniz.
  10. Java'daki soyut sınıf ve arabirim, arabirimlerin Tür bildirimi için daha uygun, soyut sınıf ise kodun yeniden kullanımı ve evrim perspektifi için daha uygundur.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.