Java编程思想---第九章 接口(上)

第九章 接口

  接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

9.1 抽象类和抽象方法

  Java提供一个叫做抽象方法的机制,这个机制是不完整的,仅有声明而没有方法体,抽象方法的语法如下:

abstract void f();

  包含抽象方法的类叫做抽象类,如果一个类包含一个或者多个抽象方法,该类必须被限定为抽象的,否则编译器就会报错。 如果一个抽象类不完整,那么当我们试图产生该类的对象时,由于抽象类创建对象时不安全的,所以我们会从编译器那里得到一条出错消息,这样编译器会确保抽象类的纯粹性,我们不必担心会误用它。

  如果从一个抽象类继承,并想创建该类的对象,就必须为基类中所有抽象方法提供方法定义没如果不这样做那么导出类便也是抽象类,且编译器会强制我们用abstract关键字来限定这个类。

  上一章的Instrument类可以很容易转化成abstract类,既然使某个类成为抽象类并不需要所有方法都是抽象的,所以仅需将某些方法声明为抽象即可,如下图所示:

  我们修改一下上面的管弦乐的例子:

package com.example.demo;

abstract class Instrument4 {
    private int i;
    public abstract void play(Note n);
    public String what() { return "Instrument4"; }
    public abstract void adjust();
}

class Wind4 extends Instrument4 {
    public void play(Note n) {
        System.out.println("Wind4.play() " + n);
    }
    public String what() { return "Wind4"; }
    public void adjust() {}
}

class Percussion4 extends  Instrument4 {
    public void play(Note n) {
        System.out.println("Percussion4.play() " + n);
    }
    public String what() { return "Percussion4"; }
    public void adjust() {}
}

class Stringed4 extends  Instrument4 {
    public void play(Note n) {
        System.out.println("Stringed4.play() " + n);
    }
    public String what() { return "Stringed4"; }
    public void adjust() {}
}

class Brass4 extends Wind4 {
    public void play(Note n) {
        System.out.println("Brass4.play() " + n);
    }
    public void adjust() {
        System.out.println("Brass.adjust()");
    }
}

class Woodwind4 extends Wind4 {
    public void play(Note n) {
        System.out.println("Woodwind4.play() " + n);
    }
    public String what() {
        return "Woodwind";
    }
}

public class Music4 {
    static void tune(Instrument4 i) {
        i.play(Note.MIDDLE_C);
    }
    static void tuneAll(Instrument4[] e) {
        for(Instrument4 i : e)
            tune(i);
    }
    public static void main(String[] args) {
        Instrument4[] orchestra = {
                new Wind4(),
                new Percussion4(),
                new Stringed4(),
                new Brass4(),
                new Woodwind4()
        };
        tuneAll(orchestra);
    }
}

输出结果为:

Wind4.play() MIDDLE_C

Percussion4.play() MIDDLE_C

Stringed4.play() MIDDLE_C

Brass4.play() MIDDLE_C

Woodwind4.play() MIDDLE_C

  我们可以看出除了基类,实际上没什么改变。

  创建抽象类和抽象方法非常有用,因为它们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样来使用它们。

9.2 接口

  Interface关键字使抽象的概念更向前迈进了一步,abstract允许我们在类中创建一个或多个没有任何定义的方法,它提供了接口部分,但没有提供任何相应的具体实现,这些实现是由此类的继承者创建的。Interface这个关键字产生一个完全抽象的类,它没有提供任何的具体实现,它允许创建者确定方法名,参数列表和返回类型,但是没有任何方法体,接口只是提供形式,没有任何具体实现。但是Interface不仅仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型来实现某种类似多重继变种的特性。

  要想创建一个接口,需要用interface关键字来替代class关键字,就像类一样,可以在interface前面加public关键字,如果不添加public则只有包访问权限。接口也可以包含域,但是这些域隐式地是static和final的。

  要让一个类遵循某个特定接口需要使用implement关键字,它表示要在这个类中对interface进行具体实现,看起来很像继承:

  可以看到,一旦实现了某个接口,其实现就变成了一个普通的类,就可以按常规方式扩展它。可以选择在接口中显示将方法声明为public的,但即使你不这么做它们也是public的,否则的话它们将只能得到默认的包访问权限,这样在方法被继承的过程中,其访问权限就被降低了,这是Java编译器所不允许的。

9.3 完全解耦

  只要一个方法操作时类而非接口,那么你就只能使用这个类及其子类,如果你想要将这个方法应用于不在此继承结构中的某个类,那么你就会触霉头了。接口可以在很大程度上放宽这种限制。

  创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式,这类方法包含的所要执行的算法中固定不变的部分,而策略包含变化的部分,策略就是传递进去的参数对象,它包含要执行的代码。

9.4 Java 中的多重继承

  接口不仅仅只是一种更纯粹形式的抽象类,它的目标比这要高,因为接口是根本没有任何具体实现的,也就是说没有任何与接口相关的存储,因此也就无法阻止多个接口的组合。在C++中,组合多个类的接口的行为被称作多重继承,在Java中你可以执行同样的行为,但是只有一个类可以有具体实现。

  在导出类中不强制要求必须有一个是抽象的或具体的基类,如果要从一个非接口的类继承,那么只能从一个类去继承,其余的基元素都必须是接口,需要将所有的接口名都置于implements关键字之后,用都好一一隔开,可以继承任意多个接口,并向上转型为每个接口,因为每一个接口都是一个独立类型。

package com.example.demo;

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);
        u(h);
        v(h);
        w(h);
    }
}

  可以看到,Hero组合了具体类ActionCharacter和接口CanFight、CanSwim、CanFly ,当通过这种方式将一个具体类和多个接口组合在一起时,这个具体类必须放在前面,后面跟着的才是接口。

原文地址:https://www.cnblogs.com/parable/p/11482496.html

时间: 2024-11-04 23:41:32

Java编程思想---第九章 接口(上)的相关文章

java编程思想 第二章

这篇时间较之前篇章时间靠后,是由于,某一天晚上看完Java编程思想文献之后来不及做笔记了. 以下笔记基本为转载,不是原创 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建新的数据类型:类 2.5 方法.参数和返回值 2.6 构建一个Java程序 2.7 你的第一个Java程序 2.8 注释和嵌入式文档 2.9 编码风格 2.1 用引用操纵对象 一切都看作对象,操纵的标识符实际上是对象的一个“引用”,遥控器(引用)操纵

<java编程思想>第一章读书笔记二

7.伴随多态的可互换对象 前面说了继承,我们知道继承中存在基类(父类)以及导出类(子类),不知道大家有没有遇到过这种情况?就是在向一个方法中传递一个对象作为参数时,我们往往会选择传递一个基类而不是一个子类,为什么要这么做呢?其实原因也很简单,说的高大上一点就是这样做有利于代码的健壮性和可扩展性,说的详细还是有利于代码的健壮性和可扩展性,更重要的也就是可扩展性. 还拿喝可乐的例子来说,如果你传递的参数对象是可乐,那么不管你是给我百事可乐还是可口可乐我都可以接受啊,但是如果你传递的参数仅仅是百事可乐

【Java编程思想】9.接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 9.1 抽象类和抽象方法 Java 提供抽象方法机制,这种方法时不完整的,仅有声明,没有方法体. 包含抽象方法的类叫做抽象类.如果一个类包含一个或多个抽象方法,那么该类必须被限定为是抽象的(否则编译器报错). 一个抽象类不完整的时候,试图创建对象时,编译器会出错(为抽象类创建对象是不安全的),编译器会保证抽象类的纯粹性. 从一个抽象类继承后,如果想创建该导出类的对象,那么必须为基类中所有抽象方法提供方法实现.不这么做,导出类便也是

java编程思想--第二章 一切都是对象

如果不做引申的话,本章没有多少可总结的内容.有些以前没有注意的细节可以写下来. 1.数据存储的位置 (1).寄存器.程序控制不了. (2).堆栈.对象的引用.基本类型. (3).堆.各种对象. (4).常量存储.和代码在一起. (5).非RAM存储.主要指流对象和持久化对象,前者准备网络传输,后者被丢到了硬盘上. 2.java中的数组会被自动初始化: (1).基本类型数组元素会被初始化为0 (2).引用类型数组元素会被初始化为null 3.变量作用域 (1).基本类型的跟C一样 (2).引用类型

Java编程思想 第一章、对象导论

对象导论阅读理解: 1.解决问题的复杂性直接取决于抽象的类型和质量(抽象类型及抽象的是什么?). 汇编语言是对底层机器的轻微抽象,而C.Basic等指令式语言都是对汇编语言的抽象,它们所做的主要抽象仍要求在解决问题时 要基于计算机的结构,而不是基于要解决的问题的结构来考虑,Java语言与C.Basic等相反,其面向问题空间的抽象而非计算 机底层实现来考虑问题结构. 2.解空间及问题空间 解空间:对应于机器模型,问题建模的地方: 问题空间:实际解决问题的模型,问题存在的地方,如一项业务: 3.对象

Java编程思想之九 接口

接口和内部为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类和抽象方法 创建一个抽象类是希望通过这个通用接口操纵一系列类. Java提供了一个叫做抽象方法的机制,这种方法是不完整的:仅声明而没有方法体. abstract void f(); 包含抽象方法的类叫做抽象类.如果一个类包含一个或多个抽象方法,那么该类必须限定为抽象的. 如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类的所有抽象方法提供方法定义. 9.2 接口 一个接口表示:所有实现该特定接口的类看起来都像这样.任

Java编程思想笔记(接口)

1.抽象类和抽象方法: abstract void f();1.包含抽象方法的类叫做抽象类.如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的.2.如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供方法定义.如果不这样做(可以选择不做),那么导出类便也是抽象类,且编译器将会强制我们用abstract关键字来限定这个类.      2.接口:interface Instrument{ //没有提供任何实现}    class Wind implements In

java编程思想第一章

1.抽象过程Alan kay 总结的面向对象的编程语言: 万物皆为对象. 程序是对象的集合,他们通过发送信息来告诉彼此所要做的. 每个对象都有自己的由其他对象所构成的存储. 每个对象都拥有其类型. 某一特定类型的所有对象都可以接受同样的信息. Booch对对象有一个更简洁的描述:对象是具有状态,行为和标识.这意味着每一个对象哪个都可以拥有内部数据(他们给出了该对象的状态)和方法(它们产生行为),并且每一个对象都可以与其他对象区分开来,就是说每一个对象在内存中有唯一的地址.2.每一个对象都有一个接

学习java编程思想 第一章 对象导论

一.面向对象的五个基本特性: 1.万物皆为对象.将对象视为奇特的变量,他可以存储数据,还可以要求它在自身上执行操作. 2.程序是对象的合集,他们通过发送消息告诉彼此所要做的. 3.每个对象都有自己的由其他对象所构成的存储.换句话说,可以通过创建包含现有对象的包的形式来创建新类型的对象. 4.每个对象否拥有其类型.每个类最重要的特性就是"可以发送什么样的消息给它". 5.某一特定类型的所有对象都可以接受同样的消息. 二.在试图开发或理解一个程序设计时,最好的方法之一就是将对象想象为&qu