Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ITEM 22 仅仅使用接口来定义类型 #10

Open
XYliang opened this issue Jul 18, 2018 · 0 comments
Open

ITEM 22 仅仅使用接口来定义类型 #10

XYliang opened this issue Jul 18, 2018 · 0 comments

Comments

@XYliang
Copy link
Owner

XYliang commented Jul 18, 2018


更多链接

###Item 22 仅仅使用接口来定义类型

当一个类实现了一个接口时,这个接口就被当作一个可以引用该类对象的类型在使用。因此类实现了哪个接口,就能调用哪个接口的方法。
用接口类定义其他事情都是不恰当。
有一种失败的接口是常量接口。这样的接口没有包含任何方法,仅仅包含一些static final的常量。这里有个例子:

//常量接口反例-不要这样用
public interface PhysicalConstants {
    // Avogadro's number (1/mol)
    static final double AVOGADROS_NUMBER =
            6.022_140_857e23;
    // Boltzmann constant (J/K)
    static final double BOLTZMANN_CONSTANT =
            1.380_648_52e-23;
    // Mass of the electron (kg)
    static final double ELECTRON_MASS = 9.109_383_56e-31;
}

这个常量接口是对接口的不良用法。类使用的什么常量属于内部的实现细节。但是当类实现一个常量接口时,就会导致类的内部实现细节被暴漏到类导出的API中。对用户来说,类实现常量接口不但用处不大而且容易造成混乱。更糟糕的是,常量接口代表了一个承诺:如果将来类被修改成不再需要使用这些常量,但它为了二进制兼容还必须继续实现这个接口,这很痛苦。如果一个非final的类实现了常量接口,那么它子类的命名空间就可能被这些常量污染。
在JAVA平台库中有几个常量接口存在,例如java.io.ObjectStreamConstants.这些接口应该被视为不规则的不应该被效仿的接口。
如果你想导出常量,有几种合理的选择。

  • 如果常量与现有的类或者接口强关联,那么你应该把他们添加到这个类和接口上。例如,所有的原始数值包装类中,像Integer和Double,都导出了MIN_VALUE和MAX_VALUE常量。
  • 如果常量是被当作枚举使用的,那么你就应该把常量导出成一个enum类型(Item34)。
  • 否则,你应该导出一个不可实例化的工具类包含这些常量(Item4)。例如前面的例子:
	package com.effectivejava.science;
    public class PhysicalConstants {
        private PhysicalConstants() { } // Prevents instantiation
        public static final double AVOGADROS_NUMBER =
                6.022_140_857e23;
        public static final double BOLTZMANN_CONST =
                1.380_648_52e-23;
        public static final double ELECTRON_MASS =
                9.109_383_56e-31;
    }

顺便说一下,注意在上面的数字中使用的下划线(_),从Java7开始是合法的使用,添加下划线不会影响数字的值,而且能使数字的可读性更强。无论是整数还是小数,当数字个数超过5个的时候,你都可以每3个分成一组来划分。

通常使用工具类调用常量时要求用类名.常量名,例如PhysicalConstants.AVOGADROS_NUMBER.但是如果你大量的使用常量时,可以通过导入工具类来直接使用常量:

	import static com.effectivejava.science.PhysicalConstants.*;
	
    public class Test {
        double atoms(double mols) {
            return AVOGADROS_NUMBER * mols;
        }
		...
		// Many more uses of PhysicalConstants justify static import
    }

总结:接口应该仅被用于定义类型,而不应该用于仅仅导出常量。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant