Java:如何声明变量实现接口?

Java:如何声明变量实现接口?,java,generics,interface,duck-typing,dynamic-typing,Java,Generics,Interface,Duck Typing,Dynamic Typing,在Objective-C中,我可以做到: id<HTTPRequestDelegate> delegate; id代表; 表示delegate(类型为id的变量)符合HTTPRequestDelegate协议(或用Java语言实现HTTPRequestDelegate接口) 这样,每当我将HTTPRequestDelegate协议定义的消息发送到delegate时,编译器就知道delegate会响应 如何在Java中实现这一点,即/dynamic typing?我认为这里有很多术

在Objective-C中,我可以做到:

id<HTTPRequestDelegate> delegate;
id代表;
表示
delegate
(类型为
id
的变量)符合
HTTPRequestDelegate
协议(或用Java语言实现
HTTPRequestDelegate
接口)

这样,每当我将
HTTPRequestDelegate
协议定义的消息发送到
delegate
时,编译器就知道
delegate
会响应


如何在Java中实现这一点,即/dynamic typing?

我认为这里有很多术语需要解释。Java不允许有原始指针,只允许有类型的引用

Interface a = new Implementation();
无论如何,假设您有一个实例的引用,您知道该实例实现了
HTTPRequestDelegate
。你可以这样施展:

HTTPRequestDelegate delegate = (HTTPRequestDelegate) ref;
括号中的位是转换。现在,只要在
HTTPRequestDelegate
上定义了方法,您就可以调用
delegate
(用java语言传递消息)上的方法来传递您的内容


Java程序员处理duck类型的另一种方法是refection,但是如果您知道接口,那么casing就是一种方法

Java没有duck类型的概念。必须将实例强制转换为已知类型。

Java中不存在Duck类型。如果一个类实现了一个接口,它必须声明该接口已实现。仅仅拥有与接口中具有相同签名的方法是不够的

不过,接口是一种类型,您可以声明这种类型的变量。例如:

List<String> myList;

但是,
ArrayList
必须声明它实现了
List
接口(它确实实现了)。

我假设委托没有显式地实现您想要的接口

您可以创建一个新类来实现接口并扩展所需的实现类(或者拥有实现类并显式调用接口中的相应方法)

如果这不是你想要的,你可能会进行健康的反思。看看java.lang.reflect.Proxy和InvocationHandler

如果您正在寻找一种简写方法来避免使用组合显式地实现接口的方法,那么Java实际上并没有为此提供语法支持。你必须直言不讳


如果你真的想进行大量的思考(不建议额外键入),请查看Mockito。

给出的大多数答案都是正确的。如果一个对象实现了一个接口,那么您可以在任何需要该接口实现的地方使用该对象。考虑到Java强大的类型系统,这是最自然的方法

为了与
列表
/
数组列表
的示例保持一致,您可以创建
数组列表
对象,然后在需要
列表
的任何位置使用它——或者,基于其他实现的接口,
可序列化
可克隆
可编辑
集合
,或
随机访问
。考虑到超类,
ArrayList
的实例可以用作
AbstractList
AbstractCollection
,或
java.lang.Object

反射可以与动态代理对象一起使用,以正确的方法将对象楔入鸭子服装中。这就把类型检查转移到了运行时,通常有更好的理由使用普通的类型系统,而不是反对它

