Вы не упомянули, какой язык вы используете, но поскольку концепция почти одинакова для всех языков ООП, на данный момент я буду использовать C #.
Единственный способ сделать этонеявное преобразование, подобное тому, которое вы указали в вашем примере, это если Invoice является подклассом TempInvoice, например, так:
public class Invoice : TemplInvoice { }
Однако вы можете выполнить явное преобразование, если обратное верно (т.е. TempInvoice является производным от Invoice), но только если метод getInvoice
действительно создает объект TempInvoice или объект, производный от TempInvoice.В противном случае вы получите InvalidCastException
при попытке выполнить явное преобразование.Имейте в виду, что только платформы, такие как Java или Microsoft.NET, будут вызывать приятное, чистое исключение для вас.Вещи могут стать намного более неприятными из языков, таких как C или C ++, поскольку они позволят вам выполнять такие вещи, как слепое приведение без особых предупреждений (static_cast и dynamic_cast не смогут скомпилироваться), что часто приводит к получению либо мусорных данных (в лучшем случае)или нарушение доступа (наихудший случай) в случайных точках кода ниже.
Если вам абсолютно необходимо иметь два объекта, вероятно, лучше всего либо извлечь один из другого, либо разбитьиз общих методов в отдельный базовый класс, который оба могут наследовать.Тем не менее, вы никогда не должны слепо понижать значение возврата из вызова функции.Если у вас есть случай, когда вы знаете, что функция всегда будет возвращать один и тот же тип, вы должны использовать этот тип напрямую и, во всяком случае, избегать принижения.Это безопаснее и эффективнее для сгенерированного кода.Если вы используете фабричный шаблон, вы можете встроить некоторую форму RTTI в базовый интерфейс, чтобы вы не делали (в основном) слепое бросание.Хорошим примером этого (немного сложнее) является метод QueryInterface для COM-объектов, но вы можете сделать что-то такое же простое, как добавление свойства Invoice.Type.