• Thinking in java Chapter9 接口


    9.1 抽象类和抽象方法

    抽象方法 abstract void f(); 抽象方法没有body
    抽象类abstract class 类名{}

    抽象类不一定有 抽象方法
    有抽象方法的类 一定是 抽象类 或接口

    抽象类不能实例化
    按照多态方式,由具体的子类实例化

    抽象类的子类 要么是抽象类,要么重写抽象类中所有抽象方法。

    package chapter9interfaces.music4;
    
    import chapter8polymorphism.music.Note;
    
    abstract class Instrument {
        private int i;
    
        public abstract void play(Note n);
    
        public String what() {
            return "Instrument";
        }
    
        public abstract void adjust();
    }
    
    class Wind extends Instrument {
    
        @Override
        public void play(Note n) {
            System.out.println("Wind.play()" + n);
        }
    
        public String what() {
            return "Wind";
        }
    
        @Override
        public void adjust() {
    
        }
    }
    
    class Percussion extends Instrument { // 打击乐器
    
        @Override
        public void play(Note n) {
            System.out.println("Percussion.play()" + n);
        }
    
        public String what() {
            return "Percussion";
        }
    
        @Override
        public void adjust() {
        }
    }
    
    class Stringed extends Instrument { // 有弦(乐器)
    
        @Override
        public void play(Note n) {
            System.out.println("Stringed.play()" + n);
        }
    
        public String what() {
            return "Stringed";
        }
    
        @Override
        public void adjust() {
        }
    }
    
    class Brass extends Wind { // 铜管乐器
    
        @Override
        public void play(Note n) {
            System.out.println("Brass.play()" + n);
        }
    
        @Override
        public void adjust() {
            System.out.println("Brass.adjust()");
        }
    }
    
    class Woodwind extends Wind{
        @Override
        public void play(Note n) {
            System.out.println("Woodwind.play()" + n);
        }
    
        public String what() {
            return "Woodwind";
        }
    }
    public class music4 {
        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);
        }
    } /* Output
    Wind.play()MIDDLE_C
    Percussion.play()MIDDLE_C
    Stringed.play()MIDDLE_C
    Brass.play()MIDDLE_C
    Woodwind.play()MIDDLE_C
    */
    
    
    abstract class NoMethod{
    }
    public class E02_abstract {
        public static void main(String[] args) {
    //        NoMethod noMethod = new NoMethod(); //抽象类不能创建实例
        }
    }
    
    
    
    abstract class ContainPrint {
        abstract void print();
    
        ContainPrint() {
            print();
            System.out.println("ContainPrint constructor");
        }
    }
    
    class SubClass extends ContainPrint {
        int a = 5;
    
        @Override
        void print() {
            System.out.println(" a = " + a);
        }
    }
    
    public class E03 {
        public static void main(String[] args) {
            SubClass subClass = new SubClass();
            subClass.print();
        }
    }
    /* Output
     a = 0  在初始化之前,jvm 分配存储对象 为 a 默认值 置0 。在运行子类初始化前,调用基类的构造器 ,所以能看到 a 为0
    ContainPrint constructor  构造器内调用依赖于子类初始化的方法是危险的。
     a = 5
     */
    
    package chapter9interfaces.music4;
    
    abstract class NoMethod {
    
    }
    
    abstract class WithMethods {
        abstract public void f();
    }
    
    class Extended1 extends NoMethod {
        public void f() {
            System.out.println("Extended1.f()");
        }
    }
    
    class Extended2 extends WithMethods {
        public void f() {
            System.out.println("Extended2.f()");
        }
    }
    
    public class E04 {
        public static void test1(NoMethod nm) {  //需要向下转型
            ((Extended1) nm).f();
        }
    
        public static void test2(WithMethods wm) { // 因为f()在基类中已经定义,所以不需要向下转型
            wm.f();
        }
    
        public static void main(String[] args) {
            NoMethod e04_noMethod = new Extended1();
            test1(e04_noMethod);
    
            WithMethods withMethods = new Extended2();
            test2(withMethods);
    
        }
    }
    
    

    与哪些关键字不能共存

    // public static abstract void method(); 类名.抽象方法 没有意义
    // public final abstract void method(); 强制子类重写 final 不让子类重写,矛盾
    // private abstract void method(); private 私有

    9.2 接口

    完全抽象的类,没有任何具体实现
    方法名,参数列表,返回类型

    接口成员特点:
    成员变量:常量,隐式 是public static 和final
    构造方法:接口中没有构造方法 一个类不写继承任何类,默认继承Object
    成员方法:只能是抽象方法。默认修饰符 public abstract

    接口中所有方法默认是public

    类与类:继承关系,只能单继承,可以多层继承
    类与接口:实现关系,可以单实现,可以多实现;可以在继承一个类多同时实现多个接口
    接口与接口: 继承关系,可以单继承,可以多继承

    9.3完全耦合

    这部分需要重点,再看 + 练习题11 (后续用单例模式改作业),涉及策略模式,适配器模式
    https://www.cnblogs.com/ITPower/p/8550627.html

    9.4Java的多重继承

    package chapter9interfaces;
    
    interface CanFight {
        void fight();
    }
    
    interface CanSwim {
        void swim();
    }
    
    interface CanFly {
        void fly();
    }
    
    interface CanClimb {
        void climb();
    }
    
    class ActionCharacter {
        public void fight() {
            System.out.println("fight");
        }
    }
    
    class Hero extends ActionCharacter implements CanFight, CanFly, CanSwim, CanClimb {
    
        @Override
        public void swim() {
            System.out.println("swim");
        }
    
        @Override
        public void fly() {
            System.out.println("fly");
    
        }
    
        @Override
        public void climb() {
            System.out.println("climb");
    
        }
    }
    
    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 x(CanClimb x) {
            x.climb();
        }
    
        public static void w(ActionCharacter x) {
            x.fight();
        } // 类做参数
    
        public static void main(String[] args) {
            Hero hero = new Hero();
            t(hero); // 向上转型
            u(hero);
            v(hero);
            w(hero);
            x(hero);
        }
    }
    
    
    多重继承 菱形问题
    
    Java allows multiple interface inheritance but not multiple implementation inheritance
    Java允许多接口继承,但不允许多个实现
    
    package chapter9interfaces;
    
    interface BaseInterface {
        void f();
    }
    
    interface IntermediateInterface1 extends BaseInterface {
    }
    
    interface IntermediateInterface2 extends BaseInterface {
    }
    
    interface CombinedInterface extends IntermediateInterface1, IntermediateInterface2 {
    
    }
    
    class CombinedImpl implements CombinedInterface {
    
        @Override
        public void f() {
            System.out.println("CombinedImpl.f()");
        }
    }
    
    public class E13_Diamond {
        public static void main(String[] args) {
            new CombinedImpl().f();
    
        }
    }
    
    

    9.5通过继承来扩展接口

    extends 单一类,多基类接口

    9.5.1组合接口时的名字冲突

    重载方法仅通过返回类型是区分不开的
    在打算组合的不同接口中,尽量使用不同的方法名,否则可能导致混乱

    package chapter9interfaces;
    
    interface I1 { void f();}
    
    interface I2 {void f(int i);}
    
    interface I3 {int f();}
    
    class C {
        public int f() {
            return 1;
        }
    }
    
    class C2 implements I1, I2 {
    
        @Override
        public void f() {
        }
    
        @Override
        public void f(int i) {
        }
    }
    
    class C3 extends C implements I2 {
        @Override
        public void f(int i) {
        }
    }
    
    class C4 extends C implements I3 {
    
    }
    
    //class C5 extends C implements I1 { //Error:(39, 1) java: 类型chapter9interfaces.I3和chapter9interfaces.I1不兼容; 两者都定义了f(), 但却带有不相关的返回类型
    //}
    
    //interface I4 extends I1, I3 { //Error:(39, 1) java: 类型chapter9interfaces.I3和chapter9interfaces.I1不兼容; 两者都定义了f(), 但却带有不相关的返回类型
    //
    //}
    
    public class InterfaceCollision {
        public static void main(String[] args) {
    
        }
    }
    
    

    9.6适配接口

    package chapter9interfaces;
    
    import java.io.IOException;
    import java.nio.CharBuffer;
    import java.util.Random;
    import java.util.Scanner;
    
    public class RandomWords implements Readable {  // 实现 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 RandomWords(int count){this.count = count;}
        @Override
        public int read(CharBuffer cb) throws IOException { // public int read(java.nio.CharBuffer cb) throws IOException;
            if (count-- ==0)
                return -1;
            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; //字符添加的数量
        }
    
        public static void main(String[] args) {
            Scanner s = new Scanner(new RandomWords(10)); //  public Scanner(Readable source) 
            while (s.hasNext())
                System.out.println(s.next());
        }
    }
    
    package chapter9interfaces;
    
    import java.util.Random;
    
    public class RandomDoubles {
        private static Random rand = new Random(47);
        public double next(){return rand.nextDouble();}
    
        public static void main(String[] args) {
            RandomDoubles rd = new RandomDoubles();
            for (int i = 0;i < 7;i++){
                System.out.print(rd.next() + " ");
            }
        }
    }
    
    package chapter9interfaces;
    
    import java.io.IOException;
    import java.nio.CharBuffer;
    import java.util.Scanner;
    
    public class AdaptedRandomDoubles extends RandomDoubles implements Readable{
        private int count;
    
        AdaptedRandomDoubles(int count){this.count = count;}
    
        @Override
        public int read(CharBuffer cb) throws IOException {
            if (count-- == 0)
                return -1;
            String result = Double.toString(next()) + " ";
            cb.append(result);
            return result.length();
        }
    
        public static void main(String[] args) {
            Scanner s = new Scanner(new AdaptedRandomDoubles(8));
            while (s.hasNextDouble())
                System.out.println(s.nextDouble() + " ");
        }
    }
    
    
    package chapter9interfaces;
    
    import java.util.Random;
    
    public class RandomChar {
        private static Random rand = new Random(47);
        private static final char[] lowers = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        private static final char[] capitals = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        private static final char[] vowels = "aeiou".toCharArray();
    
        char[] generate() {
            char[] buffer = new char[10];
            int index = 0;
            buffer[index++] = capitals[rand.nextInt(capitals.length)];
            for (int i = 0; i < 4; i++) {
                buffer[index++] = lowers[rand.nextInt(lowers.length)];
                buffer[index++] = vowels[rand.nextInt(vowels.length)];
            }
            buffer[index++] = ' ';
            return buffer;
        }
    }
    
    package chapter9interfaces;
    
    import chapter9interfaces.RandomChar;
    
    import java.io.IOException;
    import java.nio.CharBuffer;
    import java.util.Arrays;
    import java.util.Scanner;
    
    public class AdaptedRandomChar extends RandomChar implements Readable {
        private int count;
        AdaptedRandomChar(int count){this.count = count;}
    
        @Override
        public int read(CharBuffer cb) throws IOException {
            if (count-- == 0)
                return -1;
            char[] result = generate();
            cb.put(result);
            return result.length;
        }
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(new AdaptedRandomChar(10));
            while (scanner.hasNext())
                System.out.println(scanner.next());
        }
    }
    
    

    9.7接口中的域

    接口中字段 自动是static final

    public interface Months { // static final 常量初始化 大写
        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;
    }
    
    package chapter9interfaces;
    
    public class ExtendMonths implements Months {
        public static void main(String[] args) {
    //        MAY =3;  // Compile-time error: cannot assign a value to final variable RED:
            System.out.println(ExtendMonths.MAY);
        }
    }
    

    9.7.1初始化接口中的域

    不能空final,非常量表达式初始化
    static 第一次加载时初始化,这些字段不是接口的一部分,存储在接口的静态存储区域
    public interface RandVals {
        Random RAND = new Random(47);
        int RANDOM_INT = RAND.nextInt(10);
        long RANDOM_LONG = RAND.nextLong() * 10;
        float RANDOM_FLOAT = RAND.nextLong() * 10;
        double RANDOM_DOUBLE = RAND.nextDouble() * 10;
    }
    
    public class TestRandVals {
        public static void main(String[] args) {
            System.out.println(RandVals.RANDOM_INT);
            System.out.println(RandVals.RANDOM_LONG);
            System.out.println(RandVals.RANDOM_FLOAT);
            System.out.println(RandVals.RANDOM_DOUBLE);
        }
    }
    /* output
    
    8
    -32032247016559954
    -8.5939291E18
    5.779976127815049
    */
    

    9.8嵌套接口

    package chapter9interfaces.nesting;
    
    class A{
         interface B{
             void  f();
         }
         public class BImp implements B{
    
             @Override
             public void f() {
    
             }
         }
    
         private 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();
        }
        public interface H{ //redundant public
            void f();
        }
        void g();
    //    private interface  I{}  在接口里面 不能private
    }
    
    public class NestingInterfaces {
        public class BImp implements A.B{
    
            @Override
            public void f() {
    
            }
        }
        class CImp implements A.C{
    
            @Override
            public void f() {
    
            }
        }
    //    class DImp implements A.D{ // A.D 私有
    //        @Override
    //        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();
    //        A.D ad = a.getD(); // A.D 私有
    //        A.DImp2 di2 = a.getD(); //a.getD() 返回的是A.D 
            A.DImp2 di2 = (A.DImp2)a.getD(); //a.getD() 返回的是A.D 
    //        a.getD().f(); // 接口的f()
            A a2 = new A();
            a2.receiveD(a.getD());
        }
    }
    

    9.9接口与工厂

    工厂模式的结构
    package chapter9interfaces;
    
    interface Service{
        void method1();
        void method2();
    }
    
    interface ServiceFactory{ // 生成某个接口的对象
        Service getService();
    }
    
    class Implementation1 implements Service{
        Implementation1(){} // package access
    
        @Override
        public void method1() {
            System.out.println("Implementation1.method1()");
        }
    
        @Override
        public void method2() {
            System.out.println("Implementation1.method2()");
        }
    }
    
    class Implementation1Factory implements ServiceFactory{
    
        @Override
        public Service getService() {
            return new Implementation1();  //生成接口的某个实现的对象
        }
    }
    
    class Implementation2 implements Service{
        Implementation2(){} // package access
    
        @Override
        public void method1() {
            System.out.println("Implementation2.method1()");
        }
    
        @Override
        public void method2() {
            System.out.println("Implementation1.method1()");
        }
    }
    
    class Implementation2Factory implements ServiceFactory{
    
        @Override
        public Service getService() {
            return new Implementation2();
        }
    }
    
    public class Factories {
        public static void serviceConsumer(ServiceFactory fact){
            Service s = fact.getService();
            s.method1();
            s.method2();
        }
        public static void main(String[] args) {
            serviceConsumer(new Implementation1Factory());
            serviceConsumer(new Implementation2Factory());
    
        }
    }
    /*
    Implementation1.method1()
    Implementation1.method2()
    Implementation2.method1()
    Implementation1.method1()
     */
    
    
    package chapter9interfaces;
    
    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 " + 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());
        }
    }
    
    
    package chapter9interfaces;
    
    import chapter8polymorphism.Shape.Circle;
    
    interface Cycle{
        int wheels();
        void balance();
    }
    
    interface CycleFactory{
        Cycle getCycle();
    }
    
    class Unicycles implements Cycle{
    
        @Override
        public int wheels() {
            return 1;
        }
    
        @Override
        public void balance() {
            System.out.println("Unicycle.balance");
        }
    }
    
    class UnicycleFactory implements CycleFactory{
    
        @Override
        public Cycle getCycle() {
            return new Unicycles();
        }
    }
    
    class Bicycles implements Cycle{
    
        @Override
        public int wheels() {
            return 2;
        }
    
        @Override
        public void balance() {
            System.out.println("Bicycle.balance");
        }
    }
    
    class BicyclesFactory implements CycleFactory{
    
        @Override
        public Cycle getCycle() {
            return new Bicycles();
        }
    }
    class Tricycles implements Cycle{
    
        @Override
        public int wheels() {
            return 2;
        }
    
        @Override
        public void balance() {
            System.out.println("Tricycle.balance");
        }
    }
    
    class TricyclesFactory implements CycleFactory{
    
        @Override
        public Cycle getCycle() {
            return new Tricycles();
        }
    }
    
    
    public class E18Cycle {
        public static void go(CycleFactory cf){
            Cycle cycle = cf.getCycle();
            System.out.println("wheels is : " + cycle.wheels());
            cycle.balance();
        }
    
        public static void main(String[] args) {
            go(new UnicycleFactory());
            go(new TricyclesFactory());
            go(new TricyclesFactory());
        }
    }
    
    
    package chapter9interfaces;
    
    interface Tossing {
        boolean event();
    }
    
    interface TossingFactory {
        Tossing getTossing();
    }
    
    class CoinTossing implements Tossing {
        private int events;
        private static final int EVENTS = 2;
    
        @Override
        public boolean event() {
            System.out.println("Coin tossing event " + events);
            return ++events != EVENTS;
        }
    }
    
    class  CoinTossingFactory implements TossingFactory{
    
        @Override
        public Tossing getTossing() {
            return new CoinTossing();
        }
    }
    
    
    class DiceTossing implements Tossing {
        private int events;
        private static final int EVENTS = 6;
    
        @Override
        public boolean event() {
            System.out.println("Dice tossing event " + events);
            return ++events != EVENTS;
        }
    }
    
    class  DiceTossingFactory implements TossingFactory{
    
        @Override
        public Tossing getTossing() {
            return new DiceTossing();
        }
    }
    public class E19Tossing { // 抛,掷;
        public static void tossing(TossingFactory tf){
            Tossing tossing = tf.getTossing();
            while (tossing.event())
                ;
    
        }
        public static void main(String[] args) {
            tossing(new CoinTossingFactory());
            tossing(new DiceTossingFactory());
    
    
        }
    }
    
    

    9.10总结

    恰当的选择是 优先选择类而不是接口。

  • 相关阅读:
    java——异常(一)
    java —— 全面解析 Annotation
    多线程(一)——三种实现方式
    java ——static 关键词总结
    java —— equals 与 ==
    java——数组与内存控制
    java—— finall 关键词
    File类实现文件夹和文件复制
    java —— 内部类
    类成员——代码块
  • 原文地址:https://www.cnblogs.com/erinchen/p/11798524.html
Copyright © 2020-2023  润新知