[Java] 编程思想 - 接口

avatarplhDigital nomad

抽象类和抽象方法

接口中,所有的都是public方法,因为如果是private不可访问是矛盾的,自动就是public。下面是接口实现的例子。

enum Note {
    MIDDLE_C, C_SHARP, B_FLAT;
}

interface Instrument {
    int VALUE = 5; // static & final by default
    void play(Note n); // automatically public
    void adjust();
}

class Wind implements Instrument {
    public void play(Note n) {
        System.out.println(this + ".play() " + n);
    }
    public String toString() { return "Wind"; }
    public void adjust() { System.out.println(this + ".adjust()"); }
}

class Percussion implements Instrument {
    public void play(Note n) {
        System.out.println(this + ".play() " + n);
    }
    public String toString() { return "Percussion"; }
    public void adjust() { System.out.println(this + ".adjust()"); }
}

class Stringed implements Instrument {
    public void play(Note n) {
        System.out.println(this + ".play() " + n);
    }
    public String toString() { return "Stringed"; }
    public void adjust() { System.out.println(this + ".adjust()"); }
}

class Brass extends Wind {
    public String toString() { return "Brass"; }
}

class Woodwind extends Wind {
    public String toString() { return "Woodwind"; }
}

public class Music5 {
    static void tune(Instrument i) {
        i.play(Note.MIDDLE_C);
    }

    static void tuneAll(Instrument[] e) {
        for (Instrument i : e) {
            tune(i);
        }
    }

    public static void main(String[] args) {
        Instrument[] orchestra = {
            new Wind(),
            new Percussion(),
            new Stringed(),
            new Brass(),
            new Woodwind()
        };
        tuneAll(orchestra);
    }
}

Java 中的多重继承

package org.example.thinkinjava;

interface CanFlight {
    void flight();
}

interface CanSwim {
    void swim();
}

interface CanFly {
    void fly();
}

class ActionCharacter {
    public void flight() {}
}

class Hero extends ActionCharacter implements CanFly, CanSwim, CanFlight {
    public void swim() {}
    public void fly() {}
}

public class Adventure {
    public static void t(CanFlight x) {x.flight();}
    public static void u(CanSwim x) {x.swim();}
    public static void v(CanFly x) {x.fly();}
    public static void w(ActionCharacter x) {x.flight();}

    public static void main(String[] args) {
        Hero h = new Hero();
        t(h);
        u(h);
        v(h);
        w(h);
    }
}

通过继承来扩展接口

interface Monster {
    void menace();
}

interface DangerousMonster extends Monster {
    void destroy();
}

interface Lethal {
    void kill();
}

class DragonZilla implements DangerousMonster {
    public void menace() {};
    public void destroy() {};
}
interface Vampire extends DangerousMonster, Lethal {
    void drinkBlood();
}

class VeryBadVampire implements Vampire {
    public void menace() {};
    public void destroy() {};
    public void kill() {};
    public void drinkBlood() {};
}

class HorrorShow {
    static void u(Monster x) {
        x.menace();
    }
    static void v(DangerousMonster x) {
        x.menace();
        x.destroy();
    }
    static void w(Lethal x) {x.kill(); }


    public static void main(String[] args) {
        DangerousMonster barney = new DragonZilla();
        u(barney);
        v(barney);
        Vampire vampire = new VeryBadVampire();
        u(vampire);
        v(vampire);
        w(vampire);
        System.out.println("wfefew");
    }
}

接口名字冲突

因此应该避免使用相同的名字

interface I1 {
    void f();
}
interface I2 {
    int f(int i);
}
interface I3 {
    int f();
}

class C {
    public int f() {return 1; }
}

class C2 implements I1, I2 {
    public void f() {}
    public int f(int i) {return 1;}
}

class C3 extends C implements I2 {
    public int f(int i) {return 1;}
}

class C4 extends C implements I3 {
    public int f(int i) {return 1;}
}

//class C5 extends C implements I1 {}
//interface I4 extends I1, I3 {}

适配接口

下面是面向切面编程的例子,不需要整个的写scanner,只需要复写read方法就行

class RandomWords implements Readable {

    private static final Random random = 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 = 0;

    public RandomWords(int count) {
        this.count = count;
    }

    public int read(CharBuffer cb) {
        if (count-- == 0) {
            return -1;
        }
        cb.append(capitals[random.nextInt(capitals.length)]);
        for (int i = 0; i < 4; i++) {
            cb.append(vowels[random.nextInt(vowels.length)]);
            cb.append(lowers[random.nextInt(lowers.length)]);
        }
        cb.append(" ");
        return 10;
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(new RandomWords(10));
        while (s.hasNext()) {
            System.out.print(s.next());
            System.out.print("\n");
        }
    }
}

下面的例子是一个类,既继承了,又应用了Readable接口

package org.example.thinkinjava;

import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Random;
import java.util.Scanner;

class RandomDoubles {

    private static final Random random = new Random();

    public double next() {
        return random.nextDouble();
    }

    public static void main(String[] args) {
        RandomDoubles rd = new RandomDoubles();
        for (int i = 0; i < 7; i++) {
            System.out.println(rd.next() + " ");
        }
    }
}

public class AdaptedRandomDoubles extends RandomDoubles implements Readable {

    private int count;
    public AdaptedRandomDoubles(int count) {
        this.count = count;
    }

    @Override
    public int read(CharBuffer cb) {
        if (count-- == 0) {
            return -1;
        }
        String result = Double.toString(next()) + " ";
        cb.append(result);
        return result.length();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(new AdaptedRandomDoubles(7));
        while (sc.hasNextDouble()) {
            System.out.println(sc.nextDouble() + " ");
        }
    }
}

嵌套接口

package org.example.thinkinjava;

class A {
    interface B {
        void f();
    }
    public class BImpl implements B {
        @Override
        public void f() {}
    }
    private class BImpl2 implements B {
        @Override
        public void f() {}
    }
    public interface C {
        void f();
    }
    class CImpl2 implements C {
        @Override
        public void f() {}
    }
    private interface D {
        void f();
    }
    private class DImpl implements D {
        @Override
        public void f() {}
    }
    private class DImpl2 implements D {
        @Override
        public void f() {}
    }
    public D getD() {
        return new DImpl2();
    }
    private D dRef;
    public void receiveD(D d) {
        dRef = d;
        dRef.f();
    }
}

interface E {
    interface G {
        void g();
    }
    public interface H {
        void f();
    }
    void g();
//    private interface I {}
}

public class NestingInterface {
    public class BImp implements A.B {
        public void f(){}
    }
    class CImp implements A.C {
        public void f(){}
    }
    class EImp implements E {
        public void g(){}
    }
    class EGImp implements E.G {
        public void g(){}
    }
    class EImp2 implements E {
        public void g(){}
        class EG implements E.G {
            public void g(){}
        }
    }

    public static void main(String[] args) {
        A a = new A();
//        A.D ad = a.getD();
    }
}