一、混型
①、定义
二、利用JAVA如何实现混型
①、代理 ②、装饰器模式 ③、动态代理模式 ④、装饰器模式与代理模式的区别
三、潜在类型机制
①、定义
四、JAVA的潜在类型机制的补偿
①、实现类与类之间的方法共用(反射机制)。。。讲述其使用过程。。。及其缺点
②、实现序列(List,Queue)之间方法的共用。。。讲述其使用过程。。。及其缺点
③、实现Collection之间方法的共用。。。讲述其使用过程。。。及其缺点
④、实现一般化的方法共用(适配器模式)。。。讲述其使用过程。。及其缺点
⑤、实现优雅的一般化的方法共用(策略模式)。。。讲述其使用过程。。。
回答:
一、混型
就是一个类混合了多个类的能力。 当想在混型类中修改某些东西,这些修改会应用于混型的所有类型上。
二、实现混型
①、代理机制
步骤:1、创建混型接口 2、创建接口的具体实现 3、创建混型类,类中持有混型。
首先 创建混型接口
public interface Fly{ void fly(); }
其次,创建接口的具体实现
public Swing implements Fly{ public void fly(){ System.out.println("I can use swing to fly"); } }
最后创建具体混型类
public class Duck implements Fly{ private Swing mSwim = new Swing(); public void fly(){ mSwim.fly(); } public void swim(){ System.out.println("I can swim"); } }
缺点:当使用复杂的混型,代码量会急剧上升。
②、装饰器模式
步骤:1、创建被装饰对象(可以是类也可以是接口,最好是接口 这里我用的是接口) 2、创建被装饰对象继承装饰接口 3、创建装饰器(装饰器中包含装饰对象)
1、创建装饰接口
public interface Basket { void show(); }
2、继承装饰接口,为被装饰对象
public class Original implements Basket{ @Override public void show() { // TODO Auto-generated method stub System.out.println("I am a Basket"); } }
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"); } }
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"); } }
其他略
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(); } }
缺点:只有效作用于装饰的最后一层。
③、动态代理
步骤:1、创建接口 2、创建接口的具体实现 3、创建Proxy类 4、使用Proxy类
①、创建接口
public interface Business { void doSomething(); void doSomeElse(); }
②、实现接口
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); } }
③、创建代理类
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); } }
④、启动代理
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(); } }
④、
装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。当我们使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
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; } }
public class TypeTwo { private int data = 2; public void setData(int data){ this.data = data; } public int getData(){ return data; } }
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(); } } }
缺点:只能在类与类之间使用。
②、序列中调用相同的方法
步骤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(); } } } }
步骤2、创建调用对象
public class Apple { private static int count = 1; private final int id = count++; public void getId(){ System.out.println(id); } }
步骤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(); } }
个人理解:就是将传入的参数变成了迭代器而已。
缺点:只能在含迭代器的序列中使用。
③、在Colleciotn中调用add()方法
同:只是将传入的参数直接变成Collection了而已
④、通过适配器使用潜在类型
步骤1、创建适配的接口
public interface Addable<T> { void add(T data); }
步骤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); } }
步骤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); } } }
⑤、通过策略模式一般化潜在类型
步骤1、创建策略接口
步骤2、继承策略接口
步骤3、创建功能类
步骤4、调用
个人理解:策略接口的具体实现就是Collection类中对象共有的方法。 功能类的方法,就是对共有方法的调用。