因为这听起来很有趣,这里有一个在代理对象中包装非Duck的示例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DuckDemo {
    public static Duck getDuckProxy(final Object duckLike) {
        final InvocationHandler invocationHandler = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Class<?> actualClass = duckLike.getClass();
                String methodName = method.getName();
                Class[] parameterTypes = method.getParameterTypes();

                Method requested = actualClass.getDeclaredMethod (methodName, parameterTypes);

                return requested.invoke(duckLike, args);
            }
        };

        final ClassLoader originalObjectClassLoader = duckLike.getClass().getClassLoader();
        Duck woodenDuck = (Duck) Proxy.newProxyInstance(
                originalObjectClassLoader,
                new Class[] { Duck.class },
                invocationHandler
        );

        return woodenDuck;
    }

    private interface Duck {
        void quack();
    };

    public static void makeItQuack (Duck duck) {
        duck.quack();
    }

    public static void main (String args[]) {
        Object quacksLikeADuck = new Object() {
            void quack() {
                System.out.println ("Quack!");
            }
        };

        // Does not compile -- makeItQuack(DuckDemo.Duck) [...] cannot be applied to (java.lang.Object)
        // makeItQuack (quacksLikeADuck);

        // Runtime java.lang.ClassCastException: [...] cannot be cast to GenericProxyFactory$Duck
        // makeItQuack ((Duck)quacksLikeADuck);

        Duck d = getDuckProxy(quacksLikeADuck);

        makeItQuack (d);
    }
}
import java.lang.reflect.InvocationHandler;
导入java.lang.reflect.Method;
导入java.lang.reflect.Proxy;
公开课演示{
公共静态Duck getDuckProxy(最终对象duckLike){
final InvocationHandler InvocationHandler=new InvocationHandler(){
公共对象调用(对象代理、方法、对象[]args)抛出Throwable{
类actualClass=duckLike.getClass();
String methodName=method.getName();
类[]parameterTypes=method.getParameterTypes();
请求的方法=actualClass.getDeclaredMethod(方法名,参数类型);
请求返回。调用(duckLike,args);
}
};
最终类加载器originalObjectClassLoader=duckLike.getClass().getClassLoader();
Duck woodenDuck=(Duck)Proxy.newProxyInstance(
originalObjectClassLoader,
新类[]{Duck.Class},
调用处理程序
);
返回伍登杜克;
}
专用接口鸭{
虚无庸医();
};
公共静态void makeItQuack(Duck-Duck){
鸭子;
}
公共静态void main(字符串参数[]){
Object quacksLikeADuck=新对象(){
虚无庸医{
System.out.println(“嘎嘎!”);
}
};
//不编译--makeItQuack(DuckDemo.Duck)[…]不能应用于(java.lang.Object)
//使嘎嘎(嘎嘎)作响;
//运行时java.lang.ClassCastException:[…]无法强制转换为GenericProxyFactory$Duck
//使嘎嘎((鸭子)嘎嘎嘎嘎);
Duck d=getDuckProxy(quacksLikeADuck);
马克奎克(d);
}
}

值得一提的是,IBM developerWorks还提供了一个关于动态代理主题的示例。

在Objective-C中,该类型由两部分组成:1)类指针类型(例如,
NSObject*
NSString*
等);这也可以是
id
,它是一种特殊类型,可以接受任何对象指针并禁用静态类型编译器对调用方法的警告;和2)可选地,对象符合的一个或多个协议(类似于Java中的接口)(例如

在Java中,引用类型是类或接口名。(您只能选择
myList = new ArrayList<String>();
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DuckDemo {
    public static Duck getDuckProxy(final Object duckLike) {
        final InvocationHandler invocationHandler = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Class<?> actualClass = duckLike.getClass();
                String methodName = method.getName();
                Class[] parameterTypes = method.getParameterTypes();

                Method requested = actualClass.getDeclaredMethod (methodName, parameterTypes);

                return requested.invoke(duckLike, args);
            }
        };

        final ClassLoader originalObjectClassLoader = duckLike.getClass().getClassLoader();
        Duck woodenDuck = (Duck) Proxy.newProxyInstance(
                originalObjectClassLoader,
                new Class[] { Duck.class },
                invocationHandler
        );

        return woodenDuck;
    }

    private interface Duck {
        void quack();
    };

    public static void makeItQuack (Duck duck) {
        duck.quack();
    }

    public static void main (String args[]) {
        Object quacksLikeADuck = new Object() {
            void quack() {
                System.out.println ("Quack!");
            }
        };

        // Does not compile -- makeItQuack(DuckDemo.Duck) [...] cannot be applied to (java.lang.Object)
        // makeItQuack (quacksLikeADuck);

        // Runtime java.lang.ClassCastException: [...] cannot be cast to GenericProxyFactory$Duck
        // makeItQuack ((Duck)quacksLikeADuck);

        Duck d = getDuckProxy(quacksLikeADuck);

        makeItQuack (d);
    }
}
HTTPRequestDelegate delegate;