#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 отличается фундаментальным образом.
- В Java, когда базовый
class
метод переопределяется производнымclass
, они оба связаны полиморфным образом по умолчанию. В C вы должны создатьbase
метод какvirtual
- В Java вы можете остановить переопределение метода, создав его
final
. В текущем C это недоступно
аргументируйте, почему дизайнерское решение Java предпочтительнее.
Это спорно. Java применяет единый способ проектирования, который помогает программистам лучше / быстрее понимать код. Также уменьшает путаницу и использование языковых возможностей.
C поддерживает многопарадигмальную терминологию и плату за использование, что обеспечивает гибкость, а также делает его языком, ориентированным на экспертов.
Комментарии:
1. Я бы сказал, что «текущим» c является c 11, поскольку стандарт сейчас доработан и
final
доступен в c 11.2. @bames53, согласен. У меня вошло в привычку ссылаться на C 03 как на текущий. Необходимо это изменить.
3. -1. Не имеет значения. Вопрос о перегрузке, а не переопределении.
4. @EJP, OP ошибочно использовал термин «перегрузка». «Перегрузка унаследованного метода» — это, по сути, только «переопределение».
5. @iammilind Это не так. Смотрите ответ Боуи Оуэнса.