Art*_*tur 2 java factory interface abstract
ExecutorService和Service是接口,因此只有抽象方法,这意味着它们的方法没有实现.我们再怎么称呼,例如future.get(),es.submit()和es.shutdown()方法的接口类型的参考?例如,我们为什么要这样做呢?
Future f = ...
f.get();
Run Code Online (Sandbox Code Playgroud)
这是一个更具体的例子:
import java.util.concurrent.*;
class Factorial implements Callable<Long> {
long n;
public Factorial(long n) {
this.n = n;
}
public Long call() throws Exception {
if (n <= 0) {
throw new Exception("for finding factorial, N should be > 0");
}
long fact = 1;
for(long longVal = 1; longVal <= n; longVal++) {
fact *= longVal;
}
return fact;
}
}
class CallableTest {
public static void main(String []args) throws Exception {
long N = 20;
Callable<Long> task = new Factorial(N);
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Long> future = es.submit(task);
System.out.printf("factorial of %d is %d", N, future.get());
es.shutdown();
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题得到了一些贬低,因为从某种意义上来说它是基本的,但我认为它实际上有点有趣.毕竟,像Executors您的示例中的工厂类可以指定它返回Executors.但是,正如您所指出的那样,这只是一个接口,如果您能够调用这些方法,您实际上需要一个实现 的实例Executor.为什么工厂不必告诉我们返回的实际类型?
如果您以前没有看过这个,可能不清楚如何做这样的事情.需要记住的重要一点是,如果您有一个实现接口的类,那么声明为返回接口类型的方法可以返回该类的实例.也就是说,你可以这样做:
interface Foo { /* ... */ }
class Bar implements Foo { /* ... */ }
class Factory {
Foo makeFoo() {
return new Bar( /*... */ );
}
}
Run Code Online (Sandbox Code Playgroud)
makeFoo声明返回a Foo,但是Foo是一个接口; 你实际上不能拥有它的实例.您只能拥有实现 的类的实例Foo. Bar确实实现了Foo,所以你可以返回一个实例Bar.
我们可以这样做的原因是,当调用对象上的方法时,该方法的实现可以在我们引用的实际对象中找到.查找方法的方式实际上有点复杂.从概念上讲,你可能会这样想:如果你告诉我你是一个Foo,那么我可以要求你运行任何声明的方法Foo,但你可以确切地决定你为这个方法做些什么.我只能使用你的Foo类型来确定我可以要求你执行的方法.这非常重要,这也是我们可以覆盖子类中的方法的原因.这些被称为虚拟方法.其中一个重要原因是,它使我们能够使用接口,我们可以显示有关我们实现的最少量信息(我们可以选择说"我实施Foo,但这就是我告诉你的关于我自己的事情"),但仍然遵守合同(即,我保证实际实现所有声明的方法Foo).
以下示例更深入一些,并捕获了您看到的工厂模式的更多信息Executors.
public class InterfacesExample {
/**
* An interface with one method.
*/
interface Frobber {
/**
* Frob the object.
* @param object the object
*/
void frob( Object object );
}
/**
* A factory class with one method for creating printing frobber.
*/
public static class Frobbers {
/**
* Returns a Frobber whose {@link Frobber#frob(Object)} method
* prints its argument
* @return a printing Frobber
*/
public static Frobber newPrintingFrobber() {
// This returns an instance of an anonymous class
// that implements the Frobber interface. It has
// to provide an implementation of frob(Object),
// though.
return new Frobber() {
@Override
public void frob( final Object object ) {
System.out.println( "Frobbing "+object+"..." );
}
};
}
/**
* Returns a Frobber whose {@link Frobber#frob(Object)} method
* prints the prefix and its argument
* @param prefix an object
* @return a prefixing printing Frobber
*/
public static Frobber newPrefixingPrintingFrobber( final Object prefix ) {
return new PrefixingPrintingFrobber( prefix );
}
/**
* A private, but not anonymous class. Instances shouldn't be
* made with its constructor, but rather through the factory
* method {@link Frobbers#newPrefixingPrintingFrobber(Object)}.
*/
private static class PrefixingPrintingFrobber implements Frobber {
final Object prefix;
public PrefixingPrintingFrobber( Object prefix ) {
this.prefix = prefix;
}
@Override
public void frob( final Object object ) {
System.out.println( "Frobbing "+prefix+":"+object+"..." );
}
}
}
/**
* Create some frobbers with the factory and test them out.
*/
public static void main( final String[] args ) {
final Frobber f1 = Frobbers.newPrintingFrobber();
f1.frob( 42 );
final Frobber f2 = Frobbers.newPrefixingPrintingFrobber( "boing" );
f2.frob( 36 );
}
}
Run Code Online (Sandbox Code Playgroud)
Frobbing 42...
Frobbing boing:36...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |