Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.03.09 17:01
Оценка:
Объясните, пожалуйста, почему такая декларация интерфейса недопустима:

interface I {
    String getClass();
}


Если можно, то со ссылкой на спецификацию языка.
Re: Члены интерфейсов в Java
От: Blazkowicz Россия  
Дата: 02.03.09 17:11
Оценка:
Здравствуйте, nikov, Вы писали:

N>Объясните, пожалуйста, почему такая декларация интерфейса недопустима:

Вообще-то компилятор довольно популярно объясняет причину.

N>Если можно, то со ссылкой на спецификацию языка.

На что спеку-то? На то что нельзя переопределять final методы? Или на то что нельзя делать перегрузку метода с изменением только return типа?
Re[2]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.03.09 17:16
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>На что спеку-то? На то что нельзя переопределять final методы? Или на то что нельзя делать перегрузку метода с изменением только return типа?


Во-первых, для меня неочевидно, что здесь я пытаюсь переопределять final метод. Например, в C# аналогичный код вполне бы проканал. Поэтому и прошу объяснение из спецификации.
Re[3]: Члены интерфейсов в Java
От: cvetkov  
Дата: 02.03.09 17:42
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, Blazkowicz, Вы писали:


B>>На что спеку-то? На то что нельзя переопределять final методы? Или на то что нельзя делать перегрузку метода с изменением только return типа?


N>Во-первых, для меня неочевидно, что здесь я пытаюсь переопределять final метод. Например, в C# аналогичный код вполне бы проканал. Поэтому и прошу объяснение из спецификации.

Так как в яве все инстанс методы виртуальные, то значит перекрываешь.

для перекрытия нет специального синтаксиса поэтому его не отличить от определения.
а нет его потому что кроме перекрытия ничего сделать нельзя
Re[3]: Члены интерфейсов в Java
От: Blazkowicz Россия  
Дата: 02.03.09 17:44
Оценка: 1 (1)
Здравствуйте, nikov, Вы писали:

N>Во-первых, для меня неочевидно, что здесь я пытаюсь переопределять final метод. Например, в C# аналогичный код вполне бы проканал. Поэтому и прошу объяснение из спецификации.

http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html

All class and array types inherit the methods of class Object, which are summarized here

http://java.sun.com/javase/6/docs/api/java/lang/Object.html#getClass()
8.4.3.3 final Methods

Overloading:
http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html

9.4.2 Overloading
If two methods of an interface (whether both declared in the same interface, or both inherited by an interface, or one declared and one inherited) have the same name but different signatures that are not override-equivalent (§8.4.2), then the method name is said to be overloaded. This fact causes no difficulty and never of itself results in a compile-time error. There is no required relationship between the return types or between the throws clauses of two methods with the same name but different signatures that are not override-equivalent.

То есть return type не определяет сигнатуру метода.


http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#38649

The signature of a method consists of the name of the method and the number and types of formal parameters to the method. A class may not declare two methods with the same signature, or a compile-time error occurs.

Т.о. методы различающиеся лишь возвращаемым типом имеют одинаковую сигнатуру.
Re[3]: Члены интерфейсов в Java
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 02.03.09 17:56
Оценка:
Здравствуйте, nikov, Вы писали:

N>Во-первых, для меня неочевидно, что здесь я пытаюсь переопределять final метод. Например, в C# аналогичный код вполне бы проканал. Поэтому и прошу объяснение из спецификации.


Так оно неочевидно именно из-за того, что джава != c#. Т.е. в джаве невозможно создать non-private неполиморфный инстанс-метод, который можно было бы переопределить в потомке. Опять же в c# нет возможности явно запретить переопределение метода ('final' в сигнатуре метода).

6.4.4 The Members of an Interface Type

...
* If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

http://denis-zhdanov.blogspot.com
Re[3]: Члены интерфейсов в Java
От: Аноним  
Дата: 02.03.09 18:53
Оценка:
Здравствуйте, nikov, Вы писали:

N>Во-первых, для меня неочевидно, что здесь я пытаюсь переопределять final метод. Например, в C# аналогичный код вполне бы проканал. Поэтому и прошу объяснение из спецификации.

