Java veya C #'da Çoklu Devralmaya neden izin verilmiyor?


115

Java ve C # 'da çoklu kalıtıma izin verilmediğini biliyorum. Pek çok kitap, çoklu mirasa izin verilmediğini söylüyor. Ancak arayüzler kullanılarak uygulanabilir. Neden izin verilmediğine dair hiçbir şey tartışılmaz. Biri bana tam olarak neden izin verilmediğini söyleyebilir mi?


1
Sadece orada işaret etmek gibi olan orada hangi C # sınıflarında davranışa MI benzeri izin çerçeveler. Ve tabii ki, devletsiz karışımlara sahip olma seçeneğiniz de var (uzantı yöntemlerini kullanma) - devletsiz olmalarına rağmen pek kullanışlı değiller.
Dmitri Nesteruk

1
Arayüzlerin kalıtımla ilgisi olduğu, dil sözdizimi tarafından yaratılan bir yanılsamadır. Mirasın sizi daha zengin yapması gerekiyor. Bir arayüz için böyle bir şey yoktur, çömelmeyi miras almazsınız ve bu sizi önemli ölçüde daha fakir yapar. Harry amcanın kumar borcunu miras aldınız, arayüzü uygulamak için daha çok işiniz var.
Hans Passant

Yanıtlar:


143

Kısa cevap: çünkü dil tasarımcıları bunu yapmamaya karar verdi.

Temel olarak, hem .NET hem de Java tasarımcılarının çoklu kalıtıma izin vermediği görülüyordu çünkü MI eklemenin çok az fayda sağlarken dillere çok fazla karmaşıklık eklediğini düşünüyorlardı. .

Daha eğlenceli ve derinlemesine bir okuma için, web'de bazı dil tasarımcılarının röportajlarını içeren bazı makaleler var. Örneğin, .NET için Chris Brumme (CLR'de MS'de çalışan) neden yapmamaya karar verdiklerini açıkladı:

  1. Farklı dillerin aslında MI'nın nasıl çalıştığına dair farklı beklentileri vardır. Örneğin, çatışmaların nasıl çözüldüğü ve yinelenen tabanların birleştirilip birleştirilmediği veya gereksiz olup olmadığı. MI'yı CLR'de uygulamadan önce, tüm diller üzerinde bir araştırma yapmalı, ortak kavramları bulmalı ve bunları dilden bağımsız bir şekilde nasıl ifade edeceğimize karar vermeliyiz. Ayrıca MI'nin CLS'ye ait olup olmadığına ve bunun bu kavramı istemeyen diller için ne anlama geldiğine de karar vermemiz gerekir (örneğin VB.NET). Elbette, ortak bir dil çalışma zamanı olarak içinde bulunduğumuz iş bu, ancak bunu henüz MI için yapmadık.

  2. MI'nın gerçekten uygun olduğu yerlerin sayısı aslında oldukça azdır. Çoğu durumda, çoklu arayüz devralma işi yerine getirebilir. Diğer durumlarda, kapsülleme ve yetkilendirmeyi kullanabilirsiniz. Mixins gibi biraz farklı bir yapı ekleseydik, bu gerçekten daha güçlü olur muydu?

  3. Çoklu uygulama mirası, uygulamaya çok fazla karmaşıklık katar. Bu karmaşıklık, döküm, yerleşim, dağıtım, alan erişimi, serileştirme, kimlik karşılaştırmaları, doğrulanabilirlik, yansıma, jenerikler ve muhtemelen birçok başka yeri etkiler.

Yazının tamamını buradan okuyabilirsiniz.

Java için şu makaleyi okuyabilirsiniz :

Java dilinden çoklu kalıtımın atlanmasının nedenleri çoğunlukla "basit, nesne yönelimli ve tanıdık" hedeften kaynaklanmaktadır. Basit bir dil olarak Java'nın yaratıcıları, çoğu geliştiricinin kapsamlı eğitim almadan anlayabileceği bir dil istiyordu. Bu amaçla, C ++ 'ın gereksiz karmaşıklığını (basit) taşımadan dili olabildiğince C ++' ya (tanıdık) benzer hale getirmek için çalıştılar.

