クラスのデザインと特徴
クラスデザイン
データを隠す
クラスをカプセル化するために、クラスを設計するときは、データフィールドを直接開発することは避けてください。開発者が基本的な詳細に依存しないようにするには、データフィールドを非表示にし(データフォームが変更されないという保証がないため)、安定したインターフェイスを提供する必要があります。
必要に応じて、データを保護するためにアクセサーとチェンジャーが提供されます。
public long getAge() {
return this.age;
}
public void setAge(int age) {
// 校验 age 是否和发
if(/* condition */){
this.age = age;
}
}
ブール:
public boolean isMale() {
return te;
}
public void setMale(boolean male) {
this.amle = male;
}
参照型:
参照を返すことは、データを直接公開することと同じです。これは避ける必要があります。コピーを返すことができます。
public String getName() {
return this.name.clone();
}
ただし、不変であるString
ため、そのような懸念はありませんString
。
ファクトリメソッド
クラスが十分に複雑な場合は、ファクトリメソッドを使用してインスタンスを構築する方が良い解決策になる場合があります。
たとえば、このクラスには、さまざまな関数に応じて複数のサブクラスがあります。この場合、ファクトリメソッドを使用して、新しいインスタンスを多形形式で返すことができます。
単体テスト
どのクラスにmain
もmain
メソッドを含めることができ、どのメソッドもJavaプログラムのエントリポイントとして使用できるため、単体テストを簡単に実行できます。
たとえば、クラスAをテストする場合は、クラスAにmain
メソッドを実装してからjava A
、テストを実行する必要があります。
可変パラメータ法
C / C ++のprintf
関数と同様に、任意の数のパラメーターを入力します。
Javaでは、次の構文を使用するだけで済みます。
void method(Object...args) {
for(Object obj : args) {
// ... obj
}
}
実装者の観点からは、Object...
1つObject[]
の動作に違いはありません。
呼び出し元の観点からは、任意の数のパラメーターをに渡すことができます。
包装
パッケージングクラスは基本的なタイプのパッケージングであり、そのインスタンスは不変です(参照による受け渡しは避けてください)。
jdk9以降、パッケージングクラスの構築メソッドは廃止されたものとして注釈が付けられており、パッケージングクラスのファクトリメソッドを使用することをお勧めします。
このコンストラクターを使用することが適切になることはめったにありません。静的ファクトリは、スペースと時間のパフォーマンスが大幅に向上する可能性が高いため、一般的にはより適切な選択です。
ファクトリメソッド:(Integer
例を挙げて)
public static Integer valueOf(int i)
public static Integer valueOf(String s)
public static Integer valueOf(String s, int radix)
このファクトリメソッドは、オートボクシング中のコンパイラのデフォルトの動作でもあります。次に例を示します。
list.add(3);
コンパイル後は、次と同等です。
list.add(Integer.valueOf(3));
自動開封は暗黙的に以下を呼び出します:
int intValue()
自動ボックス化解除は、算術演算または割り当てでよく発生します。
int n = list.get(i);
と同等です:
int n = list.get(i).intValue();
同時に、パッケージングクラスはツールクラスとしても使用され、対応する基本タイプに関連するツールは静的メソッドとしてカプセル化されます。
static String toString(int i)
// 整数转换为字符串
static String toString(int i ,int radix)
// 整数转换为 radix 进制的字符串
static int parselnt(String s)
// 字符串转换为整数
static int parseInt(String s,int radix)
// 字符串转换为 radix 进制的整数
列挙型クラス
Javaの列挙型クラスは、C / C ++の列挙型と同じではありません。Javaでは、列挙型クラスはクラスです。
:をenum
置き換えclass
て列挙クラスを定義します。
enum State {
OPEN, CLOSE
}
列挙クラスをローカルスコープ(メソッド内)で定義することは許可されていないことに注意してください。
列挙型クラスを使用する一般的な状況:
State flag = State.OPEN;
if(flag == State.CLOSE){
// ...
}
これはどのように達成されますか?
列挙型クラスは暗黙的にクラスを継承しEnum
、クラスが初期化されてすべてのpublic static final
インスタンスを構築するときにプライベートコンストラクターが呼び出されます。
これらのインスタンスは、定義した列挙定数です。これらの定数はすべてオブジェクトであるため、いくつかのメソッドがあります。
String name()
String toString()
// 返回字符串表示
int ordinal()
// 返回该对象的声明序号
int compareTo(E o)
// 对比声明顺序
boolean equals(Object other)
// 可以使用 ==
Class<?> getDeclaringClass()
// 返回枚举类的 Class 实例,或其外部类的 Class 实例
さらに、クラスとして、列挙型クラスを使用すると、メソッドをオーバーライドしたり、構成やメンバー関数を定義したりできます。
たとえば、各列挙型定数の説明を残し、呼び出し元がこの説明を取得できるようにします。
enum State {
OPEN("This instance means that the current state is open"),
CLOSE("This instance means that the current state is off");
String desc;
private State(String aDesc){
this.desc = aDesc;
}
public String getDesc() {
return desc;
}
};
例では、列挙型クラスのインスタンスのポリモーフィズムを実現することもできます。
通常の状況では、列挙型クラスは次のとおりです。
enum State {
OPEN, CLOSE
};
彼の原則は似ています:
class State extends Enum{
public static final State OPEN;
public static final State CLOSE;
private State(String name, int i) {
super(name, i);
}
// 通过类的静态初始化块,实例化出所有枚举类型实例
static {
OPEN = new State("OPEN", 0);
CLOSE = new State("CLOSE", 1);
}
}
この部分の場合:
public static final State OPEN;
public static final State CLOSE;
それらはState
サブクラスである可能性があり、Stateで抽象メソッドを定義してから、これらの列挙メンバーState
に抽象メソッドを継承して実装させることができます。
enum State {
OPEN{
@Override
String getDesc() {
return "This instance means that the current state is open";
}
},
CLOSE {
@Override
String getDesc() {
return "This instance means that the current state is off";
}
};
abstract String getDesc();
};
このコードの原理は、次のものと同等です。
class State extends Enum{
public static final State OPEN;
public static final State CLOSE;
private State(String name, int i) {
super(name, i);
}
abstract String getDesc();
// 通过类的静态初始化块,实例化出所有枚举类型实例
static {
OPEN = new State("OPEN", 0){
@Override
String getDesc() {
return "This instance means that the current state is open";
}
};
CLOSE = new State("CLOSE", 1){
@Override
String getDesc() {
return "This instance means that the current state is off";
}
};
}
}