java中继承+接口+泛型的无解组合

本文介绍了一种基于Java的通用DAO设计模式,通过抽象基类BaseHibernateDao实现了CRUD等常见操作,极大减少了开发工作量。具体展示了User实体类、IBaseDao接口及其实现类BaseHibernateDao的代码细节。

不废话直接上代码:

 

工程结构图:

 

实体User:

package com.smonk.user.entity;

public class User {
//....
}


IBaseDao:

package com.smonk.common.base;

import java.io.Serializable;
import java.util.List;

public interface IBaseDao<T, ID extends Serializable> {

 public abstract List<T> findAll();

 /**
  * 查找所有,并分页
  * @param page 要返回的页数
  * @param pageSize 没有记录数
  * @return
  */
 public abstract List<T> findAll(int page, int pageSize);

 public abstract void save(T entity);

 public abstract void delete(T entity);

 /**
  * 与findByProperty相似,当properyName == value 时把相应的记录删除
  */
 public abstract void deleteByProperty(String propertyName, Object value);

 public abstract List<T> findByExample(T example);

 /**
  * 通过属性查找
  * @param propertyName 属性名称
  * @param value 属性的值
  * @return
  */
 public abstract List<T> findByProperty(String propertyName, Object value);

 /**
  * 通过多个属性查找
  * @param propertyNames 属性名称数组
  * @param values 属性值数组
  * @return
  */
 public abstract List<T> findByPropertys(String[] propertyNames,
   Object[] values);

 /**
  * 通过多个属性查找,并分页, 属性名称数组和属性值数组的序列要对应
  * 
  * @param propertyNames 属性名称数组
  * @param values 属性值数组
  * @param page 页码
  * @param pageSize 每页内容条数
  * @return
  */
 public List<T> findByPropertys(String[] propertyNames, Object[] values,
   int page, int pageSize);

 /**
  * 通过属性查找,并分页, 属性名称数组和属性值数组的序列要对应
  * @param propertyNames 属性名称
  * @param values 属性值
  * @param page 页码
  * @param pageSize 每页内容条数
  * @return
  */
 public List<T> findByProperty(String propertyName, Object value, int page,
   int pageSize);

 /**
  * 统计所有记录的总数
  * @return 总数
  */
 public int countAll();

 /**
  * 统计数据库中当propertyName=value时的记录总数
  * @param propertyName
  * @param value
  * @return
  */
 public int countByProperty(String propertyName, Object value);

 /**
  * 统计数据库中当多个propertyName=value时的记录总数
  * @param propertyNames
  * @param values
  * @return
  */
 public int countByPropertys(String[] propertyNames, Object[] values);

 public abstract void saveOrUpdate(T entity);

 public abstract T findById(ID id);

 public abstract void update(T entity);

 /**
  * 获得持久化对象的类型
  * @return
  */
 public abstract Class<T> getPersistentClass();

 /**
  * 查找并通过某一属性排序
  * @param property 排序依据的顺序
  * @param isSequence 是否顺序排序
  */
 public List<T> findAndOrderByProperty(int firstResult, int fetchSize,
   String propertyName, boolean isSequence);

 /**
  * 查找并通过某一属性排序
  * @param property 排序依据的顺序
  * @param isSequence 是否顺序排序
  */
 public List<T> findAllAndOrderByProperty(String propertyName,
   boolean isSequence);

}


 

BaseHibernateDao:

