现在的位置: 首页 > 综合 > 正文

Java – interface02

2013年09月22日 ⁄ 综合 ⁄ 共 3453字 ⁄ 字号 评论关闭

群组常量

接口中的字段自动是public的,同时也自动是staticfinal的,所以接口就成为了一种很便捷的用来创建常量组的工具(Java中标识有static final时,使用大写字母的风格,并在一个标识符中用下划线来分割多个单词)

/**
 * Title: About constants in interfaces<br>
 * Description: Using interfaces to create groups of constants<br>
 * Company: Augmentum Int<br>
 * Copyright: 2008 (c) Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;
public interface Months {
    
int JANUARY = 1, FEBRUARY = 2, MARCH = 3, APRIL = 4, MAY = 5, JUNE = 6
        JULY 
= 7, AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, NOVEMBER = 11, DECEMBER = 12;
}

我们可以使用包外部的常量,其方式是先导入com.augmentum.foresthe(就像导入其他包一样),然后用诸如Months.JANUARY这样的表达式来引用它的值。当然所获得的只是一个int值,并没有额外的类型安全,但是这项被广泛应用的技术比起在程序中硬编码数字显然是一种提高(硬编码数字的方式通常被称为“魔幻数字”,它会产生难以维护的代码)

如果想要额外的类型安全,那么可以像下面这样构建类:

/**
 * Title: About constants in interfaces<br>
 * Description: Using interfaces to create groups of constants<br>
 * Company: Augmentum Int<br>
 * Copyright: 2008 (c) Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;
public final class Month {
    
private String name;
    
private Month(String name) this.name = name; }
    
public String toString() return name; }
    
private static final Month
        JAN 
= new Month("January"), FEB = new Month("February"),
        MAR 
= new Month("March"), APR = new Month("April"),
        MAY 
= new Month("May"), JUN = new Month("June"),
        JUL 
= new Month("July"), AUG = new Month("August"),
        SEP 
= new Month("September"), OCT = new Month("October"),
        NOV 
= new Month("November"), DEC = new Month("December");
    
private static final Month[] month = {
        JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
    }
;
    
public static final Month getMonth(int ord) return month[ord - 1]; }
    
public static void main(String[] args) {
        Month month 
= Month.APR;
        System.out.println(month);
        month 
= getMonth(10);
        System.out.println(month);
        System.out.println(month 
== Month.OCT);
        System.out.println(month.equals(Month.OCT));
    }

}

Month是一个具有private构造器的final类,所以无法继承它,也无法创建它的任何实例。所有的实例都是在该类内部由其自身创建的final static实例:JANFEBMAR等。这些对象会在month数组中用到,该数组允许你遍历一个由Month对象构成的数组。在main()中可以看到类型安全性:m是一个Month对象,因此它仅仅可以被赋予一个Month值;而前面的例子Months.java仅提供了int值,因此用来表示月份的int变量实际上可以被赋予任何整数值,这就不是很安全了。

补充:在java.util.Calendar中也有一个表示月份的字段;ApacheJakarta Commons项目包含了用来创建枚举类型的工具。

初始化接口中的字段

在接口中定义的字段自动是staticfinal的。它们不能是“空final”,但是可以被非常量表达式初始化。

/**
 * Title: Initializing interface<br>
 * Description: Initializing interface fields with non-constant initializers<br>
 * Company: Augmentum Int<br>
 * Copyright: 2008 (c) Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;
import java.util.Random;
public interface RandVals {
    Random rand 
= new Random();
    
int randomInt = rand.nextInt(100);
    
long randomLong = rand.nextLong();
    
float randomFloat = rand.nextFloat();
    
double randomDouble = rand.nextDouble();
}

/*既然字段是static的, 它们就可以在类第一次被加载时初始化, 这发生在任何字段首次被访问时.*/
class TestRandVals {
    
public static void main(String[] args) {
        System.out.println(RandVals.randomInt);
        System.out.println(RandVals.randomLong);
        System.out.println(RandVals.randomFloat);
        System.out.println(RandVals.randomDouble);
    }

}

当然了,这些字段不是接口的一部分,只是被存储在该接口的静态存储区域内。

嵌套接口,可参见InnerClass

和非嵌套接口一样,可以拥有public和“包访问”两种可视性;并且可以被实现为public、包访问和private的嵌套类(实现一个private接口只是一种方式,它可以强制该接口中的方法定义不要添加任何类型信息,即不允许向上转型)

抱歉!评论已关闭.