flood mode on
это, чтобы дотнетчикам жизнь мёдом не казалась
flood mode off
Re[4]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.03.09 20:03
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>

B>All class and array types inherit the methods of class Object, which are summarized here

Но в данном случае у меня не класс или массив, а интерфейс.

B>Т.о. методы различающиеся лишь возвращаемым типом имеют одинаковую сигнатуру.

Согласен, сигнатуры совпадают. Но почему должна быть ошибка компиляции?
Re[4]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.03.09 20:15
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Т.е. в джаве невозможно создать non-private неполиморфный инстанс-метод, который можно было бы переопределить в потомке.

В C# тоже невозможно создать неполиморфный метод, который можно было бы переопределить в потомке.

DZ>Опять же в c# нет возможности явно запретить переопределение метода ('final' в сигнатуре метода).

Там для этой цели есть модификатор метода sealed.

DZ>

DZ>...
DZ>* If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.


Получается, интерфейс неявно определяет публичный абстрактный метод getClass с такой же сигнатурой и типом возвращаемого значения, как метод getClass в классе Object. А явно определяет метод getClass с другим типом возвращаемого значения. Ошибка-то отчего?
Re[5]: Члены интерфейсов в Java
От: Blazkowicz Россия  
Дата: 02.03.09 20:48
Оценка:
Здравствуйте, nikov, Вы писали:

N>Но в данном случае у меня не класс или массив, а интерфейс.

Любой интерфейс подразумевает что его будет реализовывать какой-либо класс. Любой класс унаследован от Object. Даже если это Proxy!

B>>Т.о. методы различающиеся лишь возвращаемым типом имеют одинаковую сигнатуру.

N>Согласен, сигнатуры совпадают. Но почему должна быть ошибка компиляции?
Сигнатура совпадает, следовательно, это не overload. Значит override, а override не возможен, т.к. переопределяемый метод — final. Лучше расскажи почему ты считаешь что это всё не логично.
Re[5]: Члены интерфейсов в Java
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 02.03.09 21:16
Оценка:
Здравствуйте, nikov, Вы писали:

N>В C# тоже невозможно создать неполиморфный метод, который можно было бы переопределить в потомке.


    using System;
    namespace Polymorphism
    {
        class A
        {
              public void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A
        {
              public void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // output --> "A::Foo()"
                b.Foo();  // output --> "B::Foo()"

                a = new B();
                a.Foo();  // output --> "A::Foo()"
            }
        }
    }



N>Там для этой цели есть модификатор метода sealed.


Он не может быть применен к методу. Но вообще да, я про него забыл.

...
* If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.


N>Получается, интерфейс неявно определяет публичный абстрактный метод getClass с такой же сигнатурой и типом возвращаемого значения, как метод getClass в классе Object. А явно определяет метод getClass с другим типом возвращаемого значения. Ошибка-то отчего?


Из-за того, что в джаве не разрешено иметь перегруженные методы отличающиеся только типом возвращаемого значения.
http://denis-zhdanov.blogspot.com
Re[5]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 02.03.09 22:39
Оценка: -1
Здравствуйте, nikov, Вы писали:

N>Но в данном случае у меня не класс или массив, а интерфейс.

Интерфейсы тоже наследуются от Object.

То есть:
interface Empty
{
};

Empty empty=new Empty() {};
Class clazz=empty.getClass(); //Всё нормально!
Sapienti sat!
Re[6]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 02.03.09 23:02
Оценка: +1
Cyberax wrote:

> Empty empty=new Empty() {};

Это нечестно. Тут неявно определяется анонимный класс, реализующий данный интерфейс. Точнее надо "Empty.class"
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[7]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 02.03.09 23:15
Оценка:
Здравствуйте, ., Вы писали:

>> Empty empty=new Empty() {};

.>Это нечестно. Тут неявно определяется анонимный класс, реализующий данный интерфейс. Точнее надо "Empty.class"
Empty.class — ничего не означает.

