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
protected
public
字段 field / 方法 method / 广义内部类 inner class
访问控制符可访问性
private
同类内部可见 with in the same class
(default)
同包内部可见 with in the same package
protected
default + 非同包子类内部可见 default + sub classes in different package
public
不限制 everywhere
PS: 用 private 限制构造器 constructor 后,其他类中将不能够通过 new 的方式来获取这个类的对象,这能有效控制对象的创建行为。这在某些设计模式中是必要的。
广义外部类 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 访问。
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
继承 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