クラスの継承
メソッドシグネチャ
メソッドの識別を決定付ける特徴のこと
method_name(int,double)
目次
1. シグネチャとは
JDKは、javaファイルをコンパイルするとき、
記述されているメソッドに重複が無いかチェックしています。
メソッドの識別を決定付ける特徴のことを「シグネチャ」(signature)といいます。
(「メソッドシグネチャ」「シグニチャ」 とも。)
ざっくり、メソッド名(引数のデータ型)の部分です。
signature は、
元々「署名」や「サイン」
といった意味の言葉らしい。
同一のクラス中にある シグネチャが同じメソッドは、
同一のメソッドと解釈されます。
そっか!
オーバーロードがあるから
メソッド名だけでは
メソッドを識別できないんすね!
お!
それそれ。
メソッドの識別
シグネチャ が同じ → 同一のメソッド
シグネチャが同じメソッドの扱い
シグネチャ が同じメソッドは、同一クラスの中で共存できません。
2. シグネチャの構成要素
具体的に、何をもってシグネチャとするのかは、プログラム言語によって異なります。
Javaでは、以下の様にシグネチャが決まります。
シグネチャの要素になるのは
メソッド名と引数のみだ。
以下は、シグネチャの構成要素です。
- メソッド名
- 引数のデータ型
- 引数の数
- 引数のデータ型の並び
以下は、シグネチャに含まれません。
- 戻り値のデータ型
- 引数の変数名
- アクセス修飾子
- static修飾子
- final修飾子
「シグネチャの書き方」というのは
特に決まってないのだけど、
コンパイルエラーに倣って
こんな感じで表現してみた。
シグネチャ表現例
class_name.method_name(int,double)
引数の変数名や修飾子は
含まれないのね。
例えば、
メソッド名と引数が完全に一致していれば、
戻り値のデータ型が異なってもシグネチャは同じです。
戻り値のデータ型が異なるだけのメソッドは、
一つのクラスの中に複数定義することはできません。
重要
戻り値のデータ型は、シグネチャ に含まれません。
実例を見てもらった方が
早いかな。
3. シグネチャが異なるメソッドの例
以下のサンプルコードでは、すべてシグネチャが異なるメソッドが定義されています。
オーバーロードが出来て、実行可能です。
method01(int,double) と
method01(double,int) は
別のメソッドなのね。
//Signa_01.java
public class Signa_01{
//すべてシグネチャが異なるメソッド
void method01(){
System.out.println("シグネチャ: method01()");
}
void method01(int a){
System.out.println("シグネチャ: method01(int)");
}
void method01(int a, int b){
System.out.println("シグネチャ: method01(int,int)");
}
void method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
void method01(double a, int b){
System.out.println("シグネチャ: method01(double,int)");
}
public static void main(String[] args){
Signa_01 sig01 = new Signa_01();
sig01.method01(3.14d, 100);
}
}
ファイルを wsフォルダに保存して実行します。
コマンドライン
>cd ws
ws>javac -encoding UTF-8 Signa_01.java
ws>java Signa_01
シグネチャ: method01(double,int)
メソッド名は同じ「method01」ですが、同じシグネチャのメソッドはありません。
無事コンパイル出来ました。
sig01.method01(3.14d, 100);
で、引数が double int と並んでいる method01メソッドが実行されていますね。
4. シグネチャが同じメソッドの例
以下のメソッドは、
すべてシグネチャが同じだ。
共存できない。
//Signa_01NG.java
public class Signa_01NG{
/*
すべてシグネチャが同じメソッドです。
オーバーロードできません。
*/
void method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
public void method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
static void method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
int method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
final void method01(int a, double b){
System.out.println("シグネチャ: method01(int,double)");
}
void method01(int a, double b) throws RuntimeException{
if(a==0){
throw new RuntimeException("例外");
}
System.out.println("シグネチャ: method01(int,double)");
}
public static void main(String[] args){
new Signa_01NG();
}
}
ファイルを wsフォルダに保存して実行します。
コマンドライン
>cd ws
ws>javac -encoding UTF-8 Signa_01NG.java
Signa_01NG.java:13: エラー: メソッド method01(int,double)は
すでにクラス Signa_01NGで定義されています
public void method01(int a, double b){
^
Signa_01NG.java:16: エラー: メソッド method01(int,double)は
すでにクラス Signa_01NGで定義されています
static void method01(int a, double b){
^
Signa_01NG.java:19: エラー: メソッド method01(int,double)は
すでにクラス Signa_01NGで定義されています
int method01(int a, double b){
^
Signa_01NG.java:22: エラー: メソッド method01(int,double)は
すでにクラス Signa_01NGで定義されています
final void method01(int a, double b){
^
Signa_01NG.java:25: エラー: メソッド method01(int,double)は
すでにクラス Signa_01NGで定義されています
void method01(int a, double b) throws RuntimeException{
^
エラー5個
最初のメソッド
void method01(int a, double b)
以降はすべて「定義済」で
コンパイルエラーになった。
クラス内ではシグネチャが
重ならないように
定義するのね。
Yes.
お疲れ様でした。