【Java】子类中某方法实现时进行调用父类的方法,在该父类的方法实现中有调用A方法,A方法在子类中也存在(函数名、形参一致,修饰符可见),那么会使用的是父类的A方法还是子类的A方法?
探索
首先定义一个接口:Human,然后定义一个抽象类:AbstractHuman。其中AbstractHuman#execute进行实现自身方法的调用。
实现类:
Man继承AbstractHuman,重写say(content),Man#execute直接使用super.execute(action, content)
SpecialHuman继承AbstractHuman,不重写say(content),SpecialHuman#execute直接使用super.execute(action, content)
通过调用实现类#execute来观察并解决此贴提出的疑问。
另外提供通过实现类#say(withSuper,content)来观察调用父类方法,且其实现中调用的方法在子类中不存在的结果。
代码实现
public class Sample0530 {
public interface Human {
void execute(String action, String content);
void say(String content);
void say(boolean withSuper, String content);
}
public static abstract class AbstractHuman implements Human {
@Override
public void execute(String action, String content) {
switch (action) {
case "say":
say(content);
break;
case "sayWithThis":
this.say(content);
break;
default:
throw new UnsupportedOperationException("not support action: " + action);
}
}
@Override
public void say(String content) {
System.out.print("(人类)嘤嘤嘤: " + content);
sayAfter();
}
private void sayAfter() {
System.out.println("~");
}
}
public static class Man extends AbstractHuman {
@Override
public void execute(String action, String content) {
super.execute(action, content);
}
@Override
public void say(String content) {
System.out.println("(男人)哈哈哈: " + content);
}
@Override
public void say(boolean withSuper, String content) {
if (withSuper) {
super.say(content);
return;
}
say(content);
}
}
public static class SpecialHuman extends AbstractHuman {
@Override
public void execute(String action, String content) {
super.execute(action, content);
}
@Override
public void say(boolean withSuper, String content) {
if (withSuper) {
super.say(content);
return;
}
say(content);
}
}
public static void main(String[] args) {
Man man = new Man();
//直接调用自身say(content)输出 (男人)哈哈哈: 爱我中华
man.say("爱我中华");
//直接调用自身say(content)输出 (男人)哈哈哈: 爱我中华
man.say(false, "爱我中华");
//通过super.say(content)调用 -- 通过父类的say(content)输出 (人类)嘤嘤嘤: 爱我中华~
man.say(true, "爱我中华");
//直接调用super.execute,其中父类实现中调用自身的say(content)
//如果子类重写了say(content) 则使用子类的say(content)输出 (男人)哈哈哈: 爱我中华
man.execute("say", "爱我中华");
//直接调用super.execute,其中父类实现中调用自身的say(content) 区别:是否使用this关键字
//如果子类重写了say(content) 则使用子类的say(content)输出 (男人)哈哈哈: 爱我中华
man.execute("sayWithThis", "爱我中华");
System.out.println("------------------------");
//子类实现不重写say(content)输出 全部:(人类)嘤嘤嘤: 爱我中华~
SpecialHuman specialHuman = new SpecialHuman();
specialHuman.say("爱我中华");
specialHuman.say(false, "爱我中华");
specialHuman.say(true, "爱我中华");
specialHuman.execute("say", "爱我中华");
specialHuman.execute("sayWithThis", "爱我中华");
}
}
输出结果
(男人)哈哈哈: 爱我中华
(男人)哈哈哈: 爱我中华
(人类)嘤嘤嘤: 爱我中华~
(男人)哈哈哈: 爱我中华
(男人)哈哈哈: 爱我中华
------------------------
(人类)嘤嘤嘤: 爱我中华~
(人类)嘤嘤嘤: 爱我中华~
(人类)嘤嘤嘤: 爱我中华~
(人类)嘤嘤嘤: 爱我中华~
(人类)嘤嘤嘤: 爱我中华~
结论
子类方法实现中进行调用父类方法,如果在父类方法的实现中存在调用的方法,该方法在子类中存在且进行了重写(函数名、形参一致,修饰符可见),则会使用子类的方法。