полиморфизм и интерфейсы - PullRequest
4 голосов
/ 17 мая 2010

если у меня есть два класса x и y, оба расширяют класс w.и x реализующий интерфейс z.если у меня есть методы doSomething (w object) и doSomething (x object), что произойдет, если я вызову doSomething (x)?

edit: я реализую это на Java, более конкретно на Android.Я спрашиваю об этом, потому что некоторые классы, которые реализуют определенный интерфейс, в основном делают то же самое, когда вызывается doSomething ().но есть особые случаи, которые я хотел бы выделить.

Ответы [ 4 ]

2 голосов
/ 17 мая 2010

Это зависит от языка, который вы используете.

Например, в C # он будет использовать doSomething (объект x), а не doSomething (объект w).

Однако, если вы приведете его к w, он будет использовать doSomething (w object) следующим образом:

doSomething((w) someObjectOfX);

или

doSomething(someObjectOfX as w);
1 голос
/ 17 мая 2010

В C # компилятор выберет правильный метод в зависимости от объявленного типа переменной, а не от фактического типа, хранящегося в ней.

Обратите внимание, код ниже объявляет W как класс и создает его экземпляр. Если вы сделаете W интерфейсом и удалите его объявление и конструкцию, вы получите то же поведение для x и y, что и в приведенной ниже программе, интерфейс или класс для W в этом случае не имеет значения.

Позвольте мне показать вам разницу:

using System;

namespace SO2851194
{
    class W { }
    class X : W { }
    class Y : W { }

    class Program
    {
        static void Main()
        {
            W w = new W();
            X x = new X();
            Y y = new Y();

            doSomething(w);
            doSomething(x);
            doSomething(y);
        }

        static void doSomething(W w)
        {
            Console.Out.WriteLine("w");
        }

        static void doSomething(X x)
        {
            Console.Out.WriteLine("x");
        }
    }
}

Здесь я объявляю три переменные типа W, X и Y и вызываю doSomething, передавая три переменные, одну за другой. Выход этой программы:

w
x
w

Как и ожидалось, компилятор выберет метод с наиболее подходящим типом параметра, а в случае переменной x он имеет метод, который может принимать объект типа X.

Тем не менее, из-за наследования классов, мы можем изменить объявление переменных, но оставить типы объектов построенными, поэтому изменив код следующим образом:

W w = new W();
W x = new X();   // Notice, changed variable type to W
W y = new Y();   // but keep constructing X and Y

Теперь выводится:

w
w
w

Таким образом, тот факт, что переменная x содержала объект типа X, не учитывал его, компилятор выбрал метод из типа переменной, а не из ее содержимого.

В C # 4.0 теперь у вас есть тип dynamic, поэтому снова измените код на:

dynamic w = new W();
dynamic x = new X();
dynamic y = new Y();

снова выводит:

w
x
w

, так как теперь компилятор откладывает выбор любого метода вообще до времени выполнения, а во время выполнения он видит, что переменная с именем x на самом деле содержит объект типа X, а затем выбирает метод с наилучшим типом параметра.

1 голос
/ 17 мая 2010

Допустим, у вас есть

w object1 = new x();
x object2 = new x();

Передача объекта1 выполнит doSomething(w object) и передачу объекта2 doSomething(x object).

P.S .: Конечно, в зависимости от языка (говорили о C #)

P.P.S: добавлены имена параметров, чтобы сделать его более понятным

0 голосов
/ 17 мая 2010

у вас не может быть двух разных методов с одинаковыми сигнатурами. Его неоднозначный код, компиляторы не будут компилироваться, а интерпретаторы выдадут ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...