Java 中的类
Java 中的类有四种(为避免混淆,后文称为“广义类”):
- 接口 interface -
interface
- 抽象类 abstract class -
abstract class
且必须包含抽象方法 abstract method 具体类 concrete class -
class
- 枚举 enumeration -
enum
- 枚举 enumeration -
它们可以放置在:
- 外部 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 |
protected | default + 非同包子类内部可见 default + sub classes in different package |
public | 不限制 everywhere |
用 private 限制构造器 constructor 后,其他类中将不能够通过 new 的方式来获取这个类的对象,这能有效控制对象的创建行为。这在某些设计模式中是必要的。
如果 class A 的一个成员是 class B,那么 A 和 B 可以相互访问声明为 private 成员和方法。如果有多个包含层级,这种可访问性是可以传递的。参见:
- https://www.zhihu.com/question/54730071/answer/140867608
- https://droidyue.com/blog/2014/10/02/the-private-modifier-in-java/
广义外部类 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 的成员和方法。参见:
- https://blog.csdn.net/zhaodedong/article/details/52911338
- https://stackoverflow.com/questions/975134/why-cant-we-have-static-method-in-a-non-static-inner-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
}
}
命名方式:
- https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names
- https://www.cnblogs.com/lanxuezaipiao/p/3534447.html - 5.2.4
重写 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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。