tamuです。
Apex入門記事です。
「JavaやってたからApexも書けるよね」と言われても大丈夫なように、主にJavaと違う部分についてまとめています。
package
について
Javaでいうところの package
はありません。
AppExchange を開発する際にその AppExchange を識別するための名前空間(namespace)を登録することはありますが、それもJavaでいうところの package
ではありません。
package
は存在しない、と思っておきましょう。
class
の書き方
↓ ここにすべてが書いてあるのですが抜粋して説明します。
|
|
アクセス範囲
global
- すべての Apex クラスからアクセス可能
- 外部から呼び出すような class に使う
global
を使うことはあまりお勧めしないとのこと
これは Java にはないです。
ほとんどの場合で global
が必要なことはないので、次で説明する public
を使っておきましょう。
逆にいうと global
がついている class は「外部から呼び出される class」と思って読んでおきましょう。
public
- 同じ名前空間であればアクセス可能
- トップレベルでクラス宣言をするのであればこれを指定しておけば良い
テストコードじゃないコードは public
をつけてクラス宣言をすれば良いです。
「同じ名前空間であれば」とあるのは、たとえば AppExchange のクラスが public で宣言してあれば、AppExchange 外のクラスは AppExchange のクラスを読んだり実行したりすることはできません。
private
- 外から参照しない inner class だったらこれをつければ良い
- テストコードはトップレベルで宣言するときにつける
private
と(何もつけない)は同じ扱い
余談
Java でいうところの static class はありません。
Java で inner class を static で定義するとこのように書きますが、
|
|
Apex では inner class はこのように書きます。
|
|
アクセス権限
Apex クラスがアクセスするレコードの取り扱いについて定義します。
sharing rule
の範囲で動くのか、 sharing rule
を無視して動くのか、のように sharing
の語源を頭においておくとイメージしやすいかと思います。
with sharing
- 共有ルールの範囲内でレコードにアクセスできる
- → そのコードを実行したユーザがアクセスできるレコードのみアクセスできる。アクセスできないレコードはアクセスできない
without sharing
- 共有ルールを超えてレコードにアクセスできる
- → そのコードを実行したユーザがアクセスできるレコード以外にも、すべてのレコードにアクセスできる
(何もつけない)
with sharing
と同じです- 「必ず付けましょう」 by Salesforce
override
させるかどうか
virtual
- 拡張クラス側での
override
を可能にします
以下は Java であればコンパイルできますが、 Apex ではコンパイルエラーになります。
|
|
このように virtual
が必要になります。
(Kotlin で class に open
を付けないと継承できないのに似てます)
|
|
abstract
- 抽象メソッドが含まれることを宣言します
- 抽象メソッドが存在していなくてもこのクラスを直接
new
することはできません - Java でいうところの匿名クラスはないため、かならず実装クラスの定義が必要になります
|
|
拡張クラスかどうか
extends
- 元の
virtual
クラスまたはabstract
クラスを拡張する場合はこれを付けます
Java と同じです。
interface の実装かどうか
implements
interface
を実装する場合はこれをつけます
Java と同じです。
できないこと
クラス拡張の禁止 (final
)
- 拡張禁止を明示することはできません
virtual
を付けなければ拡張できないので、それで代用します
ここはKotlinと同じです。
generics
generics は事前に用意されているクラスでしか使えません。 このような宣言ができません。 宣言はできないのですが、キャストはできるので Java 1.3 時代だと思えばなんとかなります。
|
|
匿名クラス
abstract
のところで触れましたが、 匿名クラスは書けません。
abstract
クラスや interface
を使うには必ずリテラルに書いた実装クラスが必要になります。
interface
の書き方
class
宣言に似てます。
というか Java とほとんど同じです。
|
|
アクセス範囲
class
のものと同じです。
トップレベルで宣言する場合は global
or public
を付けましょう。
AppExchange 開発では global
な interface
はリリースすると変更できないそうなのでお気をつけて。
(https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_classes_interfaces.htm の一番下に書いてあります)
拡張するかどうか
ちゃんとドキュメントには書いてないのですが、 Java と同じように interface
を拡張することができます。
(コンパイルは通ります)
がちゃんとドキュメント化されていないので、 interface
を拡張するのではなく、 abstract class
で implements
するほうが良いかなと思います。
|
|
余談
私は public
な interface
を宣言することはあまりありません。
Java で interface
を定義するときは、同じI/Fで呼び出したい処理がいろいろなパッケージにまたがるときが多いです。
Apex はパッケージで namespace を分けるわけではないため、その interface
を定義するメリットがあまりないためです。