LINUX.ORG.RU

Java + Object.clone


0

0

Вот такой вопрос:

Как я понимаю даже в java следующее делать нельзя

class A{
  public object getValue(){ ... }
}

class B extends A{
  public B getValue() { ... }
} 

из-за одинаковых сигнатур...

почему же следующее нормально собирается?

class B implements Clonable{
  public B clone(){
  return (B)base.clone();
 }
}
★★★★★

А ты попробуй это "нельзя" скомпилировать

execve
()

Ну начнем с того что public B clone() в декларации слегка незаконно.

public Object clone() - это да.

Во-вторы - у базового класса есть метод clone(), и то что ты его результат явно привел к классу B - это твои эротическии фантазии которые ты решил воплотить в жизнь :-)

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi

Ну мои фантазии - это понятно :). Хотя в данном контексте результат будет тот который ожидается. Если никто метод не перекроет.

То что незаконно - тоже понятно.

Но изначально вопрос-то был в другом.

eXOR ★★★★★
() автор топика
Ответ на: комментарий от eXOR

Дело в том, что в C++ на подобные извраты мне бы компилятор объяснил, что я не прав. Да и в C# тоже сказал бы пару ласковых. Чего же явно корявую конструкцию javac 1.6.0 скушал без единого warning?

или в мире жава кода - такие вещи легитимны?

eXOR ★★★★★
() автор топика
Ответ на: комментарий от eXOR

> явно корявую конструкцию

Что сдесь такого корявого? Функция getValue в классе A возвращает Object, его же она возвращает и в классе B (или ты будешь утверждать, что B не Object?). Ни к каким противоречиям такие определения не приводят. Аналогично для clone.

zwon
()
Ответ на: комментарий от zwon

То есть ты хочешь сказать что:

setValue(A a);

и

setValue(B b);

будут иметь одинаковые сигнатуры.

eXOR ★★★★★
() автор топика
Ответ на: комментарий от eXOR

Не надо делать ложные выводы. Я говорю, что A.getValue() и B.getValue() имеют одинаковые сигнатуры.

Кстати, мой компилятор C++ (это gcc 4.1.2) проглотил подобную конструкцию без вопросов ;)

zwon
()
Ответ на: комментарий от zwon

Сигнатуры одинаковые. А перегрузка метода для той же самой сигнатуры - это кривизна. Если такие вещи позволять то будет маразм типа:

char getValue();
int getValue();
MyObj getValue();
Object getValue();

Не понял как у тебя это собралось. 

=========================

$ cat z.cpp
class A{
public:
        virtual void z(){
                ;
        }
};

class B : public A{
        virtual int z(){
                ;
        }
};

int main(int argc, char ** argv){
        B b;
        return 0;
}

$ g++ z.cpp
z.cpp:9: ошибка: conflicting return type specified for ‘virtual int B::z()’
z.cpp:3: ошибка:   overriding ‘virtual void A::z()’

$ g++ --version
g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)
Copyright (C) 2006 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая
коммерческую ценность и применимость для каких-либо целей.

============================

eXOR ★★★★★
() автор топика
Ответ на: комментарий от eXOR

во-первых не путай overload и override. 

Во-вторых перечитай внимательнее своё первое сообщение и сравни с тем,
что ты пишешь сейчас. Заметь, что B является потомком Object, а int 
потомком void не является, потому компилятор и выдаёт ошибку.

Если не понятно, то тут 
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.3
разжёвано, что к чему на примере с clone.

Вот это компилируется без проблем:

class A {
    virtual A* clone() {
    	return new A();
    };
};

class B:public A {
    virtual B* clone() {
        return new B();
    }
};

int main() {
    return 0;
}

zwon
()
Ответ на: комментарий от zwon

для труЪ: If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type substitutable for d2, or a compile-time error occurs.

zwon
()
Ответ на: комментарий от eXOR

Дык ;)

ЗЫ: дорвался сегодня да до-диеза -- там действительно не работает. Я вот думаю, как они клон реализуют?

zwon
()
Ответ на: комментарий от zwon

в C# клон можно сделать без магических методов object'а например через reflection :).

eXOR ★★★★★
() автор топика

>Как я понимаю даже в java следующее делать нельзя


Почему нельзя ? Если типы приводятся то можно.

Нормально скомпилируется.
javac -version -> 1.5.0_10

public class Test {

  public static class A {
    public A getResult() {
      return this;
    }
  }

  public static class B extends A {
    public B getResult() {
      return this;
    }

    protected B clone() throws CloneNotSupportedException {
      return (B)super.clone();
    }
  }

  public static void main(String[] args) {
    System.out.println("" + new B().getResult());
  }
}

javac src/Test.java
java Test
Test$B@923e30

vtVitus ★★★★★
()

А вот в 1.4.2 ещё было нельзя :).

found   : Test.B
required: Test.A
    public B getResult() {
             ^
src/Test.java:19: clone() in Test.B cannot override clone() in java.lang.Object; attempting to use incompatible return type
found   : Test.B
required: java.lang.Object
    protected B clone() throws CloneNotSupportedException {
                ^

vtVitus ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.