Java 中的类

Java 中的类有四种(为避免混淆,后文称为“广义类”):

  • 接口 interface - interface
  • 抽象类 abstract class - abstract class 且必须包含抽象方法 abstract method
  • 具体类 concrete class - class

    • 枚举 enumeration - enum

它们可以放置在:

  • 外部 outer:java 源文件的最外层
  • 内部 inner:另一个类的的内部

枚举 enumeration

枚举  enum 的本质是一个继承自 java.lang.Enum 的具体类(语法糖 grammar sugar)。

  • 枚举可以实现接口,但是不能继承其他类。
  • 枚举的 constructor 必须为 private。

示例如下:

enum Classification {
  CONVEX_QUADRILATERAL,
  PARALLELOGRAM,
  RHOMBUS,
  RECTANGLE,
  SQUARE
}

Classification c = Classification.RECTANGLE;
c.name(); // "RECTANGLE"
c == Classification.RHOMBUS; // false
enum Classification {
  CONVEX_QUADRILATERAL("Convex Quadrilateral"),
  PARALLELOGRAM("Parallelogram"),
  RHOMBUS("Rhombus"),
  RECTANGLE("Rhombus"),
  SQUARE("Square");

  private String information;

  private Classification(String information) {
      this.information = information;
  }

  /**
   * @return the information
   */
  public String getInformation() {
      return information;
  }

  /**
   * @param information the information to set
   */
  public void setInformation(String information) {
      this.information = information;
  }
}

Classification c = Classification.RECTANGLE;
c.name(); // "RECTANGLE"
c == Classification.RHOMBUS; // false
c.getInformation(); // "Rectangle"

访问控制符 access modifier

分类

访问控制符包括:

  • private
  • default
  • protected
  • public

字段 field / 方法 method / 广义内部类 inner class

访问控制符可访问性
private同类内部可见 with in the same class
(default)同包内部可见 with in the same package
protecteddefault + 非同包子类内部可见 default + sub classes in different package
public不限制 everywhere

用 private 限制构造器 constructor 后,其他类中将不能够通过 new 的方式来获取这个类的对象,这能有效控制对象的创建行为。这在某些设计模式中是必要的。

如果 class A 的一个成员是 class B,那么 A 和 B 可以相互访问声明为 private 成员和方法。如果有多个包含层级,这种可访问性是可以传递的。参见:

广义外部类 outer class

访问控制符可访问性
(default)同包内部可见 with in the same package
public不限制 everywhere

static 和 final

static

关键字 static 有这些含义:

  • 在内存中只有一份 copy 。 | There is only one copy in memory.
  • 能通过 object 访问,也能通过 class 访问。不需要创建 object 就可以访问。属于 class 不属于 object。 | It could be called without instance.
用于含义
字段 field在内存中只有一份 copy 。能通过 object 访问,也能通过 class 访问。
方法 method在内存中只有一份 copy 。能通过 object 访问,也能通过 class 访问。根据操作系统的基本原理,即使 method 不使用 static 修饰,在内存中也只有一份 copy 。static 和 default method 的区别在于—— static method 只能访问有 static field;default method 能够访问所有的 Field。
广义内部类 inner class能通过 object 访问,也能通过 class 访问。

只有声明为 static 的广义内部类 inner class,才能包含 static 的成员和方法。参见:

final

关键字 final 的含义是:一旦赋值,不可改变。

用于含义
变量 variable常量,禁止修改 constant, cannot be modified
字段 field常量或运行时常量,禁止修改 constant or runtime constant, cannot be modified
具体方法 concrete method禁止重写 prevent method overriding
具体类 concrete class禁止继承 prevent inheritance

广义常量

常量 constant 指的是在编译时 compile time 就确定下来保持不变的量,属于静态绑定 static binding。

运行时常量 runtime constant 指的是在运行时 runtime 才能确定的量,一旦确定则保持不变,属于动态绑定 dynamic binding。

public class Playground {
  public static final String SLOGAN_0 = "constant"; // constant
  public final String slogan1 = "dynamic constant"; // runtime constant

  public static void main(String[] args) {
    final String SLOGAN_2 = "constant"; // constant
    Playground playground = new Playground();
    System.out.println(SLOGAN_0);
    System.out.println(playground.slogan1);
    System.out.println(SLOGAN_2);
  }

