您的位置:首页 > 编程语言 > Java开发

java-组合接口中的名字冲突问题

2012-10-16 09:53 597 查看

组合接口时的名字冲突

===========================组合接口时的方法冲突========================

在实现多重继承时,可能会碰到一个小陷阱:当一个类同时implements 接口1与接口2时,假如接口1与接口2同时都有一个相同方法签名(即方法的名字,参数,不包括返回类型)的方法时,如果在类中没有再定义该方法,编译器就会报错!

看个例子:

interface I1 { void f(); }

interface I2 { int f(int i); }

interface I3 { int f(); }

class C { public int f() { return 1; } }

class C2 implements I1, I2 {

public void f() {}

public int f(int i) { return 1; } // overloaded

}

class C3 extends C implements I2 {

public int f(int i) { return 1; } // overloaded

}

class C4 extends C implements I3 {

// Identical, no problem:

public int f() { return 1; }

}

// Methods differ only by return type:

//! class C5 extends C implements I1 {} //标记1

//! interface I4 extends I1, I3 {} ///:~ //标记2

在标记1的地方会报错是因为:C 与 I1 拥有相同方法签名的方法,即 f(),虽然它们的返回类型不同,但是在java的重载中,通过返回类型是不能区分的,只有方法签名不同的方法,才可以区分。由于C5没有重写f(),当调用C5的f()时,无法分清到底是要调用C 还是 I1 的f()。因此会报错。

----解决方法是 在C5类中,重新定义f()!

要标记2的地方也会报错,道理同上!!!

===========================组合接口时的域冲突========================

关于接口,首先我们想到的是abstract class,因为接口可以看成,方法全都是abstract的“类”,关于abstract 类的特点,这里就不多讲,书上都讲得很清楚,其中有一点很重要的是:一个继承于abstract的类,如果被声明为abstract,那么这个子类可以不用定义基类中的abstract方法。否则,必须写出abstract基类中的全部abstract方法!

正如,我们刚才说的,接口就是一个abstract类,所以,如果一个abstract类implements 一个接口,该类可以不用为该接口的方法做定义,否则也必须对所有方法都提供具体的实现!

这里,我们讨论的是:组合接口时的域冲突

看一个很具有代表性的例子:

abstract class MyClass Implements Interface1, Interface2{

public void f(){}

public vlid g(){}

}

interface Interface1{

int VAL_A=1;

int VAL_B=2;

void f();

void g();

}

interface Interface2{

int VAL_B=3;

inf VAL_C=4;

void g();

void h();

}

Select the one right answer.

(a) Interface1 and Interface2 do not match, therefore MyClass cannot implement them both.

(b) MyClass only implements Interface1. Implementation for void h() from Interface2 is missing.

(c) The declarations of void g() in the two interfaces clash.

(d) The definitions of int VAL_B in the two interface class.

(e) Nothing is wrong with the code, it will compile without errors

手动编译这个类,发现可以通过编译,而且不会报错。那么是不是答案就应该选择(e)了呢??

在看答案之前,我们要知道的是:MyClass是abstract的,所以,即使它Implements Interface1, Interface2,也可以不用定义这两个接口中的方法!

然后我们先来看选项(a):a 是错的,因为虽然方法g()同存于Interface1, Interface2,这可能会造成

组合接口时的方法冲突,但MyClass重新对g()做了定义!所以这样是可以的

选顶(b)也是错的,因为MyClass是abstract的,实现了Interface2,可以不有定义Interface2中的方法

选顶(C)错误码的地方同选项a差不多!

现在只剩下(d)与(e)两个选项,只有(d)才是正确的,所以本题答案是:d(惊讶吧!)

本程序虽然可以通过编译,但如果编译MyClass.VAL_B时,就会有错误,因为,这里出现了组合接口时的域冲突!Interface1, Interface2都有域int VAL_B ,MyClass 实现了这两个类,那么,这个域也被带到了该类中,如果调用VAL_B时,系统不知道要调用哪个(类似方法冲突)。

解决的方法是:在MyClass中再定义一个static int VAL_B
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: