Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在没有实现的情况下向公共API公开枚举?_Java_Api_Enums_Api Design - Fatal编程技术网

Java 如何在没有实现的情况下向公共API公开枚举?

Java 如何在没有实现的情况下向公共API公开枚举?,java,api,enums,api-design,Java,Api,Enums,Api Design,我有一个类,它有一个类型为枚举的属性。例如: enum CarType { TOYOTA("Japan"), AUDI("Germany"), BMW("Germany"); public final String country; private CarType(String country) { this.country = country; } } class Car { private CarType type; public

我有一个类,它有一个类型为枚举的属性。例如:

enum CarType {
    TOYOTA("Japan"),
    AUDI("Germany"),
    BMW("Germany");

    public final String country;
    private CarType(String country) { this.country = country; }
}

class Car {
    private CarType type;
    public CarType getType() { return type; }
}
Car
是库的一部分,我想公开它的功能,所以我创建了一个接口,它将成为公共API的一部分,并让类
Car
实现它:

interface ICar {
    CarType getType();
}

class Car implements ICar {
    private CarType type;
    @Override public CarType getType() { return type; }
}
这种方法的问题是,这将需要发布整个
CarType
enum。
CarType
enum可能包含我不想公开/发布的其他属性和方法(
country

如果我想隐藏
CarType
的实现,但我仍然想以某种方式公开可能的值(声明的枚举值),以便API用户可以在
switch
if
语句中引用它们,我该怎么办

ICar car = ...; // Get an instance somehow.
if (car.getType() == CarType.TOYOTA) System.out.println("It's Toyota.");
使附加属性和方法
受保护
私有
不是一个好的解决方案,因为这样库的其他部分也无法引用它们


如果我想继续使用enum,有什么好的替代方法来解决这个问题吗?

受保护的
私有的
包私有的
是为此提供的主要工具。如果您充分考虑您的类层次结构,您可能可以使用它们做一些事情


你应该考虑作文。拥有一个
TypeDetails
类,并让
CarType
的每个成员都包含一个
TypeDetails
成员。然后,您可以将对
TypeDetails
getter的访问限制为只有那些在库的所有部分都可以看到
TypeDetails
的同时应该访问它的人。

如果必须将
country
属性隐藏到用户代码中,您可以使用标准可见性(声明的属性没有
public
protected
private
限定符,这些属性只对同一包中的类可见)。我希望这会有用,但我知道这只是一个补丁


无论如何,我无法完全理解您的设计和必要性,因此您可能没有其他选择,但如果您想保护代码不被API滥用,您可能需要重新设计并考虑封装问题。您可以为公共API提供枚举,并将其转换为另一个枚举以供私人使用。
例如,使用一个映射,其中键是公共枚举实例和值-私有枚举实例。

问题是每次调用API时都必须转换数据。可能需要在许多地方进行更改。

尽管有一位后来的人想补充我的想法-

枚举还可以实现一个接口,在该接口中,您可以仅公开所需的详细信息:

 public enum CarType implements ICarType {
     ...
      public String getTypeName(){
        return name();
      }
   }

   public interface ICarType {
      public String getTypeName();
   }
所以您计划在if()/switch中使用它


问题中提到的问题是,枚举是从库的多个包中使用的,因此无法降低附加属性和方法的可见性。也许可以尝试使用getter方法公开属性,甚至返回防御副本,以防滥用?如果不是这样的话首先,我担心您需要重新设计您的库,严格区分API用户可见的私有逻辑和公共DTO。该属性只是一个示例(比方法短),但同样的可见性也适用于方法。最初的问题来自我想使用枚举,而枚举无法扩展您自己的类。使用类层次结构,这不会是一个问题(我可以发布祖先类并将子类隐藏在公共API中)。枚举是从库的多个包中使用的,因此我无法降低可见性。这意味着组合也不是一个好的解决方案(因为它使用受限访问)。我之所以接受这个答案,是因为我提到我希望它作为枚举发布,没有其他方法。尽管我选择了另一条路径,因为我想公开一些附加功能(但不是全部),显然不希望复制附加功能。相反,我将枚举公开为接口,其中我要发布的附加功能是接口的一部分,枚举常量也列为接口常量。此解决方案还避免了进行转换和更改实现。
  ICarType carType; //Not referencing the enum

  if("TOYOTA".equalsIgnoreCase(carType.getTypeName())){
     print("Toyota....");
  }