  public Playground() {
    // constructor
  }

  public void finalize() {
    // destructor - execute before garbage collection
  }
}

命名方式:

重写 overriding

重写 overriding 指的是,当子类继承父类时,若子类和父类存在同名同参数方法,父类方法将不可见(另一种说法是“覆盖”)。重写发生在运行时 runtime。

有个容易混淆的概念叫做重载 overloading。重载指的是,允许多个方法采用相同的名称,只要输入参数不一致即可。函数的调用是由编译器确定的,也就是说,重载发生在编译时 compile time。

abstract

修饰方法

public abstract void exampleMethood();

上述代码声明一个抽象方法 abstract method。抽象方法声明以 ; 结尾,不能定义具体实现。

由于抽象方法最终要被实现 implement,因此通常使用 public 修饰(有封装 encapsulation 需求的除外,下同),禁止使用 final 修饰。

修饰类

下列代码定义一个 “被标记为 abstract 的类“ class tagged by abstract。

public abstract class ExampleClass {
  // ...
}

如果该类包含抽象方法,那么称为抽象类 abstract class。下列代码定义了一个【突四边形】抽象类。

package geometry;

public abstract class ConvexQuadrilateralAbstract implements TwoDimensionalGeometry {
  public abstract String classify();

  private static final int EDGE_NUMBER = 4;
  private final int vertexNumber = 4;

  @Override
  public int edgeNumber() {
    return EDGE_NUMBER;
  }

  public ConvexQuadrilateralAbstract() {
    System.out.println("[constructor] ConvexQuadrilateralAbstract");
  }

  /**
   * @return the vertexNumber
   */
  public int getVertexNumber() {
    return vertexNumber;
  }
}

注意:

  • 如果一个”被标记为 abstract 的类“中不含括抽象方法,那么 Java 会将其理解为具体类 concrete class,具体表现为可以正常实例化 instantiate。抽象类必须包含1+个抽象方法。
  • 如果一个类包含抽象方法,那么必须将其标记为 abstract,否则编译报错。
  • 抽象类无法进行实例化 instantiate。
  • 由于抽象类最终要被其他类继承 inherit,因此通常使用 public 修饰,禁止使用 final 修饰。

接口 interface

下列代码定义了一个【二维几何】接口。

package geometry;

public interface TwoDimensionalGeometry {
  public abstract int edgeNumber();

  public abstract double calculatePerimeter();

  public abstract double calculateArea();
}

注意:

  • 接口 interface 只能包含抽象方法 abstract method。
  • 由于接口最终要被其他类实现 implement,因此通常使用 public 修饰,禁止使用 final 修饰。

比较

类型抽象方法实例化
具体类 concrete class禁止包含抽象方法 no abstract method允许 can instantiate
抽象类 abstract class至少包含一个方法 at least one abstract method禁止 cannot instantiate
接口 interface所有方法必须为抽象方法 all methods must be abstract禁止 cannot instantiate

继承 inherit

通过关键字 extends 进行继承,示例如下:

public class Rectangle extends Parallelogram {
  // ...
}

具体类/抽象类只能继承一个具体类/抽象类。

抽象类可以继承具体类。

实现 implement

通过关键字 implements 进行实现,示例如下:

public abstract class ConvexQuadrilateralAbstract implements TwoDimensionalGeometry {
  // ...
}
public final class Triangle implements TwoDimensionalGeometry, java.io.Serializable {
  // ...
}

具体类/抽象类可以实现多个接口

面向对象 object-oriented

Java 包含面向对象 object-oriented 的四个特性:

  • 封装 encapsulation

    • 访问控制符 | access modifier
    • 暴露方法,隐藏字段 | expose method, conceal field
  • 继承 inheritance

    • 继承一个类(单继承) | inherit a class (single inheritance)
    • 实现多个接口(多实现) | implement some interface (multiple implementation)
    • 在某种程度上,多实现提供了一种间接的多继承的方法。 | To some extent, multiple implementation provides an indirect method of multiple inheritance.
  • 多态 polymorphism

    • 重写 | overriding
  • 抽象 abstraction

    • 对象 => 具体类 => 抽象类 => 接口 | object => concrete class => abstract class => interface

参考资料


Sulfonamide
397 声望12 粉丝

技能树点亮中。