深入理解java抽象类与接口

一、抽象类

     1、概念:关键词abstract声明的类叫作“抽象类”,一个类里面有1个或多个抽象方法的类就必须定义为抽象类。但是,没有抽象方法的类也可以只是用abstract修饰定义为抽象类。

     2、特点:

           (1)抽象类是类,具有类所有的特性,可以拥有成员变量和普通的成员方法;

          (2)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;

           (3)可以实现接口,并且可以只实现接口中的一个方法;

          (4)可以继承类,抽象类和实体类都可以;但是如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类;

           (5)抽象类不能用来创建对象,不能被实例化,但是抽象类有构造方法

代码示例:如下的代码是我们所熟悉的spring框架的底层DaoSupport

package org.springframework.dao.support;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
//此处抽象类DaoSupport 实现了接口 InitializingBean 初始化Bean配置
public abstract class DaoSupport implements InitializingBean {

    /** Logger available to subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
//final 阻止此方法被继承
    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);
        }

    }

//abstract  抽象方法,继承此类的子类必须实现该方法

   protected abstract void checkDaoConfig() throws IllegalArgumentException;

    protected void initDao()
throws Exception {
    }
}


package org.mybatis.spring.support;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DaoSupport;
import org.springframework.util.Assert;
//此SqlSessionDaoSupport 抽象类继承了DaoSupport 抽象类
public abstract class SqlSessionDaoSupport extends DaoSupport {

    private SqlSession sqlSession;

    private boolean externalSqlSession;

    @Autowired(required = false)
    public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        if (!this.externalSqlSession) {
            this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    @Autowired(required = false)
    public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSession = sqlSessionTemplate;
        this.externalSqlSession = true;
    }
    public final SqlSession getSqlSession
() {
        return this.sqlSession;
    }
    /**
     * {@inheritDoc}
     */
    protected void checkDaoConfig() {
        Assert.notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
    }
}

二、接口

   1、概念:使用interface来定义一个接口,可以理解为接口是一种特殊的抽象类。

   2、特点:

       (1)接口内所有方法只有声明,没有具体实现,没有方法体(隐式声明),方法都是抽象的,属性默认为 public abstract,例如:public abstract void func();

         (2)接口内的所有变量都默认是public static final ,必须被显示初始化;

         (3)接口没有构造方法,不能被实例化;

         (4)实现接口的类要实现所有的抽象方法,否则该类就必须声明为抽象类,加上 abstract关键字;

         (5)接口不可以实现接口(因为所有接口都是抽象方法),但是接口支持多继承例如:public interface func extends  func1, func2

代码示例:如下的代码是我们所熟悉的spring框架的底层InitializingBean接口
package org.springframework.beans.factory;

/**
 * Interface to be implemented by beans that need to react once all their
 * properties have been set by a BeanFactory: for example, to perform custom
 * initialization, or merely to check that all mandatory properties have been set.
 */
public interface InitializingBean {
    
    /**
     * Invoked by a BeanFactory after it has set all bean properties supplied
     * (and satisfied BeanFactoryAware and ApplicationContextAware).
     * <p>This method allows the bean instance to perform initialization only
     * possible when all bean properties have been set and to throw an
     * exception in the event of misconfiguration.
     * @throws Exception in the event of misconfiguration (such
     * as failure to set an essential property) or if initialization fails.

     */

//方法都是抽象的,属性默认为 public abstract

    void afterPropertiesSet() throws Exception;
}

三、抽象类和接口的区别

    1、抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3、接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

   4、一个类只能继承一个抽象类,而一个类却可以实现多个接口;

     5、抽象类:展示是不是的关系,抽象类提出公共部分,让其类继承,使继承了该抽象类的所有子类都拥有这个属性或方法,不用各个类再都写一遍那个属性和方法,精简代码,提高开发质量;譬如,一个类需要实现一个接口中的某一个方法,但是这个接口有很多的方法,这时就可以先定义一个抽象类,去实现这个接口,并只实现你所需要的这一个方法,再写一个子类,继承这个抽象方法,这样便不用实现那个接口中的所有方法了。举例:定义一个person类,给person类一些属性用teacher类和student类去继承这个person类,老师和学生都有了人的一些共同属性

     6、接口:展示有没有的关系,定义一个接口,在接口里面声明一些方法,让实现该接口的类,具体实现这些方法;如:定义一个learn接口,并声明一个learnKnowledge()方法,用teacher类和student类去是实现这个learn接口,实现里面学习方法,学习不同的内容

     总结:在日常写代码的过程中,我们通常会写很多接口,用于解耦,对于接口的理解应该熟悉,但抽象类相对就写得较少,其实,抽象类应用得当,在代码的精简和提升上有很大帮助的;留心一下,看底层代码的时候,就会发现,抽象类应用非常多,所以对抽象类的熟练掌握应用也是很必要的。

     (注:第一次写博客知识,技术有限,难免出错,如发现问题,欢迎指正,感谢。)

           

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值