我有一个带有侦听器接口的类。我想用侦听器接口作为子类类型创建一个子类。例如:
interface OnSadListener {
void imSad();
}
interface OnCryingListener extends OnSadListener {
void imCrying();
}
class Person {
OnSadListener listener;
void setListener(OnSadListener listener){
this.listener = listener;
}
}
class Baby extends Person {
OnCryingListener listener; // I want it to override the original one in Person
void cry(){
listener.imSad();
listener.imCrying();
}
}
void doIt(){
Baby michael = new Baby();
michael.setListener(new OnCryingListener() {
@Override void imSad(){
System.out.print("I'm sad");
}
@Override void imCrying(){
System.out.print("Wahhhhhh!");
}
});
michael.cry(); // the imCrying funtion is empty (setListener setted Person's listener and not Baby's)
}
我知道Baby.setListener(new OnCryingListener(){...});
会起作用,因为OnCryingListener是OnSadListener的子类。但是那样我将无法调用imCrying()
,否则它将为空。
OnCryingListener listener
是否可以“替代” Person
的{{1}}?
答案 0 :(得分:0)
您需要重写setListener(OnSadListener)
类中的Baby
方法,因为您从未设置侦听器。
class Baby extends Person {
OnCryingListener listener;
@Override
void setListener(OnSadListener listener) {
this.listener = (OnCryingListener) listener;
}
void cry() {
listener.imSad();
listener.imCrying();
}
}
下面是一个更完整的示例...
class Person {
protected OnSadListener listener; // Make it protected or add accessor/mutators
void setListener(OnSadListener listener) {
this.listener = listener;
}
}
通过保护listener
,可以重用Person
类的OnSadListener
。您只需要将侦听器强制转换为OnCryingListener
即可调用imCrying()
方法。
class Baby extends Person {
@Override
void setListener(OnSadListener listener) {
this.listener = (OnCryingListener) listener;
}
void cry() {
listener.imSad();
((OnCryingListener) listener).imCrying(); // Cast here
}
}
如果要使用泛型,则可以省去强制转换。
public class Person <T extends OnSadListener> {
protected T listener;
public void setListener(T listener) {
this.listener = listener;
}
}
现在您可以告诉Baby
正在处理哪种类型的侦听器。
public class Baby extends Person<OnCryingListener> {
@Override
public void setListener(OnCryingListener listener) {
this.listener = (OnCryingListener) listener;
}
public void cry() {
listener.imSad();
listener.imCrying(); // No need to cast
}
}
答案 1 :(得分:0)
在Java中,字段不是“覆盖”的。仅方法被覆盖。
由于您假定字段被覆盖,因此在此示例中,您期望listener
对象中仅存在一个Baby
字段。并且您希望在调用michael.setListener()
时设置单个字段。
但是实际上,Baby
对象中有2个字段。调用michael.setListener()
时,只会设置Person
类中声明的字段。