2009-05-18 5 views
7
Перегрузка

В «Язык программирования Java ™, четвертое издание» Кен Арнольд, Джеймс Гослинг, Дэвид Холмс, его упоминали, что:Java Интерфейс: Наследование, Переопределение и методы

пункт: (4.3.2) «Аналогично, если интерфейс наследует более одного метода с одной и той же сигнатурой или если класс реализует разные интерфейсы, содержащие метод с одной и той же сигнатурой, существует только один такой метод. Реализация этого метода в конечном итоге определяется класс, реализующий интерфейсы, и там нет никакой двусмысленности. Если методы имеют одну и ту же подпись, но разные типы возвращаемых данных, то один из типов возвращаемых данных должен быть подтипом всех остальных, иначе ошибка компиляции. Реализация должна определить метод, который возвращает этот общий подтип «.

Может кто-нибудь дать мне пример кода, который обосновывает точки выше пункта?

Я попытался написать код и проверить, что упомянуто но я получаю ошибка времени компиляции суб-интерфейс скрывает метод базового интерфейса так можно реализовать только метод суб-интерфейс.

заранее спасибо. -Arun

+0

Можете ли вы показать код? –

+1

опубликуйте свой код и ваши ошибки в компиляторе, по крайней мере, дайте нам что-то (а) воспроизвести проблему; и (б) перейти оттуда. – corlettk

+0

Все, кого мне очень жаль - я пытался проверить, что было упомянуто в вышеупомянутом пара, используя j2sdk1.4.2_08 - я не понимал, что книга написана для JDK1.5 Так что это означает, что если вы скомпилируете фрагмент кода «Daniel Schneller» с помощью JDK1.4 вы получите «ImplementationOfAandB.java:17: methodB() в ImplementOfAandB не может реализовать methodB() в InterfaceA, пытаясь использовать несовместимый тип возвращаемого типа», тогда как с JDK1.5 он просто запускается хорошо. – akjain

ответ

2

В следующих двух интерфейсах methodA() идентично определяется в терминах параметров (нет) и типа возврата (int). Класс реализации внизу определяет один метод с этой точной сигнатурой. Поскольку он соответствует обеим интерфейсам, у вас нет проблем - любые вызовы, сделанные посредством ссылки типа InterfaceA или InterfaceB, будут отправлены на эту реализацию.

Второй methodB() определяется как возвращение любого подтипа Number (или Number сам) в InterfaceA. InterfaceB определяет methodB() как возвращающий Integer, который является подтипом Number. Класс реализации фактически реализует метод с Integer, что соответствует контракту как InterfaceA, так и InterfaceB. Здесь нет проблем. Замеченный случай methodB() был выполнен с возвратом Double, однако не работал: хотя он удовлетворил бы контракт InterfaceA, это противоречило бы с InterfaceB (что требует Integer).

Если InterfaceA и InterfaceB также с указанием (разные) контрактов на methodC() (закомментированный в примере), это было бы противоречивым и создать ошибку компилятора. Реализация обеих подписей (отличных от типа возврата) не допускается на Java.

Вышеупомянутые правила также сохраняются, если бы были добавлены какие-либо параметры в методы. Для простоты я сохранил это из примера.

public interface InterfaceA { 
    public int methodA(); 
    public Number methodB(); 
    // public int methodC(); // conflicting return type 
} 

public interface InterfaceB { 
    public int methodA(); 
    public Integer methodB(); 
    // public String methodC(); // conflicting return type 
} 

public class ImplementationOfAandB implements InterfaceA, InterfaceB { 
    public int methodA() { 
     return 0; 
    } 
    public Integer methodB() { 
     return null; 
    } 
    // This would NOT work: 
    // public Double methodB() { 
    //  return null; 
    // } 
} 
+0

Все, кого мне очень жаль - я пытался проверить, что было упомянуто в вышеупомянутом пара, используя j2sdk1.4.2_08 - Я не понимал, что книга написана для JDK1.5 Так что, если вы скомпилируете фрагмент кода «Daniel Schneller» с помощью JDK1.4, вы получите «ImplementationOfAandB.java:17: methodB() в ImplementOfAandB не может реализовать methodB() в InterfaceA; пытаясь использовать несовместимый тип возвращаемого типа «ошибка компиляции, тогда как с JDK1.5 он просто отлично работает. – akjain

1
interface A 
{ 
    void foo(); 
    //int bar(); <-- conflicts with B.bar() because of different return type 
} 

interface B 
{ 
    void foo(); 
    //double bar(); <-- conflicts with A.bar() because of different return type 
} 

class C implements A, B 
{ 
    void foo() // this implements A.foo() AND B.foo() 
    { 
     ... 
    } 
} 
8
interface A { 
    void method(); 
    Object returnMethod(); 
} 
interface B { 
    void method(); 
    B returnMethod(); 
} 

class Impl implements A,B 
{ 
    void method() { } 
    B returnMethod() { } 
} 

Как вы можете видеть, Impl.method()A.method() реализует как и B.method(), в то время как Impl.returnMethod() возвращает B, который является дочерним Object, таким образом выполняя A.returnMethod() «s контракт тоже. Будет ли последний требовать тип возврата, который не является родительским типом возврата B.returnMethod(), который был бы ошибкой компиляции, поскольку такая реализация не может существовать в Impl.

+0

Но Impl должен реализовать объект ReturnMethod(), правильно? –

+0

Это что, C#? Речь идет о Java. –

+0

Я не думаю, что это важно, какой язык;) –

1

Это то, что вы имеете в виду ?:

interface A { 
    Object get(); 
} 
interface B { 
    Number get(); 
} 

abstract class MyClass implements A, B { 
    // Try to override A.get, but cause a compile error. 
    public Object get() { return null; } 
} 

Такого метода в MyClass автоматически генерируются JAVAC как синтетический метод моста. Вы должны реализовать единственный метод, возвращающий тип, совместимый со всеми реализованными/отмененными методами (в данном случае Number/Integer/Double/и т. Д.).

1
/** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} /** 
* This is what you have 
*/ 
interface IXR { 
     //bla-bla-bla 
} 

class CXR implements IXR { 
     //concrete implementation of bla-bla-bla 
} 

interface IX { 
     public IXR f(); 
} 

interface IYR { 
     //some other bla-bla-bla 
} 

class CYR implements IYR { 
     //concrete implementation of the some other bla-bla-bla 
} 

interface IY { 
     public IYR f(); 
} 






/** 
* This is what you need to add 
*/ 
interface IZR extends IXR, IYR { 
     //EMPTY INTERFACE 
} 

class CZXR extends CXR implements IZR { 
     //EMPTY CLASS 
} 

class CZYR extends CYR implements IZR { 
     //EMPTY CLASS 
} 

class CZ implements IX, IY 
{ 
     public static boolean someCondition = true; 

     public IXR implementationOf_X_f() 
     { 
       System.out.println("CXR"); 
       return new CZXR(); 
     } 

     public IYR implementationOf_Y_f() 
     { 
       System.out.println("CYR"); 
       return new CZYR(); 
     } 

     public IZR f() { 
       if (someCondition) { 
         return (IZR) implementationOf_X_f(); 
       } else { 
         return (IZR) implementationOf_Y_f(); 
       } 
     } 

} 






/** 
* This is the usage of the required class 
*/ 
class program 
{ 
     public static void main(String[] x) { 
       CZ o = new CZ(); 
       IZR r = o.f(); 
       if (CZ.someCondition) { 
         CXR xr = (CXR) r; 
         //bla-bla-bla 
       } else { 
         CYR yr = (CYR) r; 
         //bla-bla-bla 
       } 
     } 
} 
+0

Сжатые ответы легче читать – davids

Смежные вопросы