Tasarımcıların görüşüne göre çoklu miras, çözdüğünden daha fazla soruna ve kafa karışıklığına neden olur. Böylece, dilden çoklu mirası keserler (tıpkı operatörün aşırı yüklenmesini önledikleri gibi). Tasarımcıların kapsamlı C ++ deneyimi, onlara çoklu kalıtımın baş ağrısına değmeyeceğini öğretti.


10
Güzel karşılaştırma. Bence her iki platformun altında yatan düşünce süreçlerinin oldukça göstergesi.
CurtainDog

97

Çoklu uygulama mirasına izin verilmeyen şeydir.

Sorun, derleyicinin / çalışma zamanının, her ikisi de draw () yöntemi için uygulamalarla bir Cowboy ve Artist sınıfınız varsa ne yapacağını anlayamaması ve ardından yeni bir CowboyArtist türü oluşturmaya çalışmanızdır. Draw () yöntemini çağırdığınızda ne olur? Sokakta ölü yatan biri mi var, yoksa çok güzel bir suluboyanız var mı?

Sanırım buna çift elmas kalıtım sorunu deniyor.


80
Sokakta ölen birinin güzel bir suluboyasını alıyorsunuz :-)
Dan F

Tek sorun bu mu? Sanırım, C ++ 'nın bu sorunu sanal anahtar kelimeyle çözdüğünden emin değilim, bu doğru mu? C ++ 'da iyi değilim
Abdülsattar Muhammed

2
C ++ 'da türetilmiş temel sınıf işlevlerinden hangisinin çağrılacağını belirtebilir veya bunu kendiniz yeniden uygulayabilirsiniz.
Dmitry Risenberg

1
Modern tasarım, en basit durumlar dışında hepsinde kompozisyonu mirasa tercih etme eğilimindedir. Çoklu miras asla basit bir durum olarak sayılmazdı. Kompozisyonla, bunun gibi elmas problemleri olduğunda sınıfınızın ne yapacağı üzerinde tam kontrole sahip olursunuz ...
Bill Michell

Sadece bir öncelik listesine ihtiyacınız var. Bu, Common Lisp'in nesne sistemi CLOS'ta kullanılır. Tüm sınıflar bir mirasçı oluşturur ve çağrılan yöntem buradan belirlenir. Ayrıca CLOS, bir CowboyArtist.draw () 'ın önce bir Kovboy ve sonra bir Sanatçı çizebilmesi için farklı kurallar tanımlamanıza olanak tanır. Ya da ne uydurursan.
Sebastian Krog

19

Sebep: Java, basitliği nedeniyle çok popüler ve kodlaması kolaydır.

Bu yüzden, java geliştiricileri, programcılar için anlaşılması zor ve karmaşık hissettiği şeyleri, bundan kaçınmaya çalıştılar. Bu tür bir özellik, çoklu kalıtımdır.

  1. İşaretçilerden kaçındılar
  2. Çoklu mirastan kaçındılar.

Çoklu kalıtım sorunu : Elmas sorunu.

Örnek :

  1. A sınıfının fun () bir metodu olduğunu varsayın. B sınıfı ve C sınıfı, A sınıfından türemiştir.
  2. Ve hem B hem de C sınıfları fun () yöntemini geçersiz kılar.
  3. Şimdi D sınıfının hem B hem de C sınıfını miras aldığını varsayalım (sadece Varsayım)
  4. D sınıfı için nesne oluşturun.
  5. D d = yeni D ();
  6. ve d.fun () 'a erişmeyi deneyin; => B sınıfının eğlencesi () mi yoksa C sınıfının eğlencesi () mi diyecek?

Elmas probleminde var olan belirsizlik budur.

Bu problemi çözmek imkansız değil, ancak okurken programcıya daha fazla kafa karışıklığı ve karmaşıklık yaratıyor. Çözmeye çalıştığından daha fazla soruna neden olur.

Not : Ancak, herhangi bir şekilde, arabirimleri kullanarak her zaman dolaylı olarak çoklu mirası uygulayabilirsiniz.


1
"Ancak, arabirimleri kullanarak her zaman dolaylı olarak birden çok kalıtımı uygulayabilirsiniz." - bu, programcının yöntemlerin gövdesini her seferinde, tekrar ve tekrar yeniden belirlemesini gerektirir.
Kari

13

