it-swarm.asia

Özel / iç sınıfı ne zaman kullanmalısınız?

Açıklığa kavuşturmak için, sorduğum şey

public class A{
    private/*or public*/ B b;
}

vs.

public class A{
    private/*or public*/ class B{
        ....
    }
}

Birini veya diğerini kullanmanın bazı nedenlerini kesinlikle düşünebilirim, ama gerçekten görmek istediğim şey, artı ve eksilerin sadece akademik olmadığını gösteren inandırıcı örnekler.

21
EpsilonVector

Genellikle bir sınıf, dış arabiriminin bir parçası olmaktan ziyade başka bir sınıfın bir iç uygulama ayrıntısı olduğunda kullanılır. Bunları çoğunlukla, iç veri yapılarını c-tarzı yapılar için ayrı bir sözdizimi olmayan dillerde daha temiz hale getiren sadece veri sınıfları olarak gördüm. Ayrıca bazen olay işleyicileri veya çalışan iş parçacıkları gibi yüksek düzeyde özelleştirilmiş, tek yöntemden türetilmiş nesneler için de yararlıdırlar.

20
Karl Bielefeldt

Bir ağaç, liste, grafik vb. Oluşturduğunuzu varsayalım. Bir düğümün veya hücrenin iç ayrıntılarını neden dış dünyaya göstermelisiniz?

Bir grafik veya liste kullanan herkes, onun uygulamasına değil, yalnızca arayüzüne güvenmelidir, çünkü ileride bir gün (örneğin, dizi tabanlı bir uygulamadan işaretçi tabanlı bir uygulamaya) değiştirmek isteyebilirsiniz. veri yapısı (her biri) kodunu yeni uygulamaya uygun hale getirmek için değiştirmelidir.

Bunun yerine, özel bir iç sınıfta bir düğümün veya hücrenin uygulanmasını kapsüllemek, istemcilerin veri yapınızın arabirimi kaldığı sürece sonuç olarak kodlarını ayarlamak zorunda kalmadan, uygulamayı istediğiniz zaman değiştirme özgürlüğü verir. bakir.

Veri yapınızın uygulamasının ayrıntılarını gizlemek de güvenlik avantajlarına yol açar, çünkü sınıfınızı dağıtmak istiyorsanız yalnızca derlenmiş uygulama dosyasıyla birlikte arabirim dosyasını hazırlayacaksınız ve kimse gerçekten dizileri mi yoksa işaretçileri mi kullandığınızı bilemeyecek böylece uygulamanızı bir tür sömürüden veya en azından kodunuzu yanlış kullanmanın veya denetlemenin imkansızlığından dolayı koruyun. Pratik konulara ek olarak, bu gibi durumlarda son derece zarif bir çözüm olduğu gerçeğini küçümsemeyin.

9
Nicola Lamonaca

Kanımca, belirli bir göreve izin vermek için bir sınıfta kısaca kullanılan sınıflar için dahili olarak tanımlanmış sınıfları kullanmak adil bir polistir.

Örneğin, ilgisiz iki sınıftan oluşan bir veri listesini bağlamanız gerekirse:

public class UiLayer
{
    public BindLists(List<A> as, List<B> bs)
    {
        var list = as.ZipWith(bs, (x, y) => new LayerListItem { AnA = x, AB = y});
        // do stuff with your new list.
    }

    private class LayerListItem
    {
        public A AnA;
        public B AB;
    }
}

Dahili sınıfınız başka bir sınıf tarafından kullanılıyorsa, ayrı bir sınıf koymalısınız. Dahili sınıfınız herhangi bir mantık içeriyorsa, onu ayırmanız gerekir.

Temel olarak, veri nesnelerinize delik takmak için harika olduklarını düşünüyorum, ancak gerçekten mantık içermeleri gerekiyorsa bakımı zordur, çünkü değiştirmeniz gerektiğinde onları nerede arayacağınızı bilmeniz gerekir.

