“实现”below是否意味着对象的实例?也许它们意味着实施代码。
考虑添加静态接口方法,以允许客户端代码 创建(可能是专门的)实现接口的对象。 例如,如果我们有一个带有两个方法的接口Point int x() 和int y(),然后我们可以暴露一个静态方法Point.of(int x,int y) 这会产生一个(隐藏的)接口实现。
因此,如果x和y都为零,我们可以返回一个特殊的实现 class PointOrigoImpl(没有x或y字段),否则我们返回 另一个包含给定x和y值的PointImpl类。确保 实现类在另一个包中 显然不是API的一部分(例如,将Point接口放入 com.company。 product.shape和中的实现 com.company.product.internal.shape)。
执行此操作:
Point point = Point.of(1,2);
不要这样做:
Point point = new PointImpl(1,2);
这样做的好处是强制执行封装?但是,如果实现是包私有而不是API的一部分,那是否会产生访问问题?如果客户端,“世界”如下:
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
无法访问Point
的实现,那么如何为“执行此操作”实例化新的Point
?
答案 0 :(得分:2)
例如,如果我们有一个带有两个方法的接口Point int x() 和int y(),然后我们可以暴露一个静态方法Point.of(int x,int y) 这会产生一个(隐藏的)接口实现。
1)请注意,从Java 8开始,您可以在界面中添加静态方法,但在您不能之前。
2)我很难理解这个建议:
因此,如果x和y都为零,我们可以返回一个特殊的实现 class PointOrigoImpl(没有x或y字段),否则我们返回 另一个包含给定x和y值的PointImpl类。确保 实现类在另一个包中 显然不是API的一部分(例如,将Point接口放入 com.company。 product.shape和中的实现 com.company.product.internal.shape)。
以下是与您引用的文本匹配的示例Point
类:
package com.company.product.shape;
import com.company.product.internal.shape.PointOrigoImpl;
import com.company.product.internal.shape.PointImpl;
public interface Point{
int x();
int y();
static Point of(int x, int y) {
if (x == 0 && y == 0){
return new PointOrigoImpl();
}
return new PointImpl(x, y);
}
}
如果向客户端提供Point
接口并且它声明了工厂方法,那么要编译正常,Point
接口必须具有PointOrigoImpl
和{{1}的可见性为了实例化它们的类。
由于PointImpl
接口和子类位于两个不同的包中(Point
和com.company.product.shape
),
这意味着com.company.product.internal.shape
和PointImpl
应该有一个公共构造函数,否则PointOrigoImpl
无法实例化它们。
最后,操纵Points的客户端也可以实例化Point
和PointImpl
子类的构造函数。
它违背了工厂的目的,该工厂不希望公开实施以选择自己的实施方式返回。
界面是公开的,旨在让客户完全可以访问 因此,作为一般规则,它不应包含我们不希望向客户公开的实现。
3)这里:
这样做的好处是强制执行封装?但是,如果 实现是包私有而不是API的一部分,那样做 不创建访问问题?如果客户,"世界"在这里: 无法访问Point的实现,那么它怎么可能 可能会实例化一个新的Point,如上所述"执行此操作"?
我想你想知道为什么文字说: 确保实现类位于另一个明显不属于API 的包中。
在您所引用的文本中,作者希望让PointOrigoImpl
客户知道界面,但他不想知道Point
的子类,因为他想要决定根据工厂Point中使用的参数返回点子类。
点客户端只会知道此界面。
在Java中,为了不提供对实现类的访问,您可以使用公共类,接口和内部私有类:
根据你提到的例子,它会是直的。
点(界面):
Point
Point factory(包含私有类的公共类):
public interface Point{
int x();
int y();
}
答案 1 :(得分:1)
好PointImpl
也可以使用公开的API来创建自己,可能是PointImpl.create(int x, int y)
和PointOrigoImpl.create()
的形式。由于它们都在内部包中,因此它们可以是公开的,Point.of
可以自由使用它们,而技术上“隐藏”给API的用户,因为它们在com.company.product.internal.shape
中残留。
当然,这是善意的,程序员不会滥用PointImpl.create
而不是Point.of
,但这是正常的。如果程序员想要打破封装(或需要打破封装),那么无论如何都不会阻止他(因为它应该是这样)。
答案 2 :(得分:0)
如果客户端“world”无法访问Point的实现,那么它怎么可能像上面那样为“执行此操作”实例化一个新的Point?
客户端不需要实例化,因为实例化发生在<div ui-view ng-controller="SteppersDemoCtrl as vm" layout="column">
.....................................................
.....................................................
<button ng-click="vm.nextStep();">Continue</button>
本身。作为接口Point
的实现implements
,客户端应该可以访问Point
的所有可公开访问的方法,并且客户端可以随时使用这些方法。