package com.smonk.common.base;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class BaseHibernateDao<T, ID extends Serializable> extends
		HibernateDaoSupport implements IBaseDao<T, ID> {
	private Class<T> persistentClass;

	@SuppressWarnings("unchecked")
	public BaseHibernateDao() {
		// 获取持久化对象的类型
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public Class<T> getPersistentClass() {
		return persistentClass;
	}

	/**
	 * 通过id查找
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T findById(ID id) {
		return (T) this.getHibernateTemplate().get(getPersistentClass(), id);
	}

	public void save(T entity) {
		this.getHibernateTemplate().save(entity);
	}

	/**
	 * 删除
	 */
	public void delete(T entity) {
		this.getHibernateTemplate().delete(entity);
	}

	/**
	 * 通过属性删除
	 */
	public void deleteByProperty(String propertyName, Object value) {
		String queryString = "delete from " + getPersistentClass().getName()
				+ " as model where model." + propertyName + "= ?";
		Query query = this.getSession().createQuery(queryString);
		query.setParameter(0, value);
		query.executeUpdate();
	}

	/**
	 * saveOrUpdate
	 */
	public void saveOrUpdate(T entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
	}

	/**
	 * 更新
	 */
	public void update(T entity) {
		this.getHibernateTemplate().update(entity);
	}

	/**
	 * 分页查找所有的记录
	 * @param page 要返回的页数
	 * @param pageSize 没有记录数
	 * @return
	 */
	public List<T> findAll(int page, int pageSize) {
		String queryString = "from " + getPersistentClass().getName();
		Query query = this.getSession().createQuery(queryString);
		int firstResult = (page - 1) * pageSize;
		query.setFirstResult(firstResult);
		query.setMaxResults(pageSize);
		return query.list();
	}

	/**
	 * 统计所有记录的总数
	 * @return 总数
	 */
	public int countAll() {
		String queryString = "select count(*) from "
				+ getPersistentClass().getName();
		Query query = this.getSession().createQuery(queryString);
		List list = query.list();
		Long result = (Long) list.get(0);
		return result.intValue();
	}

	/**
	 * find By Example
	 * @param entity
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByExample(T entity) {
		return this.getHibernateTemplate().findByExample(entity);
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		return this.getHibernateTemplate().find(
				"from " + getPersistentClass().getName());
	}

	/**
	 * 通过属性查找
	 * @param propertyName 属性名称
	 * @param value 属性的值
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByProperty(String propertyName, Object value) {
		String queryString = "from " + getPersistentClass().getName()
				+ " as model where model." + propertyName + "= ?";
		return this.getHibernateTemplate().find(queryString, value);

	}

	/**
	 * 通过多个属性组合查询
	 * @param propertyNames 属性名称数组
	 * @param values 对应于propertyNames的值 return 匹配的结果
	 */
	public List<T> findByPropertys(String[] propertyNames, Object[] values) {
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("from " + getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++) {
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}
		String queryString = strBuffer.toString();
		return this.getHibernateTemplate().find(queryString, values);
	}

	/**
	 * 通过属性查找并分页
	 * @param propertyName 属性名称
	 * @param value 属性值
	 * @param page 页数
	 * @param pageSize 每页显示条数
	 */
	public List<T> findByProperty(String propertyName, Object value, int page,
			int pageSize) {
		return this.findByPropertys(new String[] { propertyName },
				new Object[] { value }, page, pageSize);
	}

	/**
	 * 通过多个属性组合查询
	 * @param propertyNames 属性名称数组
	 * @param values 对应于propertyNames的值
	 * @param page 页数
	 * @param pageSize 每页显示数 return 匹配的结果 return 匹配的结果
	 */
	public List<T> findByPropertys(String[] propertyNames, Object[] values,
			int page, int pageSize) {

		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("from " + getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++) {
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}
		String queryString = strBuffer.toString();

		int firstResult = (page - 1) * pageSize;

		Query query = this.getSession().createQuery(queryString);
		query.setFirstResult(firstResult);
		query.setMaxResults(pageSize);
		for (int i = 0; i < values.length; i++) {
			query.setParameter(i, values[i]);
		}

		return query.list();
	}

	/**
	 * 通过属性统计数量
	 * @param propertyName 属性名称
	 * @param value 属性值
	 */
	public int countByProperty(String propertyName, Object value) {
		String[] propertyNames = new String[] { propertyName };
		Object[] values = new Object[] { value };
		return this.countByPropertys(propertyNames, values);
	}

	/**
	 * 通过多个属性统计数量
	 * @param propertyNames 属性名称数组
	 * @param values 对应的属性值数组 return
	 */
	public int countByPropertys(String[] propertyNames, Object[] values) {
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("select count(*) from "
				+ getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++) {
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}

		String queryString = strBuffer.toString();
		Query query = this.getSession().createQuery(queryString);
		for (int i = 0; i < values.length; i++) {
			query.setParameter(i, values[i]);
		}

		List list = query.list();
		Long result = (Long) list.get(0);
		return result.intValue();
	}

	/**
	 * 查找T并通过某一属性排序
	 * @param property 排序依据的顺序
	 * @param isSequence 是否顺序排序,false为倒序
	 */
	public List<T> findAndOrderByProperty(int firstResult, int fetchSize,
			String propertyName, boolean isSequence) {
		String queryString = "from " + getPersistentClass().getName()
				+ " as model order by model." + propertyName;
		if (isSequence == false) {
			queryString = queryString + " DESC";
		}

		Query queryObject = getSession().createQuery(queryString);
		queryObject.setFirstResult(firstResult);
		queryObject.setMaxResults(fetchSize);
		return queryObject.list();

	}

	/**
	 * 查找所有并通过某个属性排序
	 * @param propertyName 排序依据的属性名称
	 * @param isSequence 是否顺序排列
	 */
	public List<T> findAllAndOrderByProperty(String propertyName,
			boolean isSequence) {
		String queryString = "from " + getPersistentClass().getName()
				+ " as model order by model." + propertyName;
		if (isSequence == false) {
			queryString = queryString + " DESC";
		}

		Query queryObject = getSession().createQuery(queryString);
		return queryObject.list();
	}

}


IUserDao:

package com.smonk.user.dao;

import com.smonk.common.base.IBaseDao;
import com.smonk.user.entity.User;

public interface IUserDao extends IBaseDao<User, Integer> {
	/**
	 * 通过用户名查找用户
	 * @param userName 用户名
	 * @return TUser 用户对象,如果用户名不存在返回null
	 */
	public User findByUserName(String userName);
}


UserHibernateDao:

package com.smonk.user.dao;

import java.util.List;

import com.smonk.common.base.BaseHibernateDao;
import com.smonk.user.entity.User;

public class UserHibernateDao extends BaseHibernateDao<User, Integer> implements
		IUserDao {

	// property constants
	public static final String USER_NAME = "userName";

	/**
	 * 通过名称查找用户
	 * @return User
	 */
	public User findByUserName(String userName) {
		List<User> userList = super.findByProperty(USER_NAME, userName);
		if (userList.size() != 0) {
			return userList.get(0);
		} else {
			return null;
		}
	}
	
	public static void main(String[] args) {
		Integer id = 10;
		IUserDao dao = new UserHibernateDao();
		dao.findById(id);
	}
}


请看只有寥寥几句的UserDao拥有多少功能!!!:

 

亲,请问这样的架构省了多少代码?省了多少人天?省了多少枯燥与烦扰?。。。
<think>我们正在讨论接口的多继承问题。根据引用[3]和[4],我们知道在Java中,接口可以多继承其他接口,而类只能单继承类但可以实现多个接口。 引用[3]详细说明了接口继承的特点: 1. 接口里定义的都是静态常量和抽象方法(在Java 8之前),没有逻辑实现。 2. 具体的方法由实现类覆盖,不会出现歧义(因为只有方法声明,没有实现)。 3. 接口中的变量都是public static final,编译期就会检查冲突。 4. 如果多个父接口有相同的属性,会导致引用不明确,编译错误;相同的方法则没有问题。 引用[4]补充了接口继承和实现的区别: - 接口可以继承多个接口(使用extends关键字,后面可以跟多个接口,用逗号分隔)。 - 类可以实现多个接口(使用implements关键字)。 - 类可以继承一个父类的同时实现多个接口。 因此,我们将围绕接口的多继承进行详细说明,包括它的语法、规则、优点以及注意事项。 另外,引用[1]提到接口继承的优点:解耦合、提高可维护性、增强灵活性。 引用[2]则说明Java不支持类的多继承,但通过接口可以实现类似多继承的效果。 下面组织回答: 标题:接口继承详解 一、基本概念 接口继承是指一个接口可以同时继承多个父接口。在Java中,这是通过`extends`关键字后跟多个父接口(用逗号分隔)来实现的。 二、语法格式 ```java public interface 子接口名 extends 父接口1, 父接口2, ... { // 子接口可以定义新的方法或常量 } ``` 三、继承规则 1. **方法继承**:子接口继承所有父接口的抽象方法。如果多个父接口有相同的方法(方法签名相同),则合并为一个,不会产生冲突,因为接口方法没有实现。 2. **常量继承**:子接口继承所有父接口的常量。但如果多个父接口有同名的常量,则在子接口中直接使用该常量名会导致编译错误(引用不明确),必须通过父接口名来明确指定。 3. **默认方法(Java 8及以上)**:如果多个父接口有相同签名的默认方法,则子接口必须覆盖该方法(可以选择保留其中一个父接口的默认方法,或者重新定义)。 四、示例代码 根据引用[3]的示例,我们修改并完善: ```java // 父接口1 interface InterfaceA { void methodA(); int VALUE = 10; // 常量 } // 父接口2 interface InterfaceB { void methodB(); int VALUE = 20; // 常量,与InterfaceA中的常量同名 } // 子接口继承InterfaceA和InterfaceB interface SubInterface extends InterfaceA, InterfaceB { void additionalMethod(); // 由于InterfaceA和InterfaceB都有VALUE常量,这里会导致引用不明确 // 但子接口中不能直接使用VALUE,必须通过接口名访问 // 如果要重新定义一个常量,则可以: // int VALUE = 30; // 这样在子接口中就有了自己的VALUE } // 实现类 class MyClass implements SubInterface { @Override public void methodA() { System.out.println("实现methodA"); } @Override public void methodB() { System.out.println("实现methodB"); } @Override public void additionalMethod() { System.out.println("实现additionalMethod"); } // 使用常量时,必须明确指定是哪个接口的 public void printValues() { System.out.println(InterfaceA.VALUE); // 输出10 System.out.println(InterfaceB.VALUE); // 输出20 } } ``` 五、优点(参考引用[1]) 1. **解耦合**:通过接口继承,可以将不同的功能模块化,类在实现接口时不需要了解具体实现细节。 2. **提高可维护性**:功能模块化后,修改或升级某个功能不会影响其他模块。 3. **增强灵活性**:类通过实现接口可以组合多种行为,满足复杂需求。 六、注意事项 1. **常量冲突**:多个父接口有同名常量时,在子接口或实现类中直接使用常量名会导致编译错误,必须通过接口名显式指定。 2. **默认方法冲突(Java 8+)**:如果多个父接口有相同方法签名的默认方法,子接口必须覆盖这个方法,否则编译错误。覆盖时可以使用`InterfaceName.super.methodName()`来调用特定父接口的默认方法。 3. **类继承层次**:接口继承可以形成复杂的类网络,但设计时应避免过度复杂化。 七、与类多继承的对比(参考引用[2]) Java不支持类的多继承,主要是为了避免“菱形继承”问题(即一个类继承的两个父类有相同方法,导致歧义)。而接口继承之所以可行,是因为: - 接口只有方法声明(在Java 8之前),没有实现,所以不会出现方法调用的歧义(由实现类决定如何实现)。 - 接口常量是静态的,通过接口名访问,不会产生歧义。 八、在中的应用(参考引用[5]) 在中,我们可以使用接口继承来约束类参数,例如: `<T extends InterfaceA & InterfaceB>` 表示类参数T必须同时实现InterfaceA和InterfaceB。 最后给出相关问题。 </think>### 接口继承详解 接口继承Java实现多态性的核心机制,允许**一个接口继承多个父接口**,形成灵活的行为组合。以下是关键技术解析(基于引用[1][3][4][5]的综合说明): --- #### 一、核心特性 1. **语法规则** 使用`extends`关键字继承多个父接口(逗号分隔): ```java public interface ChildInterface extends ParentInterface1, ParentInterface2 { // 可声明新方法 } ``` 2. **继承内容** - ✅ **方法签名**:继承所有父接口的抽象方法 - ✅ **静态常量**:继承`public static final`常量 - ❌ **默认方法(Java 8+)**:需显式解决冲突(后文详述) 3. **冲突处理原则** | **冲突类** | **处理方式** | 示例说明 | |----------------------|--------------------------------------|----------------------------------| | 同名抽象方法 | 自动合并为单一方法[^3] | 父接口中的`void save()`被继承 | | 同名常量 | 编译报错(需显式指定接口名访问)[^3] | `ParentInterface1.VALUE` | | 同名默认方法(Java 8+) | 子接口必须重写默认方法[^4] | 使用`ParentInterface1.super.method()`调用 | --- #### 二、底层原理 1. **无实现继承机制** 接口继承**行为契约**(方法签名),不继承具体实现逻辑,从根本上避免"菱形继承问题"(引用[2]对比类多继承缺陷): ```java interface Flyable { void fly(); } interface Swimmable { void swim(); } // 合法多继承组合飞行+游泳能力 interface Amphibian extends Flyable, Swimmable {} ``` 2. **常量冲突检测** 父接口的同名常量会在编译期强制显式调用(确保类安全): ```java interface A { int VALUE = 1; } interface B { int VALUE = 2; } interface C extends A, B {} // 编译报错: ambiguous VALUE // 正确访问方式 class Impl implements C { void print() { System.out.println(A.VALUE); // 显式指定接口 } } ``` --- #### 三、典应用 1. **能力组合扩展**(引用[1][5]) 通过多继承聚合离散功能: ```java // 定义能力单元 interface Loggable { void log(); } interface Serializable { void serialize(); } // 组合成高阶接口 interface Persistable extends Loggable, Serializable {} // 实现类只需满足组合契约 class FileStorage implements Persistable { public void log() { /* 日志实现 */ } public void serialize() { /* 序列化实现 */ } } ``` 2. **约束**(引用[5]) 多继承接口用于边界: ```java // T必须同时实现Runnable和Comparable <T extends Runnable & Comparable<T>> void process(T item) { item.run(); item.compareTo(other); } ``` --- #### 四、Java 8+ 的演进 1. **默认方法冲突解决** 当父接口存在同名默认方法时,子接口必须重写: ```java interface Alpha { default void reset() { System.out.println("Alpha重置"); } } interface Beta { default void reset() { System.out.println("Beta重置"); } } interface Gamma extends Alpha, Beta { @Override default void reset() { Alpha.super.reset(); // 显式调用指定父接口实现 } } ``` 2. **静态方法隔离** 接口静态方法不被继承,需通过接口名直接调用: ```java interface Utils { static void help() { /* ... */ } } class Client { void callHelp() { Utils.help(); // 非继承调用 } } ``` --- #### 五、设计收益(引用[1][3]) 1. **解耦功能模块** 将系统能力拆解为原子接口,通过组合实现灵活扩展 2. **避免类继承缺陷** 规避类多继承的"菱形问题"(如C++的多继承缺陷[^2]) 3. **契约标准化** 统一行为定义,如JDBC的`Driver`接口规范不同数据库实现 > **最佳实践**:优先组合单一职责接口,避免超过3层继承深度;常量命名添加接口名前缀防冲突[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值