5
Ed James
  • Bazı dillerdeki iç sınıflar (örneğin Java), içerdiği sınıftaki bir nesneye bağlanır ve üyelerini nitelendirmeden kullanabilir. Mevcut olduğunda, diğer dil olanaklarını kullanarak onları yeniden uygulamaktan daha açıktır.

  • Başka bir dilde iç içe sınıfların (örneğin C++) böyle bir bağı yoktur. Sadece sınıf tarafından sağlanan kapsam belirleme ve erişilebilirlik denetimini kullanıyorsunuz.

4
AProgrammer

Java içinde iç sınıflar kaçının çünkü hot-swapping iç sınıfların varlığında çalışmaz. Bu nefret ediyorum çünkü bu tür düşünceler için kodu tehlikeye atmaktan nefret ediyorum, ancak bu Tomcat yeniden başlıyor yukarı.

3
kevin cline

Özel statik iç sınıfın kullanımlarından biri de Memo kalıbıdır. Hatırlanması gereken tüm verileri özel sınıfa koyar ve bazı işlevlerden Object olarak döndürürsünüz. Dışarıdaki hiç kimse (yansıma, serileştirme, hafıza denetimi olmadan) içine bakamaz/değiştiremez, ancak sınıfınıza geri verebilir ve durumunu geri yükleyebilir.

2
user470365

Özel bir iç sınıf kullanmanın bir nedeni, kullandığınız bir API'nin belirli bir sınıftan kalıtım gerektirmesi olabilir, ancak bu sınıfın bilgisini dış sınıfınızın kullanıcılarına vermek istemeyebilirsiniz. Örneğin:

// async_op.h -- someone else's api.
struct callback
{
    virtual ~callback(){}
    virtual void fire() = 0;
};

void do_my_async_op(callback *p);



// caller.cpp -- my api
class caller
{
private :
    struct caller_inner : callback
    {
        caller_inner(caller &self) : self_(self) {}
        void fire() { self_.do_callback(); }
        caller &self_;
    };

    void do_callback()
    {
        // Real callback
    }

    caller_inner inner_;

public :
    caller() : inner_(*this) {}

    void do_op()
    {
        do_my_async_op(&inner_);
    }
};

Burada, do_my_async_op, kendisine geri çağrı türünde bir nesnenin geçirilmesini gerektirir. Bu geri aramanın API'nın kullandığı public üye işlev imzası var.

Outer_class öğesinden do_op () çağrıldığında, kendisine bir işaretçi yerine gerekli geri arama sınıfından miras alan özel iç sınıf örneğini kullanır. Dış sınıf, geri çağrıyı dış sınıfın private do_callback üye işlevine çevirmek için dış sınıfa bir başvuruya sahiptir.

Bunun yararı, hiç kimsenin halka açık "fire ()" üye işlevini çağıramayacağından emin olmanızdır.

2
Kaz Dragon

Derinlikteki C #'daki Jon Skeet'e göre, tam tembel iş parçacığı açısından güvenli bir singleton (bkz. Beşinci Sürüm) (.NET 4'e kadar) için iç içe bir sınıf kullanmak tek yoldu.

2
Scott Whitlock

Özel ve iç sınıflar, kapsülleme düzeylerini artırmak ve uygulama ayrıntılarını gizlemek için kullanılır.

C++ 'da, özel bir sınıfa ek olarak, aynı kavram bir sınıf cpp's anonim ad alanı uygulanarak elde edilebilir. Bu, bir uygulama ayrıntısını gizlemek/özelleştirmek için iyi bir şekilde kullanılır.

Bir iç veya özel sınıfla aynı fikirdir, ancak dosyanın derleme birimi dışında tamamen görünmez olduğu için daha da büyük bir kapsülleme düzeyinde. Üstbilgi dosyasında hiçbir şey görünmüyor veya sınıfın bildiriminde dışarıdan görülemiyor.

1
hiwaylon