JAVA混型和潜在类型机制
一、混型
①、定义
二、利用JAVA如何实现混型
①、代理 ②、装饰器模式 ③、动态代理模式 ④、装饰器模式与代理模式的区别
三、潜在类型机制
①、定义
四、JAVA的潜在类型机制的补偿
①、实现类与类之间的方法共用(反射机制)。。。讲述其使用过程。。。及其缺点
②、实现序列(List,Queue)之间方法的共用。。。讲述其使用过程。。。及其缺点
③、实现Collection之间方法的共用。。。讲述其使用过程。。。及其缺点
④、实现一般化的方法共用(适配器模式)。。。讲述其使用过程。。及其缺点
⑤、实现优雅的一般化的方法共用(策略模式)。。。讲述其使用过程。。。
回答:
一、混型
就是一个类混合了多个类的能力。 当想在混型类中修改某些东西,这些修改会应用于混型的所有类型上。
二、实现混型
①、代理机制
步骤:1、创建混型接口 2、创建接口的具体实现 3、创建混型类,类中持有混型。
首先 创建混型接口
public interface Fly{
void fly();
}
Fly
其次,创建接口的具体实现
public Swing implements Fly{
public void fly(){
System.out.println("I can use swing to fly");
}
}
Swing
最后创建具体混型类
public class Duck implements Fly{
private Swing mSwim = new Swing();
public void fly(){
mSwim.fly();
}
public void swim(){
System.out.println("I can swim");
}
}
Duck
缺点:当使用复杂的混型,代码量会急剧上升。
②、装饰器模式
步骤:1、创建被装饰对象(可以是类也可以是接口,最好是接口 这里我用的是接口) 2、创建被装饰对象继承装饰接口 3、创建装饰器(装饰器中包含装饰对象)
1、创建装饰接口
public interface Basket {
void show();
}
Basket
2、继承装饰接口,为被装饰对象
public class Original implements Basket{
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("I am a Basket");
}
}
Original
3、创建装饰器(Apple,Banana,Orange)
public class AppleDecorator implements Basket{
private Basket mBasket;
public Apple(Basket basket) {
// TODO Auto-generated constructor stub
mBasket = basket;
}
@Override
public void show() {
// TODO Auto-generated method stub
mBasket.show();
System.out.println("Apple");
}
}
AppleDecorator
public class BananaDecorator implements Basket{
private Basket mBasket;
public Banana(Basket basket) {
// TODO Auto-generated constructor stub
mBasket = basket;
}
@Override
public void show() {
// TODO Auto-generated method stub
mBasket.show();
System.out.println("Banana");
}
}
BananaDecorator
其他略
4、使用装饰器
public class Main {
public static void main(String[]args){
Original original = new Original();
Basket basket = new Apple(new Banana(new Orange(original)));
basket.show();
}
}
Main
缺点:只有效作用于装饰的最后一层。
③、动态代理
步骤:1、创建接口 2、创建接口的具体实现 3、创建Proxy类 4、使用Proxy类
①、创建接口
public interface Business {
void doSomething();
void doSomeElse();
}
Business
②、实现接口
public class RealObject implements Business{
@Override
public void doSomething() {
// TODO Auto-generated method stub
printf("Do some better things");
}
@Override
public void doSomeElse() {
// TODO Auto-generated method stub
printf("Anything i can do it");
}
public static void printf(String str){
System.out.println(str);
}
}
RealObject
③、创建代理类
public class BusinessProxy implements InvocationHandler{
private Object mData;
public BusinessProxy(Object dataObject) {
// TODO Auto-generated constructor stub
mData = dataObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("No one thing I can do");
return method.invoke(mData, args);
}
}
BusinessProxy
④、启动代理
public class Main {
public static void main(String[] args){
RealObject object = new RealObject();
Business proxy = (Business)Proxy.newProxyInstance(Business.class.getClassLoader(), new Class[]{Business.class},new BusinessProxy(object));
proxy.doSomething();
}
}
Main
④、
装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。当我们使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
JAVA潜在类型机制
1、什么叫做潜在类型机制
在C++和python中,可以不知道当前类的类型,就可以调用方法。
①、JAVA如何补偿(反射机制)
步骤 1、建立两个类,其有相同的方法
public class TypeOne {
private int data = 1;
public void setData(int data){
this.data = data;
}
public int getData() {
return data;
}
}
TypeOne
public class TypeTwo {
private int data = 2;
public void setData(int data){
this.data = data;
}
public int getData(){
return data;
}
}
TypeTwo
2、利用反射调用,相同的方法
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
TypeOne typeOne = new TypeOne();
TypeTwo typeTwo = new TypeTwo();
//调用反射方法,实现不同类可以通过一个方法调用相同的方法
getData(typeOne);
getData(typeTwo);
}
//实现反射的方法
public static void getData(Object type){
Class<?> c = type.getClass();
try {
//获取叫做getData()的方法
Method method = c.getMethod("getData");
//调用该方法
int data = (int) method.invoke(type,null);
//输出
System.out.println(type.getClass().getSimpleName()+" data:"+data);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Main
缺点:只能在类与类之间使用。
②、序列中调用相同的方法
步骤1、创建fill()方法,传入迭代器,通过反射调用序列中对象的方法
public class Full{
//通过泛型,传入 迭代器,和具体需要调用的方法名,及参数
public static <T,S extends Iterable<T>> void fill(S sql,Method method,Object...args){
//获取迭代器
Iterator<T> iterator = sql.iterator();
while(iterator.hasNext()){
T object = iterator.next();
try {
//调用方法
method.invoke(object, args);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Full
步骤2、创建调用对象
public class Apple {
private static int count = 1;
private final int id = count++;
public void getId(){
System.out.println(id);
}
}
Apple
步骤3、使用方法
public static void main(String[] args){
ArrayList<Apple> list = new ArrayList<>();
for(int i=0; i<10; ++i){
list.add(new Apple());
}
try {
fill(list, Apple.class.getMethod("getId"),null);
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Full
个人理解:就是将传入的参数变成了迭代器而已。
缺点:只能在含迭代器的序列中使用。
③、在Colleciotn中调用add()方法
同:只是将传入的参数直接变成Collection了而已
④、通过适配器使用潜在类型
步骤1、创建适配的接口
public interface Addable<T> {
void add(T data);
}
Addable
步骤2、创建适配器
public class AddableAdapter<T> implements Addable<T> {
private Collection<T> collection;
public AddableAdapter(Collection<T> col) {
// TODO Auto-generated constructor stub
this.collection = col;
}
@Override
public void add(T data) {
// TODO Auto-generated method stub
collection.add(data);
}
}
AddableAdapter
步骤3、使用适配器。
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> list = new ArrayList<>();
AddableAdapter<Integer> adapter = new AddableAdapter<>(list);
adapter.add(10);
for(int i : list){
System.out.println(i);
}
}
}
Main
⑤、通过策略模式一般化潜在类型
步骤1、创建策略接口
步骤2、继承策略接口
步骤3、创建功能类
步骤4、调用
个人理解:策略接口的具体实现就是Collection类中对象共有的方法。 功能类的方法,就是对共有方法的调用。
JAVA混型和潜在类型机制的更多相关文章
- Java泛型(11):潜在类型机制
泛型的目标之一就是能够编写尽可能广泛应用的代码. 为了实现这一点,我们需要各种途径来放松对我们的代码将要作用的类型所做的限制,同时不丢失静态类型检查的好处.即写出更加泛化的代码. Java泛型看起来是 ...
- Java 基本类型和对象类型的区别
Java 基本类型和对象类型的区别 基本类型: int long byte float double char boolean short 对象类型: Integer Long Byte Float ...
- 【Java心得总结一】Java基本类型和包装类型解析
说到数据类型这个问题是一个基本的不能再基本的问题,我们当初编程入门第一课一般就是讲数据类型,而今天我想记录的是一个在Java中容易忽略的问题,即基本类型和包装类型. 一.基本类型出现的原因 我们都知道 ...
- Java 基本类型和包装类型
讲基本类型和包装类型之前,首先要介绍,装箱和拆箱 装箱:基本类型转化为包装类型 拆箱:包装类型转化为拆箱类型 为什么要有包装类型?Java是面向对象的语言,Java中一切都是对象除了基本数据类型,所以 ...
- java基本类型和封装类型区别及应用
1.基本类型只能按值传递,而每个基本类型对应的封装类是按引用传递的. 2.从性能上说java中的基本类型是在堆栈上创建的,而所有的对象类型都是在堆上创建的,(对象的引用在堆栈上创建).比如 Integ ...
- java基本类型和包装类型
int 是基本类型,直接存数值 Integer是类,产生对象时用一个引用指向这个对象 Java把内存划分成两种:一种是栈内存,另一种是堆内存 在函数中定义的一些基本类型的变量和对象的引用变 ...
- 基础篇:深入解析JAVA泛型和Type类型体系
目录 1 JAVA的Type类型体系 2 泛型的概念 3 泛型类和泛型方法的示例 4 类型擦除 5 参数化类型ParameterizedType 6 泛型的继承 7 泛型变量TypeVariable ...
- java基本类型和包装类型的区别以及object的公共方法
Java的类型分为两部分,一个是基本类型(primitive),如int.double等八种基本数据类型: 一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节 ...
- java基本类型和包装类型的区别
Java的类型分为两部分,一个是基本类型(primitive),如int.double等八种基本数据类型: 另一个是引用类型(reference type),如String.List等.而每一个基本类 ...
随机推荐
- 让操作javascript对象数组像.net lamda表达式一样
让操作javascript对象数组像.net lamda表达式一样 随着web应用程序的富客户端化.ajax的广泛使用及复杂的前端业务逻辑.对js对象数组.json数组的各种操作越来越多.越来越复杂. ...
- 正确看待HTML5的语法变化
也许会有人问:“HTML4已经很普及了,如果改变基础语法,会不会有什么影响?” 我们都知道,在HMTL5之前几乎没有符合标准规范的Webu浏览器!在这种情况下,各个浏览器之间的互相兼容性和互操作性在很 ...
- dede调用时间大全标签,不同格式!
[field:pubdate function="MyDate('Y-m-d',@me)"/]2013-12-17[field:pubdate function=MyDate('m ...
- 【Ecstore】为自建模块添加自定义主题模板
做好ECSOTRE模块后,需在主题中添加模板,而添加模板页面时只有产品分类页.产品详细页.首页等内置模块的模板类型. 下面介绍如何添加一个自定义的模板类型“buildings”. 一.修改(建议复制到 ...
- 使用meta来控制浏览器的渲染方式
<meta name="renderer" content="webkit"><!--默认使用webkit内核(360急速模式)--> ...
- Python模块的介绍
Python模块的学习: 1.os模块: 下面只对os模块中几个比较常用的方法做一些简单的示例: os.system():这个方法在shell中体现的比较多,在dos命令行中也可以执行,下面就以在do ...
- 高可用集群(HA)之Keeplived原理+配置过程
原理--> 通过vrrp协议,定义虚拟路由,在多个服务节点上进行转移. 通过节点优先级,将初始虚拟路由到优先级高的节点上,checker工作进程检测到主节点出问题时,则降低此节点优先级,从而实现 ...
- TeamTalk自定义IM协议的理解
一.TeamTalk自定义IM协议 TeamTalk自定义IM协议是一种基于protocol buffer的消息传递协议,protocol buffer可以自定义消息格式.protocol buffe ...
- 常见的SQL字符串函数
1.LEN:计算字符串的长度(字符的个数) select len('哈哈hello') 返回长度为7 2.datalength();计算字符串所占用的字节数,不属于字符串函数 select DATAL ...
- g++ error: extra qualification on member [-fpermissive]
以下这段代码是在头文件里面的,DmaOpen DmaClose函数也是直接在class pcie_chip{}里面的.加了个额外的pcie_chip::才会报错. //delete pcie_chip ...