Mixin ve kalıtım


Yanıtlar:


67

Bir mixin tipik olarak çoklu kalıtım ile kullanılır. Yani bu anlamda "fark yok".

Ayrıntı, bir karışımın tek başına bir nesne olarak nadiren yararlı olmasıdır.

Örneğin, bir renk özelliği ve genişlik ve yükseklik ekleyen "ColorAndDimension" adında bir karışımınız olduğunu varsayalım.

Şimdi, ColorAndDimension'ı bir Shape sınıfına, Sprite sınıfına, Car sınıfına vb. Ekleyebilirsiniz. Hepsi aynı arabirime sahip olacaktır (örneğin get / setColor, get / setHeight / Width vb.)

Yani, jenerik durumda bir karışım kalıtımdır. Ancak, bir mixin'in "birincil" bir sınıf mı yoksa sadece bir mixin mi olduğu konusunda sınıfın genel etki alanındaki rolünün bir meselesi olduğunu iddia edebilirsiniz.


Düzenleme - sadece açıklığa kavuşturmak için.

Evet, günümüzün modern dilinde, ilişkili bir Uygulama ile bir Arayüz olarak bir mixin düşünülebilir. Bu gerçekten basit, eski, sade, eski, günlük bir sınıf kullanan günlük çoklu kalıtımdır. Sadece belirli bir MI uygulamasıdır. Çoğu dil, herhangi bir özel statünün karışımını vermez; bu, bağımsız olarak kullanılmaktan çok "karıştırılarak" tasarlanmış bir sınıftır.


30

Bir mixin ve miras arasındaki fark nedir?

Bir karışıklık içinde ek işlevsellik sağlamak için sizi devralabilir bir temel sınıftır. Sözde kod örneği:

class Mixin:
    def complex_method(self):
        return complex_functionality(self)

"Mix-in" adı, diğer kodla karıştırılmasının amaçlandığını gösterir. Bu nedenle, çıkarım, mix-in sınıfını kendi başına somutlaştırmayacağınızdır. Aşağıdaki nesnenin verisi yoktur ve complex_method'u çağırmak için onu somutlaştırmanın bir anlamı yoktur. (Bu durumda bir sınıf yerine bir işlev de tanımlayabilirsiniz.)

>>> obj = Mixin()

Sıklıkla mix-in, diğer temel sınıflarla kullanılır.

Bu nedenle, miksinler kalıtımın bir alt kümesi veya özel durumudur.

Tek kalıtıma göre mix-in kullanmanın avantajları, işlevsellik için bir kez kod yazabilmeniz ve ardından aynı işlevi birden çok farklı sınıfta kullanabilmenizdir. Dezavantajı, bu işlevi, kullanıldığı yerden başka yerlerde aramanız gerekebilmesidir, bu nedenle, bu dezavantajı yakında tutarak hafifletmek iyidir.

Şahsen, çok sayıda benzer kodu birim test ettiğimiz, ancak test senaryolarının temel vakanın kalıtımına ve kodu yakın tutmanın tek yoluna dayanılarak tek kalıtım üzerinden kullanmak için gerekli bir karışımı buldum. hand (ve aynı modülde), kapsama numaralarıyla uğraşmadan, nesneden miras almak ve alt vakaların hem evrensel test senaryosu tabanından hem de yalnızca kendileri için geçerli olan özel tabandan miras almasını sağlamaktır.

Soyut Temel Sınıflarla Karşılaştırma ve Kontrastlı Karışımlar

Her ikisi de somutlaştırılması amaçlanmayan bir ebeveyn sınıf biçimidir.

Bir mixin işlevsellik sağlar, ancak onu doğrudan kullanamaz. Bir kullanıcının bunu bir (alt) sınıf aracılığıyla kullanması amaçlanmıştır.

Bir soyut temel sınıftır bir arabirim sağlar, ancak kullanılabilir işlevsellik olmadan. Bir kullanıcının, arayüz tarafından çağrılan işlevi yaratması amaçlanır.

