chciałbym osiągnąć to w C#C# wielokrotne dziedziczenie
(Pseudokod)
class A;
class B : A;
class C : A, B;
...
A ac = (A)c;
...
B bc = (B)c;
Czy to możliwe?
chciałbym osiągnąć to w C#C# wielokrotne dziedziczenie
(Pseudokod)
class A;
class B : A;
class C : A, B;
...
A ac = (A)c;
...
B bc = (B)c;
Czy to możliwe?
Nie. C# nie obsługuje dziedziczenia wielu klas.
Klasa może dziedziczyć z jednej klasy i może również implementować wiele interfejsów.
@stakx: dobry połów. Poprawione. –
można używać interfejsów do dziedziczenia wielokrotnego.
Nie jest to możliwe w języku C#, ale powinieneś także pomyśleć, czy jest to naprawdę potrzebny scenariusz.
CzyC naprawdę i B? Lub ma , który można dołączyć do komputera użytkownika. Jeśli ta ostatnia jest prawdziwa, powinieneś użyć kompozycji zamiast dziedziczenia.
Nie mogę użyć kompozycji z pewnych powodów. Próbowałem tego. Problem: klasy bazowe używają delegatów i udostępniają odwołania do siebie w wywołaniu zwrotnym. Jeśli C zawiera A i B, wywołania zwrotne zawierają odniesienia do A i/lub B, a nie do C, jeśli jest to wymagane. Jest to zapewnione, jeśli odziedziczę C z A i B. Interfejsy są opcją, użyj go już. – neil
Nie trzeba wielokrotne dziedziczenie w tym konkretnym przypadku: Jeżeli klasa C
dziedziczy tylko z B
, każda instancja klasy C
mogą być oddane zarówno B
iA
; od B
już wywodzi A
, C
nie musi pochodzić z A
ponownie:
class A { ... }
class B : A { ... }
class C : B { ... }
...
C c = new C();
B bc = (B)c; // <-- will work just fine without multiple inheritance
A ac = (A)c; // <-- ditto
(Jak inni już powiedziałem, jeśli trzeba coś w rodzaju wielokrotne dziedziczenie, interfejsy użyciu, ponieważ klasa może implementować tyle ile chcesz.)
Arggh ... Nadzorowałem oczywistość. Dzięki za podpowiedź! Pozdrawiam – neil
Hmmm. Pozostaje jeden problem: nie potrafię zmusić C, by zachowywał się tak, jak A. B wzmacnia A i nie zapewnia już prostych funkcji (w razie potrzeby). Mówiąc po prostu potrzebuję C, który czasami zachowuje się jak A, a czasami jako B, w zależności od kontekstu. – neil
'C' powinno zachowywać się jak' A', jeśli uzyskasz do niego dostęp poprzez 'ac'; podobnie, 'C' powinno zachowywać się jak' B', jeśli masz do niego dostęp przez 'bc'. Oczywiście, jeśli masz metody wirtualne, nadpisane wersje będą wywoływane we wszystkich tych przypadkach. – stakx
C# nie obsługuje dziedziczenia wielokrotnego, ale inni sugerują, że możesz używać wielu interfejsów. Jednak nawet w przypadku interfejsów czasami konieczne jest ponowne wykorzystanie implementacji wielu interfejsów w tej samej klasie, co ponownie wymagałoby wielokrotnego dziedziczenia.
Aby obejść ten problem (mimo że jest to prawie never needed), wymyśliłem symulowane podejście wielokrotnego dziedziczenia przy użyciu kombinacji partial classes i T4 Text Templates. To drobny hack, ale jest lepszy niż kopiowanie/wklejanie tej samej implementacji interfejsu w wielu klasach pochodnych. Poniżej przedstawiono uproszczony przykład:
IInterface.cs
public interface IInterface
{
void Foo();
}
InterfaceImpl.cs
public partial class InterfaceImpl : IInterface
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
BaseClass.cs
using System;
public class BaseClass
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
DerivedClassA.cs
public partial class DerivedClassA : BaseClass, IInterface
{
public void FooBar()
{
this.Foo();
this.Bar();
}
}
DerivedClassAInterfaceImpl.tt
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassA"); #>
<#= codeText #>
DerivedClassB.cs
public partial class DerivedClassB : BaseClass, IInterface
{
public void BarFoo()
{
this.Bar();
this.Foo();
}
}
DerivedClassBInterfaceImpl.tt
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassB"); #>
<#= codeText #>
To trochę irytujące, że wymaga to tworzenia pliku tt dla każdej klasy pochodnej, która chce wykorzystać wdrożenie interfejsu , ale nadal zapisuje kod kopiowania/wklejania, jeśli InterfaceImpl.cs to więcej niż kilka linii kodu. Możliwe jest również utworzenie tylko jednego pliku tt i podanie nazwy wszystkich pochodnych klas częściowych oraz wygenerowanie multiple files.
Wymieniłem to podejście w podobnym pytaniu here.
Nie, sprawdź te: http://stackoverflow.com/questions/191691/ http://stackoverflow.com/questions/995255/ –
http://stackoverflow.com/questions/2846752/am-i -wybieranie-do-wdrożenia-wiele-dziedziczenie-jak-można-zrobić-to i http://stackoverflow.com/questions/2456154/does-c-support-multiple-initance – Russell