Karışımlar veya özellikler düz çoklu kalıtımdan nasıl daha iyidir?


54

C ++ çoklu çoklu mirasa sahip, birçok dil tasarımını tehlikeli olarak yasaklıyor. Ancak, Ruby ve PHP gibi bazı diller aynı şeyi yapmak için garip sözdizimi kullanır ve bunları karmaşa veya özellikler olarak adlandırır. Karışımların / özelliklerin kötüye kullanımı basit çoklu kalıtımdan ziyade zor olduğunu defalarca duydum.

Onları özel olarak daha az tehlikeli yapan nedir? Mixins / özelliklerle mümkün olmayan ancak C ++ tarzı çoklu kalıtım ile mümkün olan bir şey var mı? Elmas problemine onlarla rastlamak mümkün mü?

Bu, çoklu kalıtım kullanıyormuşuz gibi görünüyor, ancak bunların karışım / özellik olduğu için mazeret göstererek onları kullanabiliriz.


7
Buna iyi yazılmış, düşünceli ve tam bir cevap veren birini bekliyorum.
Robert Harvey,

7
Ruby ve PHP, karışımları ve özellikleri tanıtmadı. Mixins Flavors'da (1980) tanıtıldı, Özellikler Squeak Smalltalk'te (2001) tanıtıldı. Flavors, çoklu kalıtım içeren ilk nesne yönelimli dildi ve karışımları kullandı. C ++, yalnızca, Flavors'dan 9 yıl sonra 1989'da piyasaya sürülen 2.0 sürümünde birden fazla kalıtım aldı. Öyleyse, soru şu olmalı: Flavours düz karışımlara sahiptir, ancak C ++ gibi bazı diller aynı şeyi yapmak ve çoklu kalıtım olarak adlandırmak için garip sözdizimi getirir.
Jörg W Mittag

Yanıtlar:


31

Tam teşekküllü sınıflarla kullanıldığında çoklu kalıtımla ilgili bir takım problemler vardır, fakat hepsi belirsizlik etrafında döner .

Belirsizlik birkaç farklı şekilde ortaya çıkıyor:

  1. Aynı alana sahip iki temel sınıfınız varsa xve türetilmiş tür isterse xne elde eder?
    • İki xdeğişkenin uyumsuz türleri varsa, onu çıkartabilirsiniz.
    • Aynı tiplerse, onları aynı değişkende birleştirmeyi deneyebilirsiniz.
    • Onları her zaman tuhaf tam isimler olarak gösterebilirsin.
  2. Aynı fimzalara sahip aynı işleve sahip iki temel sınıfınız varsa ve faranan biri aranırsa ?
    • Ya iki temel sınıf başka bir ortak sanal atayı (elmas problemi) paylaşırsa?
    • İşlev farklı ancak uyumlu imzalara sahipse?
  3. İki temel sınıf içeren bir sınıf oluşturduğunuzda, ilk temel sınıf yapıcısının hangisi ilk olarak adlandırılır? Öldürülen nesneyi yok ettiğinizde hangisi?
  4. Nesneyi belleğe yerleştirdiğinizde, tutarlı bir şekilde nasıl yaparsınız?
  5. Tüm bu vakaları 3 temel sınıfla nasıl ele alıyorsunuz? 10?

Bu, dinamik gönderim, yazım çıkarımı, örüntü eşleme ve daha az bildiğim diğer şeyler gibi görmezden gelir.

Özellikleri ya da Mix-in (veya arayüzler veya ...) özellikle tüm yapılar vardır sınırlamak belirsizlik yoktur, böylece bir türünün yetenekleri. Bunlar nadiren kendi şey kendileri. Bu, türlerin kompozisyonunun daha yumuşak olmasını sağlar çünkü iki değişken veya iki işlev yoktur ... bir değişken ve bir referans vardır; bir işlev ve bir imza. Derleyici ne yapılacağını bilir.

Alınan diğer yaygın yaklaşım, kullanıcının türünü bir kerede bir tane oluşturmaya (veya karıştırmaya) zorlamaktır. Temel sınıfların yeni türdeki eşit ortaklar yerine, bir türü diğerine eklersiniz - orada olan herhangi bir şeyi geçersiz kılar (genellikle geçersiz kılma bitlerini yeniden adlandırmak ve / veya yeniden göstermek için isteğe bağlı sözdizimi ile).

Mixins / özelliklerle mümkün olmayan ancak C ++ tarzı çoklu kalıtım ile mümkün olan bir şey var mı?

Dile bağlı olarak - genellikle birden fazla temel sınıftaki değişkenler için işlev ve depo uygulamalarını birleştirmek ve bunları türetilmiş tipte göstermek sıkıntılı veya imkansız hale gelir .

Onlarla elmas problemine rastlamak mümkün mü?

Bazen dilinize göre daha az ciddi değişiklikler olabilir, ancak genellikle hayır. Özelliklerin tamamı bu tür belirsizliği kırmaktır.


Bir örnek için bu tür "bina" türlerine izin veren dilin / teknolojinin bir örneğini verebilir misiniz?
Gherman

@german - Kesinlikle Scala uzmanı değilim, ancak benim anladığım şey withanahtar kelimenin orada yaptığı şey.
Telastyn

“özel olarak bir türün yeteneklerini sınırlayan ve böylece belirsizlik olmaması için yapılan yapılar”: ne tür sınırlamalar? Arayüzlerin değişkenleri yoktur, bu nedenle bir sınırdır, ancak Scala özellikleri ve Ruby modülleri bunu yapar. Başka yollarla sınırlı mı?
David Moles

@DavidMoles - bu ortak yoldur, ayrıca sanal gönderme kuralları konusunda da sınırlamalar gördüm (C # 'nin açıkça uygulandığı arayüzler olduğunu düşünüyorum).
Telastyn
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.