2013-07-29 21 views
12

Mam proste pytanie C# (tak wierzę). Jestem początkującym językiem i natknąłem się na problem dotyczący interfejsów i klas, które je implementują. Problemem jestMetoda klasy, która nie jest w interfejsie

mam interfejsu iA

interface iA 
{ 
    bool method1 
    bool method2 
    bool method3 
} 

i 3 klasy, które implementują interfejs: Klasa B, C i D

class B : iA 
{ 
    public bool method1 
    public bool method2 
    public bool method3 
} 

jeśli klasa B miał inną metodę, która nie jest w interfejs, powiedzmy, method4() i mam następujące:

iA element = new B(); 

a następnie chciałbym używać:

element.method4(); 

bym się błąd mówiąc, że nie mają method4() że trwa pierwszy argument typu iA.

Pytanie brzmi: Czy mogę mieć obiekt typu interfejsu i utworzyć instancję z klasą i czy ten obiekt wywołuje metodę z klasy, czyli metodę, której nie ma w interfejsie?

Rozwiązaniem, które wymyśliłem, było użycie klasy abstrakcyjnej między interfejsem a klasami pochodnymi, ale IMO, które wykluczyłoby interfejs poza zasięgiem. W moim projekcie chciałbym użyć tylko interfejsu i klas pochodnych.

+1

'if (element to typeof (B)) ((B) element) .method4();' to powinno pomóc – wudzik

+5

Świeżemu nowemu użytkownikowi zadając jasne i dobrze sformatowane pytanie. To rzadkie, gratulacje i mile widziane. :) – Otiel

+0

Dobre pytanie. +1 Jeśli podasz prawdziwy scenariusz, możemy doradzić w kwestii najlepszego podejścia do projektu. –

Odpowiedz

2

Musisz odrzucić typ interfejsu do typu klasy; Zwykle robimy to za pomocą jak:

B b = element as B; // <- try cast element as B 

    if (!Object.RefernceEquals(null, b)) { // <- element is B or can be legaly interpreted as B 
    b.method4(); 
    } 

Zaletą „jak” jest to, że nie ma tylko jedna operacja obsada, a „jest” i (B) mają zrobić dwa odlewane.

4

Tak, jest to możliwe. Wystarczy rzucić typ interfejsu do typu klasy tak:

iA element = new B(); 
((B)element).method4(); 

Jak sugeruje wudzik, należy sprawdzić, czy elemnt jest właściwego typu:

if(element is B) 
{ 
    ((B)element).method4(); 
} 
+2

Nota boczna: możesz dodać 'if (element to typeof (B))', aby upewnić się, że element jest 'B' – wudzik

+0

Prawdopodobnie jednak nie chcesz tego robić? –

+0

To dobry punkt. Dodam to do mojej odpowiedzi. –

2

bez rzucania można zrobić to.

interface iA 
{ 
    bool method1(); 
    bool method2(); 
    bool method3(); 
} 

interface IFoo : iA 
{ 
    bool method4(); 
} 

class B : IFoo 
{ 
    public bool method1() {} 
    public bool method2() {} 
    public bool method3() {} 
    public bool method4() {} 
} 

IFoo element = new B();  
element.method4(); 

NB: Spróbuj użyć kapitału I prefiks dla C# interfejsy.

+0

Pozwala to uniknąć sprawdzania typu i rzucania, ale teraz masz inny obiekt, IFoo. Jeśli użytkownik ma obiekt iA, nadal musiałby sprawdzić, czy ten obiekt jest IFoo (i rzucić go), aby móc uruchomić metodę4. –

+1

Tak, ale jeśli chodzi o projektowanie, lepiej jest pracować z takimi interfejsami niż z konkretnymi typami. Jest to rozwiązanie, które lepiej się skaluje, ponieważ teraz łatwiej jest rozszerzyć, które typy implementują różne interfejsy. –