Çünkü Java'nın C ++ 'dan çok farklı bir tasarım felsefesi var. (Burada C # konusunu tartışmayacağım.)

Stroustrup, C ++ 'yı tasarlarken, nasıl kötüye kullanılabileceklerine bakılmaksızın yararlı özellikler eklemek istedi. Çoklu miras, operatör aşırı yükleme, şablonlar ve diğer çeşitli özelliklerle büyük bir işi mahvetmek mümkündür, ancak bunlarla çok iyi şeyler yapmak da mümkündür.

Java tasarım felsefesi, dil yapılarında güvenliği vurgulamaktır. Sonuç, yapılması çok daha garip şeyler olduğu, ancak baktığınız kodun düşündüğünüz şeyi ifade ettiğinden çok daha emin olabilirsiniz.

Dahası, Java büyük ölçüde en iyi bilinen OO dilleri olan C ++ ve Smalltalk'tan gelen bir tepkiydi. MI'yı daha iyi idare eden farklı OO sistemleri ile birçok başka OO dili vardır (Common Lisp aslında standartlaştırılan ilk dildi).

Arayüzler, kompozisyon ve yetkilendirme kullanarak Java'da MI yapmanın tamamen mümkün olduğundan bahsetmiyorum bile. C ++ 'dan daha belirgindir ve bu nedenle kullanımı daha beceriksizdir, ancak size ilk bakışta anlamanız daha muhtemel bir şey verecektir.

Burada doğru cevap yok. Farklı cevaplar vardır ve belirli bir durum için hangisinin daha iyi olduğu uygulamalara ve bireysel tercihlere bağlıdır.


12

İnsanların MI'dan uzaklaşmasının ana (hiçbir şekilde tek olmasa da) nedeni, uygulamanızda belirsizliğe yol açan sözde "elmas problemi" dir. Bu wikipedia makalesi bunu tartışıyor ve elimden gelenden daha iyi açıklıyor. MI ayrıca daha karmaşık bir koda yol açabilir ve birçok OO tasarımcısı MI'ya ihtiyacınız olmadığını iddia eder ve kullanırsanız modeliniz muhtemelen yanlıştır. Bu son noktaya katılıyorum emin değilim, ancak işleri basit tutmak her zaman iyi bir plandır.


8

C ++ 'da çoklu kalıtım, yanlış kullanıldığında büyük bir baş ağrısıydı. Bu popüler tasarım sorunlarından kaçınmak için modern dillerde (java, C #) bunun yerine çoklu arayüzler "miras" zorlandı.


8

Çoklu Kalıtım:

  • anlaşılması zor
  • hata ayıklaması zor (örneğin, aynı şekilde adlandırılmış yöntemlere sahip birden çok çerçeveden sınıfları karıştırırsanız, oldukça beklenmedik sinerjiler oluşabilir)
  • yanlış kullanımı kolay
  • gerçekten o kadar kullanışlı değil
  • özellikle doğru ve verimli bir şekilde yapılmasını istiyorsanız uygulaması zordur

Bu nedenle, Java diline Çoklu Kalıtımı dahil etmemek akıllıca bir seçim olarak düşünülebilir .


3
Common Lisp Nesne Sistemi ile çalıştığım için yukarıdakilerin tümüne katılmıyorum.
David Thornley

2
Dinamik diller sayılmaz ;-) Herhangi bir Lisp benzeri sistemde, hata ayıklamayı oldukça kolaylaştıran bir REPL'e sahipsiniz. Ayrıca, CLOS (anladığım kadarıyla, onu hiç kullanmadım, sadece okudum) çok fazla esnekliğe ve kendi tavrına sahip bir meta nesne sistemidir. Ancak, C ++ gibi statik olarak derlenmiş bir dili düşünün; burada derleyici, birden çok (muhtemelen çakışan) vtables kullanarak son derece karmaşık bir yöntem araması oluşturur: böyle bir uygulamada, bir yöntemin hangi uygulamasının çağrıldığını bulmak çok da önemsiz olmayan bir görev olabilir.
mfx

5

Diğer bir neden de, tek kalıtımın dökümü önemsiz hale getirmesidir, montajcı talimatları yaymaz (gerektiğinde türlerin uyumluluğunu kontrol etmekten başka). Çoklu mirasınız varsa, çocuk sınıfında belirli bir ebeveynin nerede başladığını bulmanız gerekir. Dolayısıyla performans kesinlikle bir avantajdır (tek olmasa da).


4