class Abstraction(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def complex_method(self):
        return complex_functionality(self)

Burada, işlevselliği somut bir yöntemle uygulamak için bir alt sınıf gerektirdiğinden bu nesneyi örneklemeniz engellenir (ancak içindeki işlevselliğe buradan erişebilirsiniz super()):

>>> obj = Abstraction()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstraction with
abstract methods complex_method

Python'da, abcmodüldeki bazı sınıflar , hem miras yoluyla işlevsellik sağlayan hem de alt sınıf tarafından uygulanması gereken soyut arabirimler sağlayan üst sınıf örnekleridir. Bu fikirler birbirini dışlamaz.

Özet

Basitçe ifade etmek gerekirse, bir mix-in, kendi başına somutlaştırmayacağınız ve tipik olarak çoklu kalıtımda ikincil temel sınıf olarak kullanılan temel bir sınıftır.


18

mix-in, uygulama amaçları için kullanılan belirli, kısıtlı bir (çoklu) miras durumudur; bazı diller (örneğin Ruby), genelleştirilmiş çoklu kalıtımı desteklemeden bunu destekler.


7

Mixin soyut bir kavramdır ve gereksinimini karşılayan her şey bir karışım olarak düşünülebilir.

İşte Wikipedia'dan bir tanım.

Nesneye yönelik programlama dillerinde, bir mixin, diğer sınıfların ana sınıfı olmak zorunda kalmadan diğer sınıflar tarafından kullanılacak yöntemleri içeren bir sınıftır. Bu diğer sınıfların mixin'in yöntemlerine nasıl erişeceği dile bağlıdır. Mixinler bazen "miras alınan" değil "dahil edilen" olarak tanımlanır.

Kısaca, bir kalıtımdan temel fark, mix-in'lerin kalıtımda olduğu gibi bir "is-a" ilişkisine ihtiyaç duymamasıdır.

Uygulama açısından bakıldığında, uygulamaları ile bir arayüz olarak düşünebilirsiniz. Örneğin, Java çoklu kalıtımı destekliyorsa, Java'daki soyut bir sınıf bir karışım olarak düşünülebilir.


Cesur cümleyi anlamakta zorlanıyorum. "B'nin A'dan farkı (B?) A'daki gibi bir şeye ihtiyaç duymasıdır" gibi geliyor. Farklılıktan mı yoksa benzerlikten mi bahsediyorsunuz?
RayLuo

@RayLuo Whoops ... Biraz yazım hatası yaptım. Kafanı karıştırdığım için üzgünüm. Mix-in'lerde "is-a" ilişkisi olması GEREKMEZ
Alex

3

"Bir mixin, diğer sınıflar veya mixinler ile bestelenmesi amaçlandığı için bir sınıfın parçasıdır." -DDJ

Bir mixin, bağımsız kullanım için tasarlanmamış bir sınıf veya kod parçasıdır, bunun yerine onu başka bir sınıfın içinde kullanmanız gerekir. Ya bir üye alan / değişken ya da bir kod segmenti olarak oluşturmak. En çok sonraya maruz kaldım. Standart kodu kopyalayıp yapıştırmaktan biraz daha iyidir.

İşte konuyu tanıtan harika bir DDJ makalesi.

Half-Life 2 / "Source" SDK, C ++ karışımlarının harika bir örneğidir. Bu ortamda makrolar, sınıfa belirli bir "lezzet" veya özellik vermek için eklenebilen büyükçe kod bloklarını tanımlar.

Kaynak wiki örneğine bakın: Mantıksal Varlık Yazma . Örnek kodda, DECLARE_CLASS makrosu bir karışım olarak kabul edilebilir. Kaynak SDK, veri erişim kodunu standartlaştırmak ve davranışları varlıklara atfetmek için kapsamlı bir şekilde mixins kullanır.


0

Çoklu kalıtımla, yeni sınıf birden fazla üst sınıftan oluşabilir. Yalnızca herhangi bir üst sınıfta tanımlanan yöntemleri çağırabilirsiniz.

Öte yandan, mixin, çeşitli üst sınıfların davranışını özelleştirmek için kullanılabilen soyut bir alt sınıftır. Mixins, sayHello(): Stringböyle bir yöntemi tanımlamasalar bile (örneğin ) bir yöntemi çağırabilir .

mixin M {
    name: String
    defmethod greetings() { print sayHello() + " " + name}
}

Gördüğünüz sayHello()gibi, hiçbir yerde tanımlanmamış olsa bile arayabilirsiniz . Eğer mixin eklerseniz Msınıfına C, Csağlamalıdır sayHello()yöntemi.


1
ilk
ifadenizin

0

Bence mixin , kalıtım anlamına gelmez . Wikipedia'ya göre bir Mixin :

Nesneye yönelik programlama dillerinde, bir mixin, diğer sınıfların ana sınıfı olmak zorunda kalmadan diğer sınıflar tarafından kullanılacak yöntemleri içeren bir sınıftır. Bu diğer sınıfların mixin'in yöntemlerine nasıl erişeceği dile bağlıdır. Mixinler bazen "miras alınan" değil "dahil edilen" olarak tanımlanır.

Spesifik olarak, perl gibi bir dilde, mixins Exporter modülü kullanılarak eklenebilir:

package Mixins;

use Exporter qw(import);
our @EXPORT_OK = qw(pity);

# assumes it will be mixed-in to a class with a _who_do_i_pity method
sub pity {
    my ($self) = @_;
    printf("I pity %s\n", $self->_who_do_i_pity('da foo'));
}

Bir seferde bir veya daha fazla yöntem (ler) içeren herhangi bir modüle karıştırılabilen:

package MrT

use Mixins qw(pity);

sub new {
    return bless({}, shift);
}

sub _who_do_i_pity {
    return 'da foo!'
}

Daha sonra MrTmodülünüzde şu şekilde kullanılabilir:

use MrT;

MrT->new()->pity();

Bunun saçma bir örnek olduğunu biliyorum ama asıl noktayı anlıyor ...


0

tl; dr

mixin ve çoklu kalıtım aynı biçime sahiptir. Ancak farklı anlamlara sahip olun: mixin, işlev uygulamasını sağlayan temel sınıflara sahiptir. Kalıtım için, temel sınıflar arabirim sağlar ve alt sınıf, uygulamaya sahiptir.

Ama yine de kompozisyon mixin IMO'ya tercih edilir

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.