严格限定泛型类型采用多重界限

简介:

从哲学上来说,很难描述一个具体的人,你可以描述它的长相,性格,工作等,但是人都是有多重身份的,估计只有使用多个And(与操作)将所有的描述串联起来才能描述一个完整的人,人在不同的环境中角色也在不断的更换.

用Java程序来对一类人进行管理,比如在公交车费优惠系统中,对部分人员,工资低于2500元的上班族而且是站立着的乘客 车费打8折.

这里的类型参数有两个限制条件,一为上班族,二为乘客,具体到程序中就是一个泛型参数有两个上界Upper Bound,首先定义两个接口以及实现类:

复制代码
 1 //职员
 2 interface Staff{
 3     //工资
 4     public int getSalary();
 5 }
 6 
 7 //乘客
 8 interface Passenger{
 9     //是否是站立状态
10     public boolean isStanding();
11 }
12 
13 class Me implements Staff,Passenger{
14     public boolean isStanding(){
15         return true;
16     }
17 
18     public int getSalary() {
19         return 2000;        
20     }    
21 }
复制代码

Me这种类型的人物有很多,不同的人都可能站着,但是他们的工资实现很可能不同.

也就是说使用 T extends Me 是限定不了需求对象的.

可以考虑使用多重限定,看代码:

复制代码
 1 public class Client {
 2     //工资低于2500元的上斑族并且站立的乘客车票打8折
 3     public static <T extends Staff & Passenger> void discount(T t){
 4         if(t.getSalary()<2500 && t.isStanding()){
 5             System.out.println("恭喜你!您的车票打八折!");
 6         }
 7     }
 8     public static void main(String[] args) {
 9         discount(new Me());
10     }
11 }
复制代码

使用"&"符号设定多重边界Multi Bounds 指定泛型类型T必须是Staff和Passenger的共有子类型,此时变量t就 有了限定的方法和属性.

 

在Java的泛型中,可以使用&符号关联多个上界并实现多个边界限定,而且只有上界才有此限定.

下界没有多重限定的情况.

多个下界,编码者可以自行推断出具体的类型.比如"? super Integer"和"? super Double"可以细化为Number类型了,或者Object类型了,无需编译器推断了.

为什么要说明多重边界?

因为编码者太少使用它了.比如一个判断用户权限的方法,使用的是策略模式Startegy Pattern,实例代码:

复制代码
import java.util.Arrays;
import java.util.List;

public class UserHandler<T extends User>{
    // 判断用户是否有权限执行操作
    public boolean permit(T user, List<Job> jobs) {
        List<Class<?>> iList = Arrays.asList(user.getClass().getInterfaces());
        // 判断是否是管理员
        if (iList.indexOf(Admin.class) > -1) {
            Admin admin = (Admin) user;
            /* 判断管理员是否有此权限 */
        } else {
            /* 判断普通用户是否有此权限 */
        }
        return false;
    }
}



interface User {

}

class UserImpl implements User, Admin {

}

interface Admin {

}

class Job {

}
复制代码

此处进行了一次泛型参数类别判断,这里不仅仅违背了单一职责原则,而且已经使用泛型限定参数的边界了,还要进行泛型类型的判断.

事实上,使用多重边界可以很方便的解决问题,而且非常优雅,建议读者在开发中考虑使用多重限定.

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/5626071.html,如需转载请自行联系原作者

相关文章
|
29天前
|
Java Spring
使用枚举定义常量更好点儿
使用枚举定义常量更好点儿
14 1
|
4月前
|
存储 安全 Java
泛型+通配符(数学角度)
泛型+通配符(数学角度)
32 0
|
8月前
🎖️typeScrpt中如何使用条件类型和泛型?
我将通过一个可能对日常使用非常有帮助的代码示例更深入地介绍泛型。
47 1
|
9月前
|
存储 Java
你知道变量、数据类型、方法、控制语句之间的关系吗?
java程序在运行的过程中会在内存中产生一些数据,这些数据就会被临时保存在内存当中,而内存中的每一小块区域我们就可以理解为是变量,数据会动态改变的,当程序想要访问或是修改这些数据的时候需要通过一些标识来进行操作,我们就可以使用变量名来标识每一块内存区域。
|
12月前
|
编译器 C++
c++中基本类型详细解释外加基本运算规则
类型 含义 wchat_t 宽字符 bool 布尔类型 char 字符 chat16_t unicode字符 chat_32 unicode字符 short 短整型 int 整形 long 长整型 longlong 长整型 float 单精度浮点型 double 双精度浮点型 longdouble 扩展精度浮点型
90 1
|
JavaScript 编译器
学习TypeScrip6(类型断言 | 联合类型 | 交叉类型)
学习TypeScrip6(类型断言 | 联合类型 | 交叉类型)
61 0
|
自然语言处理 JavaScript Shell
什么,你告诉我?作用域也分种类?
什么,你告诉我?作用域也分种类?
71 0
什么,你告诉我?作用域也分种类?
泛型的上下限怎么理解
实体类 public class Fruit { } class Apple extends Fruit{} class Pear extends Fruit{} class Orange extends Fruit{} 复制代码 泛型的上限 如下图,可以看到这里是不允许再添加任何实例的,只能从该list中去获取实例。 为什么不能添加呢?🐖 因为这个list 可能有以下几个情况 list是Fruit类型的,此时你去添加Fruit的子类都没问题 list是Apple类型的,此时你只能添加Apple,同理Pear,Orange也是。🙃 根本不晓得传进来的参数list会是哪种类型
165 0
|
Java Kotlin
Kotlin 范型之泛型约束、类型投影、星号投影
Kotlin 范型之泛型约束、类型投影、星号投影
388 0
|
编译器 C#
改善C#程序的157建议——建议42学习笔记:使用泛型参数兼容泛型接口的不可变性。
改善C#程序的157建议——建议42学习笔记:使用泛型参数兼容泛型接口的不可变性。
101 0