Class clazz=int.class;
assert clazz.getDeclaredMethods().length==0; //Всё ОК!
Sapienti sat!
Re[8]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 02.03.09 23:31
Оценка:
Cyberax wrote:

>> > Empty empty=new Empty() {};

> .>Это нечестно. Тут неявно определяется анонимный класс, реализующий
> данный интерфейс. Точнее надо "Empty.class"
> Empty.class — ничего не означает.
Т.е.? Не понял. ".class" — тупо обращение к публичному статическому финальному полю.
public class Test
{
    interface Empty{}
    public static void main(String []args)
    {
        System.out.println(Empty.class);
        System.out.println(new Empty(){}.getClass());
        System.out.println(int.class);
    }
}

работает вполне очевидно.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 02.03.09 23:53
Оценка:
Здравствуйте, ., Вы писали:

.>Т.е.? Не понял. ".class" — тупо обращение к публичному статическому финальному полю.

Нет, .class — это специальная конструкция языка. Она работает и для примитивов, хотя никаких полей у них нет.
Sapienti sat!
Re[6]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:01
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>>>Т.о. методы различающиеся лишь возвращаемым типом имеют одинаковую сигнатуру.

N>>Согласен, сигнатуры совпадают. Но почему должна быть ошибка компиляции?
B>Сигнатура совпадает, следовательно, это не overload. Значит override, а override не возможен, т.к. переопределяемый метод — final. Лучше расскажи почему ты считаешь что это всё не логично.

Я вовсе не считаю, что это нелогично. Просто я в отпуске и решил разобраться со спецификацией языка Java. Вижу, что многие вещи отличаются от C#, но пока не могу найти достаточно понятных объяснений. Был бы признателен, если бы ты не просто объяснил это своими словами, а сказал, где именно это в спецификации написано.

Кроме того, я не могу применить твое объяснение к такой ситуации:

public class A {
    private final void foo() { }
    public class B extends A {
        public void foo() { } // а это что: overload или override?
    }
}
Re[7]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 00:08
Оценка:
Здравствуйте, nikov, Вы писали:

N>Кроме того, я не могу применить твое объяснение к такой ситуации:

N>
N>public class A {
N>    private final void foo() { }
N>    public class B extends A {
N>        public void foo() { } // а это что: overload или override?
N>    }
N>}
N>

Это ни overload, ни override. Приватные просто методы никак не влияют на наследуемые классы.
Sapienti sat!
Re[6]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:13
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

N>>В C# тоже невозможно создать неполиморфный метод, который можно было бы переопределить в потомке.


DZ>
DZ>    using System;
DZ>    namespace Polymorphism
DZ>    {
DZ>        class A
DZ>        {
DZ>              public void Foo() { Console.WriteLine("A::Foo()"); }
DZ>        }

DZ>        class B : A
DZ>        {
DZ>              public void Foo() { Console.WriteLine("B::Foo()"); }
DZ>        }
DZ>


Здесь метод потомка не переопределяет, а скрывает метод базового класса.

N>>Там для этой цели есть модификатор метода sealed.

DZ>Он не может быть применен к методу. Но вообще да, я про него забыл.

Еще как может. Попробуй:

class A {
    public override sealed string ToString() { return "A"; }
}


DZ>

DZ>...
DZ>* If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.


N>>Получается, интерфейс неявно определяет публичный абстрактный метод getClass с такой же сигнатурой и типом возвращаемого значения, как метод getClass в классе Object. А явно определяет метод getClass с другим типом возвращаемого значения. Ошибка-то отчего?


DZ>Из-за того, что в джаве не разрешено иметь перегруженные методы отличающиеся только типом возвращаемого значения.

Я не вижу, где такое написано — "не разрешено". Вижу только, что методы интерфейса называются перегруженными, когда они имеют одинаковые имена, но разные сигнатуры.
Re[6]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:14
Оценка:
Здравствуйте, Cyberax, Вы писали:

N>>Но в данном случае у меня не класс или массив, а интерфейс.

C>Интерфейсы тоже наследуются от Object.

Но это не делает их классами или массивами.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.