Члены интерфейсов в 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.

Но это не делает их классами или массивами.
Re[7]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 00:15
Оценка: -1
nikov wrote:

> public class A {

> private final void foo() { }
> public class B extends A {
> public void foo() { } // а это что: overload или override?
private член никоим образом не виден за пределами класса. Поэтому B ничего о наличии A.foo не знает, а значит overload.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 00:15
Оценка:
Cyberax wrote:

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

> финальному полю.
> Нет, .class — это специальная конструкция языка. Она работает и для
> примитивов, хотя никаких полей у них нет.
Ну да, возможно она обрабатывается специальным образом компилятором, но с т.з. пользователя языка может пониматься как обычное поле.
Я лишь хотел сказать, что new Empty(){}.getClass() никакого отношения к классу интерфейса не имеет. Хотя бы потому, что "new Empty(){}.getClass().equals(new Empty(){}.getClass())" ложно.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:18
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Это ни overload, ни override.


О, значит бывают ни overload, ни override. Значит, в первом примере нужно еще сначала доказать, что там нет третьего варианта (ни overload, ни override).
Re[8]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:20
Оценка:
Здравствуйте, ., Вы писали:

.>private член никоим образом не виден за пределами класса.


За какими пределами? Класс B внутри класса A, из него даже можно вызвать этот приватный метод.

P.S
Re[11]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 00:23
Оценка:
Здравствуйте, ., Вы писали:

.>Ну да, возможно она обрабатывается специальным образом компилятором, но с т.з. пользователя языка может пониматься как обычное поле.

Да?
int.class = String.class; //Упс...

Для обычных полей такого добиться нельзя.

.>Я лишь хотел сказать, что new Empty(){}.getClass() никакого отношения к классу интерфейса не имеет. Хотя бы потому, что "new Empty(){}.getClass().equals(new Empty(){}.getClass())" ложно.

empty.getClass() — это вызов метода _инстанса_. Т.е. показывает, что любой интерфейс является наследником Object'а.
Sapienti sat!
Re[9]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 00:25
Оценка:
Здравствуйте, nikov, Вы писали:

C>>Это ни overload, ни override.

N>О, значит бывают ни overload, ни override. Значит, в первом примере нужно еще сначала доказать, что там нет третьего варианта (ни overload, ни override).
Метод Object.getClass() — не приватный.
Sapienti sat!
Re[9]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 00:45
Оценка:
nikov wrote:

> За какими пределами? Класс B внутри класса A, из него даже можно вызвать

> этот приватный метод.
За пределами класса A.
Ну то что он внутри, совершенно перпендикулярно тому, что он наследник, тут механизмы inner-классов работают, можно только всякие A.this использовать (т.е. обращение к методу идёт из this, указывающего на экземпляр A). Причём тут тогда override? override — исключительно для механизма наследования.

Кстати да, не overload там был, а простое определение метода.
overload это разничный список аргументов для функции с одним именем.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 00:50
Оценка:
Здравствуйте, Cyberax, Вы писали:

N>>О, значит бывают ни overload, ни override. Значит, в первом примере нужно еще сначала доказать, что там нет третьего варианта (ни overload, ни override).

C>Метод Object.getClass() — не приватный.

Ну и что? Чем приватные методы особенные?

Мне хочется увидеть цельную картину, а вы мне пишете отдельные факты, непонятно как друг с другом связанные.
Re[12]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 00:56
Оценка:
Cyberax wrote:

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

> но с т.з. пользователя языка может пониматься как обычное поле.
> Да?
> int.class = String.class; //Упс...
> Для обычных полей такого добиться нельзя.
так говорю же public static final Class

> .>Я лишь хотел сказать, что new Empty(){}.getClass() никакого отношения

> к классу интерфейса не имеет. Хотя бы потому, что "new
> Empty(){}.getClass().equals(new Empty(){}.getClass())" ложно.
> empty.getClass() — это вызов метода _инстанса_. Т.е. показывает, что
так empty это не инстанс интерфейса, а ссылка на инстанс анонимного класса.

> любой интерфейс является наследником Object'а.

Нет, "new Empty(){}.getClass()" это синтаксический сахар для:
class $1 implements Empty extends Object
{
}
new $1().getClass()

Посмотри какие .class-файлы генерятся при компиляции.

или ты считаешь, что в "new Object(){}" Object является сам себе папой?
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 01:02
Оценка:
Здравствуйте, ., Вы писали:

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>


.>private член никоим образом не виден за пределами класса. Поэтому B ничего о наличии A.foo не знает, а значит overload.


>> За какими пределами? Класс B внутри класса A, из него даже можно вызвать

>> этот приватный метод.

.>За пределами класса A.

.>Ну то что он внутри, совершенно перпендикулярно тому, что он наследник, тут механизмы inner-классов работают, можно только всякие A.this использовать (т.е. обращение к методу идёт из this, указывающего на экземпляр A).
Я тебя не понял. Какое место есть в этом коде, находящееся за пределами класса A, в котором не виден метод foo, определенный в классе A? Ты хочешь сказать, что я не смогу вызвать этот метод из класса B? Это не так.

public class A {
    private final void foo() { }
    public class B extends A {
        public void foo() { new A().foo(); }
    }
}


.>Причём тут тогда override? override — исключительно для механизма наследования.

Я вообще ничего не утверждал про override. Было заявлено (без убедительного обоснования), что два метода с одинаковыми именами могут быть только override либо overload. Я привел пример и спросил: вот два метода с одинаковыми именами — чем они являются?
Re[11]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 01:04
Оценка:
Здравствуйте, nikov, Вы писали:

C>>Метод Object.getClass() — не приватный.

N>Ну и что? Чем приватные методы особенные?
Приватные методы не должны быть видны вне класса (внутренние/анонимные классы сюда не относятся). От них вообще вне класса не должно быть никаких эффектов. Если от этого отталкиваться, то всё становится просто и логично.

N>Мне хочется увидеть цельную картину, а вы мне пишете отдельные факты, непонятно как друг с другом связанные.

Ну вот я и пытаюсь объяснить
Sapienti sat!
Re[13]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 01:06
Оценка:
Здравствуйте, ., Вы писали:

>> Для обычных полей такого добиться нельзя.

.>так говорю же public static final Class
Да, торможу.

>> Empty(){}.getClass().equals(new Empty(){}.getClass())" ложно.

>> empty.getClass() — это вызов метода _инстанса_. Т.е. показывает, что
.>так empty это не инстанс интерфейса, а ссылка на инстанс анонимного класса.
Без разницы. Замени getClass() на notifyAll() или ему подобный.

.>Посмотри какие .class-файлы генерятся при компиляции.

И что?
Sapienti sat!
Re[11]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 01:07
Оценка:
nikov wrote:

> Я тебя не понял. Какое место есть в этом коде, находящееся за пределами

> класса A, в котором не виден метод foo, определенный в классе A? Ты
> хочешь сказать, что я не смогу вызвать этот метод из класса B? Это не так.
Понятно. Я имею в виду, что у тебя тут испоьзуется механизм inner-классов. Все приваты видны иннеру. И на наследование это никак не влияет. Приватные методы не наследуются, понятное дело.

> .>Причём тут тогда override? override — исключительно для механизма

> наследования.
> Я вообще ничего не утверждал про override. Было заявлено (без
> убедительного обоснования), что два метода с одинаковыми именами могут
> быть только override либо overload. Я привел пример и спросил: вот два
> метода с одинаковыми именами — чем они являются?

Твой пример аналогичен
class X {public void foo()}
class Y {public void foo()}
тоже методы с одинаковым именем.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: Члены интерфейсов в Java
От: . Великобритания  
Дата: 03.03.09 01:12
Оценка:
Cyberax wrote:

>> > Empty(){}.getClass().equals(new Empty(){}.getClass())" ложно.

>> > empty.getClass() — это вызов метода _инстанса_. Т.е. показывает, что
> .>так empty это не инстанс интерфейса, а ссылка на инстанс анонимного
> класса.
> Без разницы. Замени getClass() на notifyAll() или ему подобный.
Так это всё методы класса Object, а не интерфейсов.

> .>Посмотри какие .class-файлы генерятся при компиляции.

> И что?
Что утверждать наличие getClass у интерфейсов то же самое, что говорить: "скорость света в темноте равна нулю".
"new Empty(){}" никакого отношения к интерфейсам не имеет, это тоже класс.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 01:20
Оценка:
Здравствуйте, ., Вы писали:

.>Понятно. Я имею в виду, что у тебя тут испоьзуется механизм inner-классов. Все приваты видны иннеру. И на наследование это никак не влияет. Приватные методы не наследуются, понятное дело.


Мне это пока не понятно. Где это написано?
Кстати, в C# приватные методы всегда наследуются.
Re[13]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 01:34
Оценка:
Здравствуйте, nikov, Вы писали:

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


.>>Понятно. Я имею в виду, что у тебя тут испоьзуется механизм inner-классов. Все приваты видны иннеру. И на наследование это никак не влияет. Приватные методы не наследуются, понятное дело.


N>Мне это пока не понятно. Где это написано?


А, вот нашел в 8.4.8. Действительно не наследуются. Но какое отношение это имеет к override? Ведь в таком случае метод foo, определенный в классе A, тоже не наследуется, однако это не мешает методу из класса B переопределять его:

class A {
    public void foo() { }
}
class B extends A {
    public void foo() { }
}
Re[14]: Члены интерфейсов в Java
От: Cyberax Марс  
Дата: 03.03.09 02:06
Оценка:
Здравствуйте, nikov, Вы писали:

N>А, вот нашел в 8.4.8. Действительно не наследуются. Но какое отношение это имеет к override? Ведь в таком случае метод foo, определенный в классе A, тоже не наследуется, однако это не мешает методу из класса B переопределять его:

N>
N>class A {
N>    public void foo() { }
N>}
N>class B extends A {
N>    public void foo() { }
N>}
N>

А что тут такого? Тут простое переопределение (override) виртуального метода.

Объясняю для чего вводилась невидимость private'ов. Предположим, что у нас есть:
public class AbstractClass
{
    public abstract void someFunction();

    public void someFunc()
    {
           //... реализация
    }
}
public class Implementor extends AbstractClass
{
    public void someFunction() {/*....*/} //Тихо-мирно реализуем

    public void someAPI()
    {
         //Какая-то публичная функция
    }
}


Потом библиотека с AbstractClass меняется:
public class AbstractClass
{
    public abstract void someFunction();

    public void someFunc()
    {
           //... реализация
    }

    private void someAPI()
    {
         //Просто совпало имя функции.
    }
}
public class Implementor extends AbstractClass
{
    public void someFunction() {/*....*/} //Тихо-мирно реализуем

    public void someAPI()
    {
         //Какая-то публичная функция
    }
}


Что делать в этом случае?
Sapienti sat!
Re[7]: Члены интерфейсов в Java
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 03.03.09 06:08
Оценка: 42 (1)
Здравствуйте, nikov, Вы писали:

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


Вот здесь уже для меня неочевидно различие между 'скрывает метод базового класса' и 'неполиморфным методом'. То, что я вижу как пользователь класса, именно неполиморфное поведение.

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


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


Попробовать не в чем
Я исходил из официальной документации, которая ничего не говорит о возможности применения 'sealed' к class members.



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


Невнимательно я поглядел сначала спецификацию. Результат внимательного погляда:

9.2 Interface Members

It follows that is a compile-time error if the interface declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but has a different return type or incompatible throws clause.


8.4.2 Method Signature

...
Two methods have the same signature if they have the same name and argument types.

Two method or constructor declarations M and N have the same argument types if all of the following conditions hold:

* They have the same number of formal parameters (possibly zero)
* They have the same number of type parameters (possibly zero)
* Let <A1,...,An> be the formal type parameters of M and let <B1,...,Bn> be the formal type parameters of N. After renaming each occurrence of a Bi in N's type to Ai the bounds of corresponding type variables and the argument types of M and N are the same.

The signature of a method m1 is a subsignature of the signature of a method m2 if either

* m2 has the same signature as m1, or
* the signature of m1 is the same as the erasure of the signature of m2.
...
Two method signatures m1 and m2 are override-equivalent if either m1 is a subsignature of m2 or m2 is a subsignature of m1.



На мой взгляд, было бы более корректно поменять в спецификации условие 'unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface' на неявно объявляемые методы интерфейсов и заменить его на что-то вида 'unless a method with a signature that is override-equivalent to a public method of Object is explicitly declared by the interface'.
http://denis-zhdanov.blogspot.com
Re[7]: Члены интерфейсов в Java
От: Blazkowicz Россия  
Дата: 03.03.09 06:20
Оценка:
Здравствуйте, nikov, Вы писали:

N>Был бы признателен, если бы ты не просто объяснил это своими словами, а сказал, где именно это в спецификации написано.


Так открой спецификацию и попробуй хотя бы почитать:
http://rsdn.ru/forum/message/3310629.1.aspx
Автор: Blazkowicz
Дата: 02.03.09
Re[7]: Члены интерфейсов в Java
От: Blazkowicz Россия  
Дата: 03.03.09 06:29
Оценка:
Здравствуйте, nikov, Вы писали:

N>Я не вижу, где такое написано — "не разрешено". Вижу только, что методы интерфейса называются перегруженными, когда они имеют одинаковые имена, но разные сигнатуры.

Если бы ты хотя бы попытался почитать спецификацию по ссылкам которые я привел выше, то обнаружил бы, что методы называются перегружеными, только если у них различается сигнатура. А два метода с разным только возвращаемым типом имеют одну сигнатуру. Двух методов с одной сигнатурой в одном классе быть не может. Это тоже явно написано по ссылкам на спеку, которые ты не удосужился прочесть.
Re[5]: Члены интерфейсов в Java
От: Аноним  
Дата: 03.03.09 08:08
Оценка: 10 (2) +1
Здравствуйте, nikov, Вы писали:

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


B>>

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

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

JLS 3rd edition, 9.2 Interface Members

The members of an interface are:
* Those members declared in the interface.
* Those members inherited from direct superinterfaces.
* 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.

Последний bullet. Это из третьей редакции и полностью объясняет указанное поведение.

По второй редакции JLS получается, что в интерфейсе определены два метода с одинаковыми сигнатурами, но разными возвращаемыми типами. Такое во второй редакции недопустимо для классов, реализующих указанный интерфейс, т.е. интерфейс не может быть реализован.

Кстати, а о какой JLS мы говорим? В топике приводились ссылки на две редакции, а между ними есть разница.
Re[8]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 10:01
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

DZ>Я исходил из официальной документации, которая ничего не говорит о возможности применения 'sealed' к class members.


Не-не-не, точное описание языка на MSDN нельзя смотреть. Надо смотреть здесь.

DZ>9.2 Interface Members

DZ>

DZ>It follows that is a compile-time error if the interface declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but has a different return type or incompatible throws clause.


О, вот это полностью отвечает на мой вопрос. Большое спасибо!
Re[8]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 10:01
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Если бы ты хотя бы попытался почитать спецификацию по ссылкам которые я привел выше, то обнаружил бы, что методы называются перегружеными, только если у них различается сигнатура. А два метода с разным только возвращаемым типом имеют одну сигнатуру. Двух методов с одной сигнатурой в одном классе быть не может. Это тоже явно написано по ссылкам на спеку, которые ты не удосужился прочесть.


Читал, но видимо невнимательно, и нужный параграф упустил. Спасибо denis.zhdanov, что он указал на точное место.
Re[6]: Члены интерфейсов в Java
От: nikov США http://www.linkedin.com/in/nikov
Дата: 03.03.09 10:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>JLS 3rd edition, 9.2 Interface Members

А>

А>The members of an interface are:
А> * Those members declared in the interface.
А> * Those members inherited from direct superinterfaces.
А> * 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.

А>Последний bullet. Это из третьей редакции и полностью объясняет указанное поведение.

Да, я тоже говорю о 3rd edition. Этот абзац — первое, что я нашел по данному вопросу, но я не вижу, что он объясняет. В последнем bullet говорится о методе с совпадающим return type, а в моем примере он не совпадает. Впрочем, denis.zhdanov уже указал убедительное объяснение из 9.2.
Re: Члены интерфейсов в Java
От: mkizub Литва http://symade.tigris.org
Дата: 03.03.09 10:36
Оценка:
Здравствуйте, nikov, Вы писали:

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


N>
N>interface I {
N>    String getClass();
N>}
N>


interface I extends Object. Всегда (увы, хотелось бы иногда задавать interface Node extends AbstractNode). Потому как class Object является корнем всей иерархии reference классов, а интерфейсы есть reference класс (и ему нельзя задать другого класса-родителя). Пока понятно?

Второе, в Object есть метод final Class getClass(). Это значит, что данный метод нельзя переопределить (override) в классе-наследнике. Ему можно сделать overload, и в JVM это проканает, так как у этих методов будет разная сигнатура типа ( ()Ljava.lang.Class; и ()Ljava.lang.String; ). Используя ассемблер для JVM можно такой класс/интерфейс соорудить. Но сделать это в java и пользоваться им из java (языка, а не JVM) не сможешь, так как при резолвинге метода его возвращаемый тип не учитывается (даже если ты напишешь String s = ((I)i).getClass(); ). Из ассемблера, конечно, пользоваться им будет можно.

Если бы getClass() был не final и возвращал Object, то ему можно было-бы сделать такой override, поскольку String extends Object (а java с некоторых пор поддерживает ковариантные возвращаемые из метода типы). В JVM это был-бы overload (сигнатуры разные), а для java (как языка) это override (поскольку в языке возвращаемый тип не учитывается в "сигнатуре" метода). javac для таких случаев создаёт специальный bridge метод с сигнатурой типа ()Ljava.lang.Object; который просто будет вызывать ()Ljava.lang.String;
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.