Java - 面向对象编程概念

153 阅读4分钟

面向对象编程概念

1. 对象

对象是理解面向对象编程(OOP)技术的关键概念。举例来说,你身边的事物,一支笔、一个椅子、一只狗,都是现实生活中的对象。这些现实对象都具有两个特征:状态和行为。

狗的状态:名字,颜色,是否饥饿。狗的行为:跑,叫,躺等等;
椅子的状态:颜色,高度,长度,材质。椅子的行为:折叠。

面向对象编程中对象的概念类似于现实生活中对象的概念,面向对象编程中的对象具有属性(状态)和方法(行为),对应着现实生活中对象的状态和行为。

1.1 数据封装

通过方法对对象的内部状态进行操作,并作为对象到对象通信的主要机制。一个对象隐藏所有的内部状态,并且要求所有的对象交互行为通过已知的方法来进行,这种机制称为数据封装

数据封装是面向对象编程概念的一个基础原则。

1.2 使用对象的好处

  • 模块化:一个对象的源代码可以独立于其他对象的源代码来编写和维护。一旦创建,一个对象就可以很容易地在系统内部传递。
  • 信息隐藏:通过数据封装,外部世界看不到对象内部的实现细节。
  • 代码复用:可以复用已经实现的对象代码。
  • 可插拔性和调试容易:如果一个特定的对象被证明是有问题,那么可以用其他对象来替换这个对象,就像现实世界中机器维修一样,一个螺母损坏,替换掉它就ok了,并不需要替换整个机器。

2. 类

类是创建单个对象的蓝图,换句话说,对象是类的实例。

在现实生活中,你会发现许多对象都是同一个类别,比如各种各样的自行车,同属于自行车类。在面向对象的术语中,我们会说一个具体的自行车是一个自行车类的一个实例。

这里是一个自行车类:

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 = speed + increment;   
    }

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

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

在BicycleDemo中,用Bicycle类实例化两个自行车对象:

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();
    }
}

3. 继承

不同类的对象之间具有一定数量的共同点。

山地自行车,公路自行车,双人自行车等等。例如,山地自行车、公路自行车和双人自行车都具有自行车的特征(当前速度、当前踏板节奏、当前档位)。 然而,每一种都定义了使它们与众不同的附加功能:双人自行车有两个座位和两组车把; 公路自行车有下降车把; 一些山地自行车有一个额外的链环,使它们的传动比较低。

面向对象编程允许类从其他类继承常用的状态和行为。

在下图中,BicycleMountain Bike, Road Bike, Tandem Bike的超类。

image.png

在Java中,每一个子类允许有一个超类,而每一个超类可以拥有无限数量的子类。

extends关键字创建子类,创建子类的语法如下:

class MountainBike extends Bicycle {

    // new fields and methods defining 
    // a mountain bike would go here

}

Mountain Bike继承了Bicycle类中的所有属性和方法,继承使得子类专注于其与众不同独特的属性和方法的实现。

4. 接口

我们已经学过,对象通过方法与外界的对象进行交互,则方法形成了与外界对象交互的接口。
在最常见的形式中,接口是一组具有空主体的相关方法。

如果指定为接口,自行车的行为可能如下:

interface Bicycle {

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

    void changeGear(int newValue);

    void speedUp(int increment);

    void applyBrakes(int decrement);
}

为了实现这个接口,假设我们现在要用ACMEBicycle这个品牌的自行车来实现接口,用关键字implements来声明:

class ACMEBicycle implements Bicycle {

    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 those
   // methods are missing from this class.

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

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

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

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

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

实现一个接口允许一个类对于它承诺提供的行为变得更加正式。

如果一个类使用implements关键字声称实现了一个接口,那么在这个类被成功编译之前,接口中的所有方法都必须出现在这个类的源代码中。

5. Package

Package是组织一系列相关的类和接口的命名空间,可以理解为计算机上不同的文件夹。因为在实际的应用和开发中,会有很多的类和接口的产生,通过将相关的类和接口放入包中来组织事物是有意义的。