Наследование перегруженных методов в Java и C отличается каким фундаментальным образом?

#java #c #overloading

#java #c #перегрузка

Вопрос:

Я готовлюсь к выпускному экзамену по курсу сравнительных языков, и профессор устроил нам старый экзамен, чтобы мы почувствовали, что это такое на самом деле. Один вопрос, который я не понимаю, заключается в следующем:

«Наследование перегруженных методов в Java и C отличается фундаментальным образом. Наглядно покажите разницу в двух используемых подходах и аргументируйте, почему дизайнерское решение Java предпочтительнее.»

Единственная идея, которая у меня есть по этому вопросу, — это память, которая у меня есть о перегрузке оператора Java и о том, что вы не можете этого сделать, но в C вы можете.

Комментарии:

1. Я бы сказал, что любой вопрос, который предполагает , что «дизайнерское решение Java предпочтительнее», является академически мошенническим и этически отталкивающим. (Отвечая на вопрос, я думаю, что это связано с virtual функциями.)

2. @KerrekSB Здесь написано «аргументировать» — означает ли это, что люди, пишущие заметки для дискуссионного клуба, академически мошенничают и этически отталкивают? 😉 Однако, если серьезно, многие профессора любят проводить более одного теста, так что заставляет вас думать, что половине класса не пришлось спорить с точностью до наоборот? Я, конечно, мог бы легко найти достаточно точек зрения для обеих сторон спора..

3. @Voo: Здесь написано «аргументировать почему», а не «аргументировать ли». Я думаю, что это довольно большая разница! 🙂 Было бы здорово, если бы действительно существовало два лагеря, но почему-то я серьезно сомневаюсь, что какой-либо современный класс CS будет запускаться таким образом 🙁

4. @KerrekSB Ну, если бы там было сказано «ли», то здесь не было бы много представителей двух разных лагерей — это так же, как в дискуссионном клубе: вы занимаете позицию и должны ее защищать — определенно соответствует моей конфликтной натуре 😉 Очевидно, что prof может быть всем, что вы сказали, и даже больше, но в dubio pro reo 😉 Как анекдот, у меня однажды был экзамен на компилятор, где одна половина класса должна была аргументировать в пользу LALR, а другая половина — в пользу синтаксических анализаторов LR.

5. @Voo: А, я понимаю. Вы действительно хотите , чтобы кто-то защищал заданную позицию. Да, я думаю, это могло бы быть весело. Я должен надеяться, что вопрос проясняет это, хотя и не предполагает, что эта позиция на самом деле правильная.

Ответ №1:

Я бы попросил лектора привести пример иерархии наследования, который демонстрирует «наследование перегруженных методов». Я бы предположил, что в C это означает что-то вроде следующего:

 struct A1 { };
struct A2 { };

struct B1 {
    virtual void f(A1*) = 0;
};

struct B2 {
    virtual void f(A2*) = 0;
};

struct D : B1, B2 { };

void f(Damp; d)
{
    A1 a1;
    A2 a2;
    d.f(amp;a1);
    d.f(amp;a2);
}
  

И следующее в Java (моя Java немного грубовата, поэтому я надеюсь, что я понял это примерно правильно):

 class M {
    class A1 { };
    class A2 { };

    interface B1 {
        void f(A1 a1);
    };
    interface B2 {
        void f(A2 a2);
    };

    abstract class D implements B1, B2 {
    }; 

    void f(D d)
    {
        A1 a1 = new A1();
        A2 a2 = new A2();
        d.f(a1);
        d.f(a2);
    }
};
  

Обратите внимание, что разница здесь в том, что код C не будет компилироваться, потому что f() неоднозначен. Тогда как код Java будет компилироваться. Если это то, о чем они говорят, вы могли бы возразить, что Java делает то, чего ожидает программист, тогда как C , вероятно, удивит программиста. Одна важная вещь, которую я узнал в университете, заключается в том, что прохождение курсов по программированию в университете иногда означает ответы на вопросы так, как от вас ожидает эксперт, в первую очередь и правильно во вторую.

Комментарии:

1. 1: Согласен, что в университете дать ожидаемый ответ важнее, чем пытаться быть правильным. 😉

Ответ №2:

кажется, что в большинстве ответов здесь говорится о наследовании и «Переопределении» метода в C / Java.

Однако ключевое слово в вопросе заставляет меня думать, что на самом деле он спрашивает о другом: «Наследование перегруженных методов»

Есть одно фундаментальное отличие, если я правильно помню, о наследовании перегрузке метода:

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

Однако в Java все в порядке.

Если это действительно то, о чем спрашивается, то, честно говоря, способ Java предпочтительнее, потому что перегрузка метода не должна мешать наследованию и переопределению метода. И такое затенение вызывает многие проблемы проектирования, например, вы не сможете получить доступ к методу родительского класса напрямую в сценарии «перегрузка наследование затенение».

Ответ №3:

Наследование перегруженных методов в Java и C отличается фундаментальным образом.

  1. В Java, когда базовый class метод переопределяется производным class , они оба связаны полиморфным образом по умолчанию. В C вы должны создать base метод как virtual
  2. В Java вы можете остановить переопределение метода, создав его final . В текущем C это недоступно

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

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

C поддерживает многопарадигмальную терминологию и плату за использование, что обеспечивает гибкость, а также делает его языком, ориентированным на экспертов.

Комментарии:

1. Я бы сказал, что «текущим» c является c 11, поскольку стандарт сейчас доработан и final доступен в c 11.

2. @bames53, согласен. У меня вошло в привычку ссылаться на C 03 как на текущий. Необходимо это изменить.

3. -1. Не имеет значения. Вопрос о перегрузке, а не переопределении.

4. @EJP, OP ошибочно использовал термин «перегрузка». «Перегрузка унаследованного метода» — это, по сути, только «переопределение».

5. @iammilind Это не так. Смотрите ответ Боуи Оуэнса.