码迷,mamicode.com
首页 > 编程语言 > 详细

Java核心技术之深入理解抽象类和接口

时间:2015-09-04 07:36:43      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

1 总体说明

抽象类
模板方法模式
接口

2 抽象类

抽象类是不能被实例化的类,一般设计成被子类继承,实现父类的抽象方法。
和普通类最大的不同就是不能实例化,可以声明抽象方法,让子类实现。
可以定义成员变量和普通方法

package tony.javacore.oop.abstractclass;
import static tony.javacore.util.io.PrintUtils.println;
/**
 * <p>抽象父类Shape</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name Shape.java
 * @see
 * @version 2015年8月30日下午10:20:19
 * @since JDK8.0u45
 */
public abstract class Shape {

    private String color; //图形颜色

    /*get set */
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }


    /*默认构造器*/
    public Shape(){
        println("Execute Shape Constructor Method");
    }

    /*重载构造器*/
    public Shape(String color){
        println("Execute Shape Constructor Method :Color is "+color);
        this.color=color;
    }

    /**
     * 定义抽象计算周长的方法
     * @return
     * @version 2015年8月30日下午10:21:10
     * @since
     */
    public abstract double calPerimeter();
    /**
     * 返回图形形状的抽象方法
     * @return
     * @version 2015年8月30日下午10:22:53
     * @since
     */
    public abstract String getType();
}

子类继承抽象类时,必须实现抽象父类的抽象方法

package tony.javacore.oop.abstractclass;
/**
 * 
 * <p>定义子类圆形</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name Circle.java
 * @see
 * @version 2015年8月30日下午10:25:35
 * @since JDK8.0u45
 */
public class Circle extends Shape{

    private double radius; //子类特有属性 半径


    /*get set */
    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    /**
     * 子类Circle构造器
     * @param color
     * @param radius
     */
     public Circle(String color,double radius) {
         super(color);
         this.radius=radius;
    }

    @Override
    public double calPerimeter() {
        return 2*Math.PI*radius; //圆的周长为2r
    }

    @Override
    public String getType() {
        return getColor()+" 圆形";
    }

    @Override
    public String toString() {
        return "Circle [radius=" + radius + "]";
    }


}

子类可以拥有自己独特的属性,方法

package tony.javacore.oop.abstractclass;
import static tony.javacore.util.io.PrintUtils.println;
/**
 * <p>三角形</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name Triangle.java
 * @see
 * @version 2015年8月30日下午10:28:35
 * @since JDK8.0u45
 */
public class Triangle extends Shape {

    /*定义三角形的三条边*/
    private double one;
    private double two;
    private double three;

    public Triangle(String color, double one, double two, double three) {
        super(color);
        setSides(one, two, three);
    }

    /**
     * 创建三角形对象的三条边
     * @param one
     * @param two
     * @param three
     * @version 2015年8月30日下午10:33:22
     * @since
     */
    public void setSides(double one, double two, double three){
        if(one>=two+three||two>one+three||three>one+two){
            println("两边之和必须大于第三边长");
            return;
        }
        this.one=one;
        this.two=two;
        this.three=three;
    }

    @Override
    public double calPerimeter() {
        return one+two+three;
    }

    @Override
    public String getType() {
        return super.getColor()+" 三角形";
    }

    @Override
    public String toString() {
        return "Triangle [one=" + one + ", two=" + two + ", three=" + three + "]";
    }
}

当父类的引用(Shape shape)指向子类的对象(Circle)时,多态就发生了。
此时如果使用父类的引用调用父类中定义的方法,运行时实际上是调用子类的方法,父类的同名方法被覆盖了。

package tony.javacore.oop.abstractclass;
import static tony.javacore.util.io.PrintUtils.println;

/**
 * <p>抽象类测试用例</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name ShapeHandler.java
 * @see
 * @version 2015年8月30日下午10:35:11
 * @since JDK8.0u45
 */
public class ShapeHandler {

    public static void main(String[] args) {
        Shape circle =new Circle("红色 ", 2.2);
        Shape triangle=new Triangle("绿色 ", 3.0, 4.0, 5.0);
        println("圆形的周长为 : "+circle.calPerimeter());
        println("三角形的周长为 : "+triangle.calPerimeter());

        println(circle.getType());
    }
}

3 模板方法模式

模板方法模式是类的行为模式。
准备一个抽象类,将部分逻辑以具体方法以及具体的构造函数的形式实现,然后声明一些抽象方法强迫让子类实现剩余的逻辑。不同的子类可以使用不同的方式来实现这些抽象方法,从而对剩余的逻辑有不同的实现。

定义处理航班消息模板的抽象父类
模板方法:主要是接收到消息后对消息进行转换,然后针对消息做业务逻辑处理
抽象方法:主要是针对消息的转换以及业务逻辑的方法声明

package tony.javacore.oop.abstractclass;

import tony.javacore.oop.abstractclass.bean.MessageBean;

/**
 * <p>消息处理抽象父类</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name MsgHandlerAbs.java
 * @see
 * @version 2015年8月30日下午11:38:49
 * @since JDK8.0u45
 */
public abstract class MsgHandlerAbs {
    /**
     * 处理消息模板方法
     * @param object
     * @version 2015年8月30日下午11:44:05
     * @since
     */
    public final void handleMessage(Object object){
        try {
            MessageBean msgBean =new MessageBean();

            if(msgBean instanceof MessageBean){
                msgBean=(MessageBean) object;
            }
            else{
                msgBean.setMessage(object);
            }

            Object newObj=parseMsg(msgBean);

            handleBussiness(newObj);
        } catch (Exception e) {
        }
    }

    /**
     * 对解析后的消息再进行加工,变成程序后续处理所需实体(包含原实体)
     * @param messageBean
     * @return
     * @version 2015年8月30日下午11:44:14
     * @since
     */
    public abstract Object parseMsg(MessageBean messageBean);
    /**
     * 对再加工后的实体进行逻辑处理
     * @param object
     * @version 2015年8月30日下午11:45:07
     * @since
     */
    public abstract void handleBussiness(Object object);
}

消息实体,包括消息类型以及类型所对应的对象

package tony.javacore.oop.abstractclass.bean;
/**
 * <p> 消息实体,包括消息类型以及类型所对应的对象</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass.bean
 * @file_name MessageBean.java
 * @see
 * @version 2015年8月30日下午11:53:27
 * @since JDK8.0u45
 */
public class MessageBean {


    private String msgType; //消息类型

    private String uniqueKey;//消息代表的唯一键值

    private Object message; //消息对象

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        this.msgType = msgType;
    }

    public String getUniqueKey() {
        return uniqueKey;
    }

    public void setUniqueKey(String uniqueKey) {
        this.uniqueKey = uniqueKey;
    }

    public Object getMessage() {
        return message;
    }

    public void setMessage(Object message) {
        this.message = message;
    }

}

航路点上的航班消息处理,继承自抽象父类MsgHandlerAbs ,实现消息转换以及对应航路点上的消息业务逻辑处理

package tony.javacore.oop.abstractclass.message;

import tony.javacore.oop.abstractclass.MsgHandlerAbs;
import tony.javacore.oop.abstractclass.bean.MessageBean;
/**
 * <p>航路点上的航班消息处理</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass
 * @file_name PointFlightInfoMsgHandler.java
 * @see
 * @version 2015年8月30日下午11:47:10
 * @since JDK8.0u45
 */
public class PointFlightInfoMsgHandler extends MsgHandlerAbs {

    @Override
    public Object parseMsg(MessageBean messageBean) {
        //将发送过来的消息转换为对应航路点航班消息Bean
        return null;
    }

    @Override
    public void handleBussiness(Object object) {
        //处理航路点上的航班消息业务逻辑
    }
}

机场点航班消息处理继承自抽象父类MsgHandlerAbs ,实现消息转换以及对应机场点上的消息业务逻辑处理

package tony.javacore.oop.abstractclass.message;

import tony.javacore.oop.abstractclass.MsgHandlerAbs;
import tony.javacore.oop.abstractclass.bean.MessageBean;
/**
 * <p>机场点上的航班消息处理</p>
 * @author tony 18616939520@163.com
 * @project_name JavaCore
 * @package_name tony.javacore.oop.abstractclass.message
 * @file_name AirportInfoMsgHandler.java
 * @see
 * @version 2015年8月31日上午12:00:31
 * @since JDK8.0u45
 */
public class AirportInfoMsgHandler extends MsgHandlerAbs {

    @Override
    public Object parseMsg(MessageBean messageBean) {
        //将传递过来的消息实体转换为机场点消息Bean
        return null;
    }

    @Override
    public void handleBussiness(Object object) {
        //处理机场点上的航班消息的业务逻辑
    }
}

4 接口

接口是体现规范和实现分离的思想
与抽象类最大的不同之处在于不能定义普通方法,意味着方法只能是抽象方法(只有方法声明,让实现接口的实现类去实现声明的方法),接口可以继承多个接口
成员变量默认使用static final修饰,也就是静态常量。
JDK8.0以后,接口中可以定义默认方法,默认方法可以提供实现。
JDK8.0以后,接口中可以定义类方法(也就是使用static修饰的方法)

在JavaWeb开发中通常都是采用接口加实现的方式来实现业务的分层开发。
例如DAO层,声明常用的数据访问方法,然后让子类去实现
这里采用了Spring封装的SqlSessionTemplate去实现,而如果想让其他实现类(例如Spring JDBC)去实现,只要继承自DaoManager即可。

定义常用的数据访问接口

package tony.shopcenter.common.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import tony.shopcenter.common.page.PagerModel;

/**
 * <p>统一数据库访问接口</p>
 * @author tony 18616939520@163.com
 * @project_name ShopCenter
 * @package_name tony.shopcenter.dao
 * @file_name DaoManager.java
 * @see  tony.shopcenter.common.page.PagerModel
 * @version 2015年8月27日 上午11:14:47
 * @since JDK8.0u45
 */
public interface DaoManager<E extends PagerModel<?>> {

    /*************************增加记录*************************/
    public int insert(String statement);
    public int insert(String statement,Object... parametes);


    /*************************删除记录*************************/
    public int delete(String statement);
    public int delete(String statement,Object ... parameters);


    /*************************修改记录*************************/
    public int udpate(String statement);
    public int update(String statement,Object ... parameters);

    /*************************查询记录*************************/
    public <T> T selectOne(String statement);
    public <T> T selectOne(String statement,Class<T>requiredType,Object...parameters);
    public <K,V> Map<K, V> selectMap(String statement,String mapKey );
    public <K,V> Map<K,V> selectMap(String statement,String mapKey,Object...parameters);
    public <E> List<E> selectList(String statement);
    public <E> List<E> selectList(String statement,Object ... parameters);

    /*************************获取数据连接信息*************************/
    public Connection getConnection() throws SQLException;

}

MyBatis特有的批量数据处理

package tony.shopcenter.common.dao;

import java.util.List;

import tony.shopcenter.common.page.PagerModel;

/**
 * <p>MyBatisBaseDao数据访问接口</p>
 * @author tony 18616939520@163.com
 * @project_name ShopCenter
 * @package_name tony.shopcenter.common.dao
 * @file_name MyBatisBaseDao.java
 * @see
 * @version 2015年8月27日 下午12:57:36
 * @since JDK8.0u45
 * @param <T>
 */
public interface MyBatisBaseDao<T> extends DaoManager<PagerModel>  {


    /**
     * 批量新增,修改,删除
     * @param statement
     * @param list
     * @return
     */
    public int batchUpdate(String statement,List<T> list);

}

使用Spring封装MyBatis的SqlSessionTemplate完成数据库的数据操作

package tony.shopcenter.common.dao.impl;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import tony.shopcenter.common.dao.MyBatisBaseDao;
import tony.shopcenter.common.page.PagerModel;

/**
 * <p>
 * MyBatis数据访问实现
 * </p>
 * @author tony 18616939520@163.com
 * @project_name ShopCenter
 * @package_name tony.shopcenter.common.dao.impl
 * @file_name MyBatisBaseDaoImpl.java
 * @see
 * @version 2015年8月27日 下午4:08:16
 * @since JDK8.0u45
 */
@Repository
public class MyBatisBaseDaoImpl<PagerModel> implements
        MyBatisBaseDao<PagerModel> {
    // 使用Spring封装MyBatis的SqlSessionTemplate完成数据库的数据操作
    @Value("sqlSessionTemplate")
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    public int insert(String statement) {
        return sqlSessionTemplate.insert(statement);
    }

    @Override
    public int insert(String statement, Object... parameters) {
        return sqlSessionTemplate.insert(statement, parameters);
    }

    @Override
    public int delete(String statement) {
        return sqlSessionTemplate.delete(statement);
    }

    @Override
    public int delete(String statement, Object... parameters) {
        return sqlSessionTemplate.delete(statement, parameters);
    }

    @Override
    public int udpate(String statement) {
        return sqlSessionTemplate.update(statement);
    }

    @Override
    public int update(String statement, Object... parameters) {
        return sqlSessionTemplate.update(statement, parameters);
    }

    @Override
    public <T> T selectOne(String statement) {
        return sqlSessionTemplate.selectOne(statement);
    }

    @Override
    public <T> T selectOne(String statement, Class<T> requiredType,
            Object... parameters) {
        return sqlSessionTemplate.selectOne(statement, parameters);
    }

    @Override
    public <K, V> Map<K, V> selectMap(String statement, String mapKey) {

        return sqlSessionTemplate.selectMap(statement, mapKey);
    }

    @Override
    public <K, V> Map<K, V> selectMap(String statement, String mapKey,
            Object... parameters) {

        return sqlSessionTemplate.selectMap(statement, parameters, mapKey);
    }

    @Override
    public <E> List<E> selectList(String statement) {
        return sqlSessionTemplate.selectList(statement);
    }

    @Override
    public <E> List<E> selectList(String statement, Object... parameters) {
        return sqlSessionTemplate.selectList(statement, parameters);
    }

    @Override
    public int batchUpdate(String statement, List<PagerModel> list) {
        return this.update(statement, list);
    }

    @Override
    public Connection getConnection() throws SQLException {
        return sqlSessionTemplate.getConnection();
    }
}

关于接口和抽象类的使用案例,可以去阅读JDK的集合框架API,Collection接口以及常用实现类ArrayList,LinkedList以及HashSet,TreeSet等等。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java核心技术之深入理解抽象类和接口

标签:

原文地址:http://blog.csdn.net/tony_cto/article/details/48119561

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!