Bilgisayar Biliminin daha çok Bilim ve daha az seri üretim olduğu eski günlerde (70'ler), programcıların iyi tasarım ve iyi uygulama hakkında düşünmek için zamanları vardı ve sonuç olarak ürünler (programlar) yüksek kaliteye sahipti (ör. TCP / IP tasarımı Ve uygulama ). Günümüzde, herkes programlama yaparken ve yöneticiler son teslim tarihlerinden önce özellikleri değiştirirken, Steve Haigh gönderisindeki wikipedia bağlantısında açıklananlar gibi ince konuları izlemek zordur; bu nedenle, "çoklu miras" derleyici tasarımı ile sınırlıdır. Beğendiyseniz, yine de C ++ 'ı kullanabilirsiniz .... ve istediğiniz tüm özgürlüğe sahip olabilirsiniz :)


4
... kendini ayağından defalarca vurma özgürlüğü dahil;)
Mario Ortegón

4

Bir tutam tuzla "Java'da çoklu kalıtıma izin verilmez" ifadesini alıyorum.

Bir "Tip" birden fazla "Tip" ten miras aldığında Çoklu Kalıtım tanımlanır. Ve arayüzler de davranışa sahip oldukları için türler olarak sınıflandırılır. Yani Java'nın birden çok mirası var. Sadece daha güvenli.


6
Ancak bir arayüzden miras almazsınız, onu uygularsınız. Arayüzler sınıf değildir.
Blorgbeard

2
Evet, ancak kalıtım, bazı ön kitaplar dışında hiçbir zaman bu kadar dar tanımlanmadı. Ve bunun gramerinin ötesine bakmamız gerektiğini düşünüyorum. İkisi de aynı şeyi yapıyor ve arayüzler sadece bu nedenle "icat edildi".
Rig Veda

Closeable arayüzünü alın: bir yöntem, close (). Bunu, Açılabilir'e genişletmek istediğinizi varsayalım: isOpen boole alanını true olarak ayarlayan bir open () yöntemi vardır. Zaten açık olan bir Açılabilir'i açmaya çalışmak, açık olmayan bir Açılabilir'i kapatmaya çalışmak gibi bir İstisna atar ... Sınıfların yüzlerce daha ilginç şeceresi, her birini genişletmeyi seçmek zorunda kalmadan bu tür bir işlevselliği benimsemek isteyebilir. sınıf Açılabilir zaman. Açılabilir sadece bir arayüz olsaydı, bu işlevselliği sağlayamazdı. QED: arayüzler kalıtım sağlamaz!
mike rodent

4

Sınıfların dinamik olarak yüklenmesi, çoklu mirasın uygulanmasını zorlaştırır.

Java'da aslında tekli kalıtım ve arayüz kullanarak çoklu kalıtımın karmaşıklığından kaçındılar. Çoklu kalıtımın karmaşıklığı, aşağıda açıklandığı gibi bir durumda çok yüksektir

çoklu kalıtımın elmas problemi. A'dan miras alan iki B ve C sınıfımız var. B ve C'nin miras alınan bir yöntemi geçersiz kıldığını ve kendi uygulamalarını sağladıklarını varsayın. Şimdi D, çoklu kalıtım yaparak hem B hem de C'den miras alır. D geçersiz kılınan yöntemi miras almalı, jvm hangi geçersiz kılınan yöntemin kullanılacağına karar veremiyor mu?

C ++ 'da sanal işlevler işlemek için kullanılır ve bunu açıkça yapmamız gerekir.

Bu arabirimler kullanılarak önlenebilir, hiçbir yöntem gövdesi yoktur. Arayüzler somutlaştırılamaz - sadece sınıflar tarafından uygulanabilir veya diğer arayüzler tarafından genişletilebilirler.


3

Gerçekte çoklu kalıtım, miras alınan sınıfların aynı işleve sahip olması durumunda bir karmaşıklık ortaya çıkaracaktır. yani derleyicinin seçmesi gereken bir kafa karışıklığı olacaktır (elmas problemi). Yani Java'da bu karmaşıklık kaldırıldı ve çoklu kalıtımın verdiği gibi işlevselliği elde etmek için arayüz verdi. Arayüzü kullanabiliriz


2

