2009-04-25 3 views
4

Что делать, если у меня есть класс, который и расширяет абстрактный класс и реализует интерфейс, например:класса и расширяет абстрактный класс и реализует интерфейс

class Example : AbstractExample, ExampleInterface 
{ 
    // class content here 
} 

Как я могу инициализировать этот класс, так что я могу получить доступ к методы как интерфейса, так и абстрактного класса?

Когда я делаю:

AbstractExample example = new Example(); 

Я не могу получить доступ к методам из интерфейса.

ответ

5

Последний пример привяжет вас к твердому экземпляру либо интерфейс или абстрактный класс, который я предполагаю это не ваша goal.The плохая новость заключается в том, вы не в динамично типизированный язык, поэтому ваш застрял либо имея ссылку на твердом теле «Пример» объектов, как ранее sprcified или литье/uncasting т.е.

AbstractExample example = new Example(); 
((IExampleInterface)example).DoSomeMethodDefinedInInterface(); 

ваши другие alternitives должны иметь как AbstractExample и IExampleInterface реализовать общий интерфейс, вы бы указали то, что

abstract class AbstractExample : ICommonInterface 
interface IExampleInterface : ICommonInterface 
class Example : AbstractExample, IExampleInterface 

Теперь вы можете работать с ICommonInterface и иметь функциональность как абстрактного класса, так и реализации вашего интерфейса IExample.

Если ни один из этих ответов не является приемлемым, вы можете захотеть взглянуть на некоторые языки DLR, которые выполняются в рамках платформы .NET, то есть IronPython.

+0

Спасибо, что оба ваших ответа очень полезны;) Я немного смущен C#, потому что я родом из PHP/Zend, и это довольно разные языки. –

+0

Да, я думаю, что многие люди тоже пришли с этого фона (включая меня). Вы можете делать вещи со статическими языками, которые невозможны с динамическим и наоборот. Самое лучшее, что нужно сделать, это понять разницу и увидеть, где линия может быть слегка размыта. .NET 3.5 представил некоторые замечательные функции, которые делают язык «динамичным», решение Kent Boogaart - это хорошее начало, возможно, получить функции, которые вы ищете, без многословия дополнительных интерфейсов. – Owen

+2

Сокращенный. C# не является динамически типизированным языком. Также вы не даете простейший ответ, например Example example = new Example(); –

1

Использование:

Example example = new Example(); 

Обновленный после получения дополнительной информации:

Если вы уверены он реализует ExampleInterface, вы можете использовать

AbstractClass example = new Example(); 
ExampleInterface exampleInterface = (ExampleInterface)example; 
exampleInterface.InterfaceMethod(); 

Вы можете также убедиться, что это действительно инвентарь путем проверки интерфейса с помощью

if (example is ExampleInterface) { 
    // Cast to ExampleInterface like above and call its methods. 
} 

Я не верю, что Generics помогут вам, поскольку они разрешают время компиляции, и если у вас есть только ссылка на AbstractClass, то компилятор будет жаловаться.

Редактировать: Более или менее то, что сказал Оуэн. :)

+0

Спасибо. Но что, если я не знаю ссылки на класс, я знаю только, какой абстрактный класс он расширяет и какой интерфейс он реализует? Richard –

10

Вы должны

  • реализуют интерфейс в AbstractExample
  • или получить ссылку на примере

Example example = new Example();

5

Если вы знаете только абстрактный класс, можно предположить, что вы знаете фактический тип через экземпляр Type. Таким образом, вы могли бы использовать дженерики:

private T SomeMethod<T>() 
    where T : new(), AbstractExample, ExampleInterface 
{ 
    T instance = new T(); 
    instance.SomeMethodOnAbstractClass(); 
    instance.SomeMethodOnInterface(); 
    return instance; 
} 
+0

Действительно, как этот ответ, и теперь у вас есть мой ум, который мчатся о том, как принять это решение дальше. – Owen

1

Я думаю, что этот пример поможет вам:

public interface ICrud 
{ 
    void Add(); 
    void Update(); 
    void Delete(); 
    void Select(); 
} 

public abstract class CrudBase 
{ 
    public void Add() 
    { 
     Console.WriteLine("Performing add operation..."); 
     Console.ReadLine(); 
    } 

    public void Update() 
    { 
     Console.WriteLine("Performing update operation..."); 
     Console.ReadLine(); 
    } 
    public void Delete() 
    { 
     Console.WriteLine("Performing delete operation..."); 
     Console.ReadLine(); 
    } 
    public void Select() 
    { 
     Console.WriteLine("Performing select operation..."); 
     Console.ReadLine(); 
    } 
} 

public class ProcessData : CrudBase, ICrud 
{ 

} 

var process = new ProcessData(); 
process.Add(); 
+0

Откуда взялось 'ProcessData()'? Об этом не упоминается за пределами инстанцирования. – McArthey

+0

@McArthey, я отредактировал свой ответ только для вас. Создайте класс реализации и сначала наследуйте базовый класс, а затем интерфейс ICrud. – Toffee

+0

Благодарим вас за то, что нашли время, чтобы уточнить. Очень хорошо. – McArthey

Смежные вопросы