对象,类 与 接口

不同于国内大多数Java教程,英文世界的Java教程首先讲的就是Java的面向对象的特性。因为Java是一门纯面向对象的编程语言,理解面向对象的概念对于学习Java至关重要。
如果你从没有使用过(object-oriented programming language,OOP)面向对象编程语言,那么你需要先了解一些基本概念。

What is an Object?

Object 是一组相关的 状态行为 在软件视角上的组合。

对象分享两个特征:状态与行为。例如,一只狗有状态(名字、颜色、年龄)和行为(吠、跑、摇尾巴)。自行车也有状态(当前档位、当前速度、当前方向)和行为(换档、刹车、转向)。找到真实世界中的物体,并思考它们的状态与行为,是理解对象概念的好方法。

软件对象也由状态与其相关的行为组成。一个对象通过 fields(也称为属性) 来存储状态,通过 methods(也称为函数) 暴露它的行为。Methods操作一个对象的状态,并作为对象间的主要通信手段。隐藏内部状态并且仅通过methods与对象交互,是面向对象编程的一个重要原则,称为 data-encapsulation(封装),这是一个面向对象编程的基础原则。

What is a Class?

考虑真实世界的自行车。一个城市有各种品牌的自行车。每一个品牌所有的自行车都有相同的零部件和形状。因此每一个自行车都是一个真实存在的东西,它属于自行车这个类别。我们把这个类别称为 Class(类)。每一个具体的自行车就是这个类的一个 Instance (实例)

下面的 Bicycle 类是一种可能的实现:

public class Bicycle {

    int cadence = 0;
    int speed = 0;
    int gear = 1;

    void changeCadence(int newValue) {
        cadence = newValue;
    }

    void changeGear(int newValue) {
        gear = newValue;
    }

    void speedUp(int increment) {
        speed += increment;
    }

    void applyBrakes(int decrement) {
        speed -= decrement;
    }

    void printStates() {
        IO.println("cadence: " + cadence + " speed: "
                + speed + " gear: " + gear);
    }
}

字段cadencespeedgear表示了对象的状态。同时,方法 changeCadence()changeGear()speedUp()applyBrakes 定义了它与外部世界的交互方式。

你可能注意到上面的类中没有包含任何 main() 方法。这是因为类本身并不是一个完整的程序。类只是一个对象的蓝图。要运行程序,你需要创建一个包含 main() 方法的类,并在该方法中创建类的实例。下面是一个包含 main() 方法的类,它创建了两个个 Bicycle 类的实例并调用了它的方法:

public class BicycleDemo {
    public static void main(String[] args) {

        // Create two different
        // Bicycle objects
        Bicycle bike1 = new Bicycle();
        Bicycle bike2 = new Bicycle();

        // Invoke methods on
        // those objects
        bike1.changeCadence(50);
        bike1.speedUp(10);
        bike1.changeGear(2);
        bike1.printStates();

        bike2.changeCadence(50);
        bike2.speedUp(10);
        bike2.changeGear(2);
        bike2.changeCadence(40);
        bike2.speedUp(10);
        bike2.changeGear(3);
        bike2.printStates();
    }
}

输出如下:

cadence: 50 speed: 10 gear: 2
cadence: 40 speed: 20 gear: 3

What is Inheritance?

不同类型的物体往往有某项共同点。山地自行车,公路自行车和双座自行车。举个例子来说,他们都共享自行车的特征(当前速度、当前踏频、当前档位)。即使他们各自也定义了属于自己的额外的特性。双座自行车有两个座位和两个车把手,公路自行车有赛车车把,一些山地自行车有额外的齿盘,给它们更多的档位。

面向对象编程允许类从其他类继承一些共同使用的状态和行为。在这个例子里,Bicycle类是山地车类、、公路车和双座自行车的超类(superclass)。在Java编程语言中,每个类允许有一个直接的superclass。每一个超类可能潜在地有无数个子类(subclass)

创建子类的语法很简单,在类声明中使用关键字 extends。后面跟着需要继承的类名。
下面是一个从Bicycle类继承的MountainBike类的例子:

public class MountainBike extends Bicycle {
    // new fields and methods defining
    // a mountain bike would go here
}

这种方式给了MountainBike类所有Bicycle类相同的字段和方法,却让它的代码专注于自身那些独有的特性。

What is an Interface?

就像前面说的那样,对象与外部世界交互是通过它暴露给外部的方法完成的。方法构成对象与外部世界的接口。举个例子,电视机的按钮就是你和电视机内部电路之间的接口。你按下电源按钮,电视机就会打开或者关闭。
最常见的形式是,接口是一组相关的方法,这些方法有空的主体。用自行车的例子来说,如果定义成一个接口,它可能看起来像这样:

public interface IBicycle {

    //  wheel revolutions per minute
    void changeCadence(int newValue);

    void changeGear(int newValue);

    void speedUp(int increment);

    void applyBrakes(int decrement);
}

实现此接口,你的类名字最好换一下,比如叫ACMEBicycle。同时你要在类声明时使用关键字 implements 来声明你要实现这个接口:

public class ACMEBicycle implements IBicycle {

    int cadence = 0;
    int speed = 0;
    int gear = 1;

    // The compiler will now require that methods
    // changeCadence, changeGear, speedUp, and applyBrakes
    // all be implemented. Compilation will fail if
    // these methods are missing from this class.
    
    public void changeCadence(int newValue) {
        cadence = newValue;
    }

    public void changeGear(int newValue) {
        gear = newValue;
    }

    public void speedUp(int increment) {
        speed += increment;
    }

    public void applyBrakes(int decrement) {
        speed -= decrement;
    }

    void printStates() {
        IO.println("cadence: " + cadence + " speed: "
                + speed + " gear: " + gear);
    }
}

实现接口使类能够更正式地承诺其将提供的行为。接口构成了类与外部世界交互的契约。与此同时,这个契约在编译时被编译器强制执行。如果你的类声称实现了某个接口,该接口定义的所有方法都必须出现在其源代码中,否则类将无法成功编译。

What is a Package?

包(package) 就是一个命名空间,它由一些相关的类和接口组成。概念上思考,它有点类似电脑上的不同文件夹。你可能保存一个HTML在一个文件夹,图片在另一个文件夹。由于用Java编写的程序可能包含成百上千个类,将相关类和接口放入包中进行组织是有意义的。

Java平台提供了大量的类库,以便于程序的开发。这个类库被称为 Application Programming Interface (API)。其中代表了与常用编程最常关联的任务。例如:
String 对象包含字符串的状态和行为。File 对象允许程序员轻松的创建、删除、检查、比较或者修改一个文件。Socket 对象允许创建和使用网络套接字。这些成千上万的类库使你能够专注于你的程序的独特功能,而不是重新发明轮子。

The Java Platform API Specification 包含了完整的包、接口、类、字段和方法的列表。打开你的浏览器并且收藏它,作为程序员,它将成为你最重要的参考文档。