Robię program, który używa polimorfizmu, alena liście. Teraz, gdy używam wartości z listy, już określiłem, które są dziećmi i rodzicami za pomocą instrukcji if, ale problem polega na tym, że nie mam dostępu do żadnych atrybutów podrzędnych. Wszelkie sugestie? (Przykładowy kod poniżej)
//In Class one
public List<Parent> parent;
parent.Add(new Child());
//In Class two
if (parent[0] is Child)
{
//treats it as parent
Console.WriteLine(parent[0].name());
}
W powyższym kodzie nazwa atrybutu jest publicznaale w klasie dziecka, więc nie mogę uzyskać dostępu do żadnego z atrybutów dziecka, ponieważ on nie wie, że jest dzieckiem. Czy istnieje sposób, aby uczynić przedmiot dzieckiem? Lista musi korzystać z polimorfizmu, ponieważ istnieje wiele różnych klas potomnych, które muszą znajdować się na jednej liście.
Odpowiedzi:
1 dla odpowiedzi № 1Chciałbym użyć as
słowo kluczowe. Jest to bezpieczna obsada, która zwraca wartość null, gdy rzutowanie nie jest możliwe.
Child child = obj as Child;
if (child!=null)
{
child.childMethod();
}
0 dla odpowiedzi nr 2
W przypadku dziedziczenia i polimorfizmu odwołanie do obiektu nadrzędnego, które wskazuje obiekt podrzędny, może uzyskać dostęp do metod nadrzędnych w środowisku wykonawczym. Jednak można go obsadzić i wywołać metody Child. ((Child) obj).childMethod();
0 dla odpowiedzi № 3
Możesz uzyskać metody potomne poprzez rzutowanie, w ten sposób:
//In Class one
public List<Parent> parent;
parent.Add(new Child());
//In Class two
Child parentAsChild = parent[0] as Child;
if (parentAsChild != null)
{
Console.WriteLine(parentAsChild.name());
}
The as
operator wykonuje rzut obronny, który zwraca wartość null, jeśli parent[0]
nie można rzutować na Child
obiekt.
Bądź jednak ostrożny - omijaszcelu polimorfizmu w ten sposób. Cały punkt polimorfizmu polega na tym, że nie musisz wykonywać sprawdzania typu i rzucania - klasa potomna powinna zastąpić każde zachowanie różniące się od rodzica.
0 dla odpowiedzi nr 4
Albo rzuć obiekt Child
po sprawdzeniu jego typu:
//In Class one
public List<Parent> parent;
parent.Add(new Child());
//In Class two
if (parent[0] is Child)
{
var child = (Child) parent[0];
Console.WriteLine(child.name());
}
lub rzucić obiekt na Child
przed sprawdzeniem jego typu:
//In Class one
public List<Parent> parent;
parent.Add(new Child());
//In Class two
var child = parent[0] as Child;
if (child != null)
{
//treats it as parent
Console.WriteLine(child.name());
}
Tego rodzaju odlewania należy unikać, gdy tylko jest to możliwe. Rozważ skorzystanie z interfejsu do zdefiniowania interfejsu API, który musisz skonsumować lub zdefiniowania wirtualnego elementu na Parent
.