Java'nın kavramı, yani polimorfizmi vardır. Java'da 2 tür polimorfizm vardır. Yöntem aşırı yükleme ve yöntemi geçersiz kılma vardır. Bunlar arasında, yöntemi geçersiz kılma, üst ve alt sınıf ilişkisi ile olur. Bir alt sınıfın bir nesnesini oluşturuyor ve üst sınıf yöntemini çağırıyorsak ve alt sınıf birden fazla sınıfı genişletiyorsa, hangi süper sınıf yöntemi çağrılmalıdır?

Veya, super()süper sınıf kurucusunu çağırırken , hangi süper sınıf kurucusu çağrılacak?

Bu kararlar, mevcut java API özellikleri nedeniyle imkansızdır. bu nedenle java'da çoklu kalıtıma izin verilmez.


Temel olarak, Java'nın tür sistemi, her nesne örneğinin bir türü olduğunu varsayar, bir nesneyi bir üst türe çevirmek her zaman işe yarar ve referansı koruyacaktır ve bir alt türe bir referans atamak, örnek bu alt türden veya bir alt türe aitse referansı koruyacaktır. alt türü. Bu tür varsayımlar faydalıdır ve genelleştirilmiş çoklu kalıtıma onlarla tutarlı bir şekilde izin vermenin mümkün olduğunu sanmıyorum.
supercat

1

Java'da Çoklu Devralmaya doğrudan izin verilmez, ancak arayüzler aracılığıyla buna izin verilir.

Nedeni:

Çoklu Kalıtım: Daha fazla karmaşıklık ve belirsizlik getirir.

Arayüzler: Arayüzler, programınızın yapısını veya iç işleyişini genel kullanıma açık arayüzünden düzgün bir şekilde tanımlamanız için tek tip bir yol sağlayan tamamen soyut Java sınıflarıdır; bunun sonucunda daha fazla esneklik ve yeniden kullanılabilir kod ve daha fazla kontrol elde edilir. diğer sınıfları nasıl oluşturduğunuz ve onlarla nasıl etkileşim kurduğunuz üzerine.

Daha doğrusu, bunlar bir tür çoklu kalıtım, yani birden fazla sınıfa yükseltilebilen sınıflar gerçekleştirmenize izin veren ek özellikleriyle Java'da özel bir yapıdır.

Basit bir örnek verelim.

  1. Aynı yöntem adlarına ancak farklı işlevlere sahip 2 üst sınıf sınıf A ve B olduğunu varsayalım. (Extends) anahtar kelimesi ile aşağıdaki kod sayesinde çoklu kalıtım mümkün değildir.

       public class A                               
         {
           void display()
             {
               System.out.println("Hello 'A' ");
             }
         }
    
       public class B                               
          {
            void display()
              {
                System.out.println("Hello 'B' ");
              }
          }
    
      public class C extends A, B    // which is not possible in java
        {
          public static void main(String args[])
            {
              C object = new C();
              object.display();  // Here there is confusion,which display() to call, method from A class or B class
            }
        }
  2. Ancak arayüzler aracılığıyla, anahtar kelime (uygular) ile çoklu kalıtım mümkündür.

    interface A
        {
           // display()
        }
    
    
     interface B
        {
          //display()
        }
    
     class C implements A,B
        {
           //main()
           C object = new C();
           (A)object.display();     // call A's display
    
           (B)object.display(); //call B's display
        }
    }

0

Biri bana tam olarak neden izin verilmediğini söyleyebilir mi?

Cevabı bu dokümantasyon bağlantısından bulabilirsiniz

Java programlama dilinin birden fazla sınıfı genişletmenize izin vermemesinin bir nedeni, alanları birden çok sınıftan devralma yeteneği olan çoklu durum mirası sorunlarından kaçınmaktır.

Birden fazla kalıtıma izin veriliyorsa ve bu sınıfı başlatarak bir nesne oluşturduğunuzda, bu nesne sınıfın tüm süper sınıflarından alanları devralacaktır. İki soruna neden olacak.

  1. Ya farklı süper sınıflardan yöntemler veya yapıcılar aynı alanı başlatırsa?

  2. Hangi yöntem veya kurucu öncelikli olacak?

Artık birden fazla devlet mirasına izin veriliyor olsa da, yine de

Çoklu miras türü : Bir sınıfın birden fazla arabirimi uygulama yeteneği.

