// interfaces/AttemptToUseBasic.java
// {WillNotCompile}
public class AttemptToUseBasic {
Basic b = new Basic();
// error: Basic is abstract; cannot be instantiated
}
// interfaces/AbstractWithoutAbstracts.java
abstract class Basic3 {
int f() {
return 111;
}
// No abstract methods
}
public class AbstractWithoutAbstracts {
// Basic3 b3 = new Basic3();
// error: Basic3 is abstract; cannot be instantiated
}
为了创建可初始化的类,就要继承抽象类,并提供所有抽象方法的定义:
// interfaces/Instantiable.java
abstract class Uninstantiable {
abstract void f();
abstract int g();
}
public class Instantiable extends Uninstantiable {
@Override
void f() {
System.out.println("f()");
}
@Override
int g() {
return 22;
}
public static void main(String[] args) {
Uninstantiable ui = new Instantiable();
}
}
// interfaces/AnImplementation.java
public class AnImplementation implements AnInterface {
public void firstMethod() {
System.out.println("firstMethod");
}
public void secondMethod() {
System.out.println("secondMethod");
}
public static void main(String[] args) {
AnInterface i = new AnImplementation();
i.firstMethod();
i.secondMethod();
}
}
AnImplementation.java:3:error: AnImplementation is not abstract and does not override abstract method newMethod() in AnInterface
public class AnImplementation implements AnInterface {
^
1 error
// interfaces/Applicator.java
import java.util.*;
class Processor {
public String name() {
return getClass().getSimpleName();
}
public Object process(Object input) {
return input;
}
}
class Upcase extends Processor {
// 返回协变类型
@Override
public String process(Object input) {
return ((String) input).toUpperCase();
}
}
class Downcase extends Processor {
@Override
public String process(Object input) {
return ((String) input).toLowerCase();
}
}
class Splitter extends Processor {
@Override
public String process(Object input) {
// split() divides a String into pieces:
return Arrays.toString(((String) input).split(" "));
}
}
public class Applicator {
public static void apply(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}
public static void main(String[] args) {
String s = "We are such stuff as dreams are made on";
apply(new Upcase(), s);
apply(new Downcase(), s);
apply(new Splitter(), s);
}
}
输出:
Using Processor Upcase
WE ARE SUCH STUFF AS DREAMS ARE MADE ON
Using Processor Downcase
we are such stuff as dreams are made on
Using Processor Splitter
[We, are, such, stuff, as, dreams, are, made, on]
// interfaces/interfaceprocessor/StringProcessor.java
// {java interfaces.interfaceprocessor.StringProcessor}
package interfaces.interfaceprocessor;
import java.util.*;
interface StringProcessor extends Processor {
@Override
String process(Object input); // [1]
String S = "If she weighs the same as a duck, she's made of wood"; // [2]
static void main(String[] args) { // [3]
Applicator.apply(new Upcase(), S);
Applicator.apply(new Downcase(), S);
Applicator.apply(new Splitter(), S);
}
}
class Upcase implements StringProcessor {
// 返回协变类型
@Override
public String process(Object input) {
return ((String) input).toUpperCase();
}
}
class Downcase implements StringProcessor {
@Override
public String process(Object input) {
return ((String) input).toLowerCase();
}
}
class Splitter implements StringProcessor {
@Override
public String process(Object input) {
return Arrays.toString(((String) input).split(" "));
}
}
输出:
Using Processor Upcase
IF SHE WEIGHS THE SAME AS A DUCK, SHE'S MADE OF WOOD
Using Processor Downcase
if she weighs the same as a duck, she's made of wood
Using Processor Splitter
[If, she, weighs, the, same, as, a, duck,, she's, made, of, wood]
// interfaces/Adventure.java
// Multiple interfaces
interface CanFight {
void fight();
}
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
class ActionCharacter {
public void fight(){}
}
class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly {
public void swim() {}
public void fly() {}
}
public class Adventure {
public static void t(CanFight x) {
x.fight();
}
public static void u(CanSwim x) {
x.swim();
}
public static void v(CanFly x) {
x.fly();
}
public static void w(ActionCharacter x) {
x.fight();
}
public static void main(String[] args) {
Hero h = new Hero();
t(h); // Treat it as a CanFight
u(h); // Treat it as a CanSwim
v(h); // Treat it as a CanFly
w(h); // Treat it as an ActionCharacter
}
}
error: C5 is not abstract and does not override abstract
method f() in I1
class C5 extends C implements I1 {}
error: types I3 and I1 are incompatible; both define f(),
but with unrelated return types
interfacce I4 extends I1, I3 {}
// interfaces/RandomStrings.java
// Implementing an interface to conform to a method
import java.nio.*;
import java.util.*;
public class RandomStrings implements Readable {
private static Random rand = new Random(47);
private static final char[] CAPITALS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final char[] LOWERS = "abcdefghijklmnopqrstuvwxyz".toCharArray();
private static final char[] VOWELS = "aeiou".toCharArray();
private int count;
public RandomStrings(int count) {
this.count = count;
}
@Override
public int read(CharBuffer cb) {
if (count-- == 0) {
return -1; // indicates end of input
}
cb.append(CAPITALS[rand.nextInt(CAPITALS.length)]);
for (int i = 0; i < 4; i++) {
cb.append(VOWELS[rand.nextInt(VOWELS.length)]);
cb.append(LOWERS[rand.nextInt(LOWERS.length)]);
}
cb.append(" ");
return 10; // Number of characters appended
}
public static void main(String[] args) {
Scanner s = new Scanner(new RandomStrings(10));
while (s.hasNext()) {
System.out.println(s.next());
}
}
}
因为接口中的字段都自动是 static 和 final 的,所以接口就成为了创建一组常量的方便的工具。在 Java 5 之前,这是产生与 C 或 C++ 中的 enum (枚举类型) 具有相同效果的唯一方式。所以你可能在 Java 5 之前的代码中看到:
// interfaces/Months.java
// Using interfaces to create groups of constants
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;
}
注意 Java 中使用大写字母的风格定义具有初始化值的 staticfinal 变量。接口中的字段自动是 public 的,所以没有显式指明这点。
// interfaces/nesting/NestingInterfaces.java
// {java interfaces.nesting.NestingInterfaces}
package interfaces.nesting;
class A {
interface B {
void f();
}
public class BImp implements B {
@Override
public void f() {}
}
public class BImp2 implements B {
@Override
public void f() {}
}
public interface C {
void f();
}
class CImp implements C {
@Override
public void f() {}
}
private class CImp2 implements C {
@Override
public void f() {}
}
private interface D {
void f();
}
private class DImp implements D {
@Override
public void f() {}
}
public class DImp2 implements D {
@Override
public void f() {}
}
public D getD() {
return new DImp2();
}
private D dRef;
public void receiveD(D d) {
dRef = d;
dRef.f();
}
}
interface E {
interface G {
void f();
}
// Redundant "public"
public interface H {
void f();
}
void g();
// Cannot be private within an interface
//- private interface I {}
}
public class NestingInterfaces {
public class BImp implements A.B {
@Override
public void f() {}
}
class CImp implements A.C {
@Override
public void f() {}
}
// Cannot implements a private interface except
// within that interface's defining class:
//- class DImp implements A.D {
//- public void f() {}
//- }
class EImp implements E {
@Override
public void g() {}
}
class EGImp implements E.G {
@Override
public void f() {}
}
class EImp2 implements E {
@Override
public void g() {}
class EG implements E.G {
@Override
public void f() {}
}
}
public static void main(String[] args) {
A a = new A();
// Can't access to A.D:
//- A.D ad = a.getD();
// Doesn't return anything but A.D:
//- A.DImp2 di2 = a.getD();
// cannot access a member of the interface:
//- a.getD().f();
// Only another A can do anything with getD():
A a2 = new A();
a2.receiveD(a.getD());
}
}
在类中嵌套接口的语法是相当显而易见的。就像非嵌套接口一样,它们具有 public 或包访问权限的可见性。
// interfaces/Games.java
// A Game framework using Factory Methods
interface Game {
boolean move();
}
interface GameFactory {
Game getGame();
}
class Checkers implements Game {
private int moves = 0;
private static final int MOVES = 3;
@Override
public boolean move() {
System.out.println("Checkers move " + moves);
return ++moves != MOVES;
}
}
class CheckersFactory implements GameFactory {
@Override
public Game getGame() {
return new Checkers();
}
}
class Chess implements Game {
private int moves = 0;
private static final int MOVES = 4;
@Override
public boolean move() {
System.out.println("Chess move " + moves);
return ++moves != MOVES;
}
}
class ChessFactory implements GameFactory {
@Override
public Game getGame() {
return new Chess();
}
}
public class Games {
public static void playGame(GameFactory factory) {
Game s = factory.getGame();
while (s.move()) {
;
}
}
public static void main(String[] args) {
playGame(new CheckersFactory());
playGame(new ChessFactory());
}
}