У меня основная проблема с приведением унаследованных типов к базовому классу. Я знаю, что это обычно невозможно, т. Е. Вы можете привести производный класс к его базовому классу, но обратное неверно. Вот пример фрагмента, с которым я борюсь:
Допустим, я определил абстрактный класс для представления PCI-карты компьютера:
public abstract class PciDevice
{
public abstract int GetDeviceId();
public abstract String GetVendorName();
}
и теперь я создаю 3 типа унаследованных классов (устройств):
public class GraphicsCard : PciDevice
{
public override int GetDeviceId() { return 1666; }
public override String GetVendorName() { return "CoolCorp"; }
int trianglesPerSecond;
ChipsetTypeEnum chipsetType;
}
public class AudioCard : PciDevice
{
public override int GetDeviceId() { return 1999; }
public override String GetVendorName() { return "ShinyCorp"; }
int numChannels;
int samplingRate;
}
public class Modem : PciDevice
{
public override int GetDeviceId() { return 1234; }
public override String GetVendorName() { return "BoringCorp"; }
public int baudRate;
bool faxEnabled;
}
Теперь я определяю «слот» внутри компьютера:
public class PciCardSlot
{
private int slotId;
private int clockFreq;
private PciDevice cardInSlot;
public PciDevice getCard() { return cardInSlot; }
public void setCard(PciDevice card) { cardInSlot = card; }
}
и у меня есть массив слотов для представления всех слотов на компьютере:
PciCardSlot [] pciSlotsInComputer = new PciCardSlot[6];
Затем я определяю функцию для извлечения объекта PciDevice, учитывая идентификатор слота:
public PciDevice getInsertedCard(int slotId)
{
return pciSlotsInComputer[slotId].getCard();
}
пока все хорошо. Теперь где-то в коде я создаю экземпляры объектов AudioCard, GraphicsCard и Modem и назначаю их слотам.
AudioCard a = new AudioCard();
Modem b = new Modem();
GraphicsCard c = new GraphicsCard();
PciCardSlot s0 = new PciCardSlot(); s0.setCard(a);
PciCardSlot s1 = new PciCardSlot(); s1.setCard(b);
PciCardSlot s2 = new PciCardSlot(); s2.setCard(c);
pciSlotsInComputer[0] = s0; pciSlotsInComputer[1] = s1; pciSlotsInComputer[2] = s2;
Тогда у меня есть функция, которая выглядит следующим образом, которая предназначена для работы с объектом Модем:
public setBaudRateForModem(int slotId, int rate)
{
((Modem)getInsertedCard(slotId)).baudRate = rate; // Can not cast!!!
}
...
// I know that slot 1 contains a modem, so I do:
setBaudRateForModem(1, 9600);
Приведенное выше приведение не работает, так как я пытаюсь привести объект PciDevice к объекту Modem, производному от PciDevice.
Я читал об этом, и почти везде я смотрю, люди, кажется, думают, что если вам нужно привести базовый класс к классу-члену, у вас плохой дизайн. Моя иерархия классов плохо спроектирована? Какие-либо предложения? Спасибо за чтение.