Çoklu uygulama mirası ( arabirimlerdeki varsayılan yöntemler aracılığıyla): Birden çok sınıftan yöntem tanımlarını devralma yeteneği

Ek bilgi için bu ilgili SE sorusuna bakın:

Arayüzlü Çoklu Kalıtım Belirsizliği


0

C ++ 'da bir sınıf, birden fazla sınıftan (doğrudan veya dolaylı olarak) miras alabilir, bu da çoklu miras olarak adlandırılır. .

Bununla birlikte, C # ve Java, sınıfları her sınıfın tek bir ana sınıftan miras aldığı tek mirasla sınırlar .

Çoklu miras, iki farklı sınıf hiyerarşisinin yönlerini birleştiren sınıflar oluşturmanın yararlı bir yoludur; bu, genellikle tek bir uygulamada farklı sınıf çerçeveleri kullanıldığında meydana gelen bir şeydir.

Örneğin, iki çerçeve istisnalar için kendi temel sınıflarını tanımlıyorsa, her iki çerçeveyle de kullanılabilen istisna sınıfları oluşturmak için çoklu miras kullanabilirsiniz.

Çoklu kalıtımla ilgili sorun, belirsizliğe yol açabilmesidir. Klasik örnek, bir sınıfın, her biri aynı sınıftan miras alan diğer iki sınıftan miras almasıdır:

class A {
    protected:
    bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
    public:
    void setFlag( bool nflag ){
        flag = nflag; // ambiguous
    }
};

Bu örnekte, flagveri üyesi tarafından tanımlanmıştır class A. Ama class Dgelen alçalır class B ve class Chem türetmek,A bu yüzden özünde, iki kopya ait flagiki örneğini çünkü mevcut Aolan Dbireyin sınıf hiyerarşisi. Hangisini ayarlamak istiyorsun? Derleyici referans şikayet edecektir flagin Dolduğu belirsiz . Bir düzeltme, referansı açıkça belirsizleştirmektir:

B::flag = nflag;

Diğer bir düzeltme de B ve C'yi olarak bildirmektir virtual base classes; bu, hiyerarşide herhangi bir belirsizliği ortadan kaldırarak yalnızca bir A kopyasının var olabileceği anlamına gelir.

Türetilmiş bir nesne oluşturulduğunda temel sınıfların başlatılma sırası veya üyelerin türetilmiş sınıflardan yanlışlıkla gizlenebilme şekli gibi çoklu mirasla ilgili diğer karmaşıklıklar mevcuttur. Bu karmaşıklıklardan kaçınmak için, bazı diller kendilerini daha basit tekli kalıtım modeliyle sınırlar.

Bu, kalıtımı önemli ölçüde basitleştirse de, aynı zamanda yararlılığını da sınırlar çünkü yalnızca ortak bir ataya sahip sınıflar davranışları paylaşabilir. Arabirimler, farklı hiyerarşilerdeki sınıfların ortak arabirimleri kod paylaşarak uygulanmasalar bile ortaya çıkarmasına izin vererek bu kısıtlamayı bir ölçüde azaltır.


-1

Şu Örneği düşünün: Bir sınıfım var Shape1

It has CalcualteAreayöntemi:

Class Shape1
{

 public void CalculateArea()

     {
       //
     }
}

Shape2Aynı yönteme sahip başka bir sınıf daha var

Class Shape2
{

 public void CalculateArea()

     {

     }
}

Artık Circle alt sınıfım var, hem Shape1 hem de Shape2'den türetiliyor;

public class Circle: Shape1, Shape2
{
}

Şimdi Circle için nesne oluşturduğumda ve yöntemi çağırdığımda, sistem hangi hesaplama alanı yönteminin çağrılacağını bilmiyor. Her ikisinin de imzaları aynı. Böylece derleyicinin kafası karışacaktır. Bu yüzden birden fazla mirasa izin verilmez.

Ancak, arabirimlerin yöntem tanımları olmadığı için birden çok arabirim olabilir. Her iki arabirim de aynı yönteme sahip olsa bile, ikisinin de herhangi bir uygulaması yoktur ve her zaman alt sınıfta yöntem çalıştırılacaktır.


dil tasarımcısı, Arayüzde olduğu gibi açık yöntem çağrısı verebilir. Böyle bir nokta yok! Diğer bir neden de, soyut yöntemlerle soyut sınıflara ne dersiniz?
Nomi Ali
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.