C #: Soyut sınıfların arayüzleri uygulaması mı gerekiyor?


131

C #'daki test kodum:

namespace DSnA
{
    public abstract class Test : IComparable
    {

    }
}

Aşağıdaki derleyici hatasıyla sonuçlanır:

error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)'

Sınıf yana Testbir olan soyut sınıf , neden derleyici arabirimini uygulamak üzere bu gerektiriyor? Bu gereklilik sadece somut dersler için zorunlu olmamalı mı ?


Haha. Bir şey yazdım ve değiştirmeye karar verdim. Afedersiniz. :)
Joel

2
Kabul edilen yanıtla ilgili olumsuz oylara ve yorumlara dayanarak, olumsuz oyların sorunun ifade edilme biçiminden kaynaklandığına inanıyorum. OP, stackoverflow kapsamının dışında olan "neden bu şekilde" diye sorar. Bununla kendim karşılaştıktan sonra, soru daha çok "Bir şeyi mi kaçırıyorum? Gerçekten uygulamaları sağlamam gerekiyor mu? Bu, soyut bir sınıf olma noktasını bozmaz mı?" Cevabı "Hayır, (soyut bir sınıfın amacına aykırı olan) uygulamalar sağlamak zorunda değilsiniz , ancak durumunuzun işe yaraması için yapmanız gereken şey burada."
ToolmakerSteve

Bir uygulama sağlamanız gereken bir vaka buldum. Arayüzün isteğe bağlı bir parametresi olduğu yerdir. Yöntemi temel sınıfa soyut olarak eklerseniz, miras alınan sınıflar isteğe bağlı parametre olmadan derlenmez (bu, isteğe bağlı bir parametrenin amacını geçersiz kılar). Bu durumda sadece NotImplementedException atıyorum.
Paul McCarthy

Önceki yorumumu görmezden gelin - beklendiği gibi çalışmadı, en az sürpriz ilkesi burada geçerli değil.
Paul McCarthy

Yanıtlar:


141

C # 'da, bir arabirim uygulayan bir sınıf , bu arabirimin tüm üyelerini tanımlamak için gereklidir . Soyut bir sınıf olması durumunda, bu üyeleri abstractanahtar kelimeyle tanımlamanız yeterlidir :

interface IFoo
{
    void Bar();
}

abstract class Foo : IFoo
{
    public abstract void Bar();
}

Ya da başka bir deyişle için: Eğer yok zorunda "uygulamak" (soyut sınıflar üzerinde korkunç bir sınırlama olurdu) onu; ancak, C # ' da derleyiciye kasıtlı olarak parayı somut alt sınıflara geçirdiğinizi söylemeniz gerekir - ve yukarıdaki kod satırı bunun nasıl yapılacağını gösterir.

Bunun sorunun cevabı olmadığından şikayet eden yorumlar ve olumsuz oylar asıl noktayı kaçırıyor. Stack Overflow'a gelen, bu derleyici hatasını alan, ancak bir uygulama sağlamanın hata olacağı soyut bir sınıfa sahip olan biri, iyi bir çözüm olmadan takılır - çalışma zamanı istisnalarını atan uygulama yöntemleri yazmak zorunda kalır, korkunç bir çalışma -around - yukarıdaki bilgilere sahip olana kadar. C # 'ın bu açıklığı gerektirmesinin iyi ya da kötü olması, Stack Overflow kapsamının dışındadır ve ne soru ne de bu yanıtla ilgili değildir.


2
@Ben Yorumunuzu az önce gördüm. Muhtemelen zaten anlamışsınızdır, ancak başka birinin buna ihtiyacı olması durumunda. Açık Arayüz Uygulamalarına göz atın: msdn.microsoft.com/en-us/library/ms173157.aspx
Joel

2
@Joel @Ben Açık arayüzlerin soyut sınıflarla çalışabileceğini düşünmüyorum. Yukarıdaki örnek kodda, tanımını olarak Foodeğiştirin public abstract void IFoo.Bar();ve "genel" ve "soyut" un geçerli değiştiriciler olmadığına dair şikayetler alırsınız.
Darren Cook

8
Bu, soyut bir sınıf olduğu ve derleyicinin boşluğu nasıl dolduracağını bilmesi gerektiği düşünüldüğünde, bunun neden gerekli olduğu sorusuna cevap vermez. Java'da bu gerekli değildir, bu da ioc konteynerlerindeki dekoratör modeli gibi birkaç kullanışlı modele izin verir, örneğin Spring / JavaEE (yönetilen bir arayüzün belirli bir yöntemini dekore etmeniz gerektiğinde). İn.net'teki aynı uygulama, geliştiricileri özellikle nhibernate's ISession
Sheepy

1
AspectJ'nin karışımları başka bir örnektir. Birçok soyut sınıftan kısmi uygulamaları tek bir arayüzde karıştırmanıza izin verir. Her soyut sınıfın yalnızca uygulamak istediği yöntemi uygulaması gerekir. Aynı işlevselliği
.net'te

1
@Sheepy - Doğru, ama IMHO, soruyu soranın neye ihtiyacı olduğunu ve bunun nasıl bir "cevap" olduğunu yanlış anlıyorsunuz . Ben de aynı soruyu sormuştum - çünkü bir uygulama sağlamanın gerekli olması mantıklı gelmiyordu, bu yüzden sıkışmıştım. Cevap şudur: Onu " uygulamak " zorunda değilsiniz - ama derleyiciye onu uygulamayacağınızı söylemek için yapmanız gerekenler burada . (Bunun cevabı olmadığını [doğru şekilde] söylediğiniz soru, uygun bir yığın aşımı sorusu olmayacaktır - amaç dışı olduğu için kapatılmış olabilir.)
ToolmakerSteve

10

Java'dan farklı olarak, C # 'da: "soyut bir sınıf, sınıfın temel sınıf listesinde listelenen arabirimlerin tüm üyelerinin uygulamalarını sağlamalıdır. Ancak, arabirim yöntemlerini soyut yöntemlerle eşlemek için soyut bir sınıfa izin verilir."

https://msdn.microsoft.com/en-us/library/Aa664595(v=VS.71).aspx


1
Süper net cevap ve her iki durumu da sağlamanız harika, çünkü bazen davranışı temel sınıfa uygulamak isteyebilirsiniz
VinKel

Burada ortaya çıkan sorulardan biri şudur: Bu C # ortak şablon bildirimlerinin (açıkçası bunlar) neden soyut sınıflarda var olması gerekir, aksi takdirde kısa ve öz olabilir (böylece sınıfları karıştırabilir)? C # projemde çok sayıda soyut sınıfım ve arabirimim var ve çoğu zaman yaptığım şey, Visual Studio'da yöntem bildirimlerini kopyalayıp yapıştırmak.
forsberg

5

Arayüzü gerçekten uygulamak zorunda değiller .
Arayüz yöntemleri / özellikleri soyut veya hatta sanal olabilir. Bu yüzden onları gerçekten uygulamak alt sınıflara bağlıdır.

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.