java父类调用被子类重写的方法
来源:互联网 发布:linux cens输入法切换 编辑:程序博客网 时间:2024/04/30 01:20
1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解java继承中的初始化机制)。
例子:
public abstract class Father {public Father() {display();}public void display() {System.out.println("Father's display");}}
public class Son extends Father {public Son() {}public void display() {System.out.println("Son's display");}public static void main(String[] args) {new Son();}}
输出为:
Son's display
这种机制有优点,不过有时也存在问题。
优点:通过继承相同的父类,初始化子类时,父类会调用不同子类的不同复写方法,从而实现多态性。
举一个Spring中的例子:
Spring中可以通过为每个DAO注入一个已经用DataSource初始化的JdbcTemplate,来执行SQL语句。但是每个DAO都通过编码实现这个注入就产生了大量代码冗余,于是Spring提供了一个JdbcDaoSupport类,DAO只需继承这个类,就会自动注入已初始化好的JdbcTemplate,那么是如何做到的呢?查看源码:
JdbcDaoSupport继承了DaoSupport:
public abstract class JdbcDaoSupport extends DaoSupport
DaoSupport实现了InitializingBean接口,该接口只有一个void afterPropertiesSet() throws Exception;
方法,Spring会在初始化Bean的属相后查看这个Bean是否实现了InitializingBean接口,如果继承了就会自动调用afterPropertiesSet方法。
那么看一下DaoSupport中的afterPropertiesSet是如何实现的:
public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {// Let abstract subclasses check their configuration.checkDaoConfig();// Let concrete implementations initialize themselves.try {initDao();}catch (Exception ex) {throw new BeanInitializationException("Initialization of DAO failed", ex);}}
他这里调用了checkDaoConfig方法,此方法是抽象方法,真正运行时会去调用子类重写过的该方法。
查看JdbcDaoSupport如何重写checkDaoConfig():
@Overrideprotected void checkDaoConfig() {if (this.jdbcTemplate == null) {throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required");}}
JdbcDaoSupport会检查jdbcTemplate是否注入,没注入会抛出异常!这就完成了注入检测,通过子类实现具体检测的过程!这也就是当你的DAO继承了JdbcDaoSupport,但是在XML配置DAO时没有配置DataSource属性会抛出异常的原因。
那么JdbcTemplate是何时注入的呢?观察JdbcDaoSupport源码,发现setDataSource()方法,框架根据XML配置初始化DAO时,会调用属性的set方法注入,如果DAO没有该set方法,则调用父类的。也就是调用JdbcDaoSupport的setDataSource方法,此时便创建了DAO执行SQL语句需要的jdbcTemplate。
/** * Set the JDBC DataSource to be used by this DAO. */public final void setDataSource(DataSource dataSource) {if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {this.jdbcTemplate = createJdbcTemplate(dataSource);initTemplateConfig();}}
缺点:如果在父类构造函数中调用被子类重写的方法,会导致子类重写的方法在子类构造器的所有代码之前执行,从而导致子类重写的方法访问不到子类实例变量的值,因为此时这些变量还没有被初始化。
0 0
- java父类调用被子类重写的方法
- 调用被子类重写的方法
- 父类构造器调用被子类重写的方法
- Java中不要在父类的构造方法中调用会被子类重写的方法
- JAVA笔试题总结3:父类构造器调用被子类重写方法
- 父类构造函数调用被子类重写的方法——要避免!
- 父类的静态方法能否被子类重写
- 父类的静态方法能否被子类重写
- Java之调用被子类重载的方法
- [Java]static、final修饰的方法是否可以被子类继承、是否可以被子类重写及final修饰详解
- 不要在构造函数中调用以后会被子类重写的方法
- 创建子类对象时,父类构造函数中调用被子类重写的方法为什么调用的是子类的方法,而被子类重载的方法不会调用?
- 创建子类对象时,父类构造函数中调用被子类重写的方法为什么调用的是子类的方法,而被子类重载的方法不会调用?
- 关于父类静态方法能不能被子类重写详细
- java_静态方法能否被子类重写
- 关于父类的静态方法能否被子类重写的问题
- java的main方法能不能被子类继承
- Java的重写与调用父类方法问题
- FTP连接报530 User 用户名 cannot log in home directory inaccessible的解决方法
- android 蓝牙创建通讯链路的2种方法
- mars android开发之八:SQLite
- shell按行读取文件的方法
- poj 2886 Who Gets the Most Candies?(线段树单点更新+反素数)真难。。。
- java父类调用被子类重写的方法
- 共享内存和 系列函数
- html5开发之viewport使用(页面缩放)
- Runtime.exec()执行linux shell
- 开发框架——横版格斗——6.技能播放的逻辑关系
- 2014.02.19 系统操作记录 数据库表的设计
- 无需Cgwin打包cocos2dx APK。
- 东莞小姐打工年入百万
- JAVA 聊天程序(客户端)