protectedメソッド
日本語 | 保護メソッド |
英語 | protected method |
ふりがな | ぷろてくてっどめそっど |
フリガナ | プロテクテッドメソッド |
protectedで修飾されたメソッド。
「protected 戻り値 メソッド名(引数){ 実装 }」のように、メソッドの宣言の先頭にprotectedが付けられたメソッド。
protectedメソッドは「パッケージの異なるクラスから呼び出すことができない」という制限が設けられている。ただし、パッケージが異なっていても「サブクラスでのオーバーライド」と「サブクラスからの呼び出し」は許されている。それ以外は、publicメソッドと同様。
protectedメソッドは、慣例的に「オーバーライドして欲しいメソッド」や「サブクラスから呼び出して欲しいメソッド」に対して付けることになっている。
通常「オーバーライドして欲しいメソッド」は抽象メソッドにするが、デフォルトとしての実装が必要な場合、そのメソッドをprotectedにすることで「このメソッドはサブクラスでオーバーライドしてください」と暗に示すことができる。
また「クラスの内部でしか使わないメソッドを、サブクラスでオーバーライドしたメソッドでも使えるようにしたい」場合にも、そのメソッドをprotectedにする。そうすることで、サブクラスから呼び出すことができ、かつ他のパッケージからアクセスできないメソッドを作ることができる。
ただし、protectedメソッドは「ざる」だと考えた方がよい。同パッケージから自由に呼び出すことができるうえ、サブクラスを作りpublicメソッドから呼び出してしまえば「publicメソッド化」できてしまう。
セキュリティ的には「publicメソッドよりは安全」程度のものであるため、コンパイル時の制限はあまり期待せず、オーバーライド等の「目印」くらいに考えた方が良い。
「protected 戻り値 メソッド名(引数){ 実装 }」のように、メソッドの宣言の先頭にprotectedが付けられたメソッド。
protectedメソッドは「パッケージの異なるクラスから呼び出すことができない」という制限が設けられている。ただし、パッケージが異なっていても「サブクラスでのオーバーライド」と「サブクラスからの呼び出し」は許されている。それ以外は、publicメソッドと同様。
protectedメソッドは、慣例的に「オーバーライドして欲しいメソッド」や「サブクラスから呼び出して欲しいメソッド」に対して付けることになっている。
通常「オーバーライドして欲しいメソッド」は抽象メソッドにするが、デフォルトとしての実装が必要な場合、そのメソッドをprotectedにすることで「このメソッドはサブクラスでオーバーライドしてください」と暗に示すことができる。
また「クラスの内部でしか使わないメソッドを、サブクラスでオーバーライドしたメソッドでも使えるようにしたい」場合にも、そのメソッドをprotectedにする。そうすることで、サブクラスから呼び出すことができ、かつ他のパッケージからアクセスできないメソッドを作ることができる。
ただし、protectedメソッドは「ざる」だと考えた方がよい。同パッケージから自由に呼び出すことができるうえ、サブクラスを作りpublicメソッドから呼び出してしまえば「publicメソッド化」できてしまう。
セキュリティ的には「publicメソッドよりは安全」程度のものであるため、コンパイル時の制限はあまり期待せず、オーバーライド等の「目印」くらいに考えた方が良い。
参考サイト
- (参考サイトはありません)
// Sample.java
// testパッケージのOtherPackageClassクラスを使用します。
import test.OtherPackageClass;
public class Sample
{
public static void main( String[] args )
{
// 同パッケージのクラスの場合。
NormalClass normalClass = new NormalClass();
// protectedメソッドを別クラスからアクセスします。
normalClass.output();
// NormalClass#output()
// このように、普通にアクセスできます。
// 他のパッケージのクラスの場合。
OtherPackageClass otherPackageClass = new OtherPackageClass();
// otherPackageClass.forOverride();
// コンパイルエラー:
// メソッド forOverride() は型 OtherPackageClass で不可視です。
// サブクラスを使用します。
otherPackageClass = new ExtendedOtherPackageClass();
otherPackageClass.output();
// OtherPackageClass#output()
// ExtendedOtherPackageClass#forOverride()
// OtherPackageClass#forOverride()
// このように、protectedメソッドは、
// サブクラスでオーバーライドすることができ、
// サブクラスから呼び出すこともできます。
}
}
/**
* フツーのクラス。
*/
class NormalClass
{
/**
* protectedメソッド。
*/
protected void output()
{
System.out.println( "NormalClass#output()" );
}
}
/**
* OtherPackageClassのサブクラス。
*/
class ExtendedOtherPackageClass extends OtherPackageClass
{
/**
* protectedメソッドをオーバーライドします。
*/
protected void forOverride()
{
System.out.println( "ExtendedOtherPackageClass#forOverride()" );
// さらに、スーパークラスの同名メソッドを
// 呼び出します。
super.forOverride();
}
}
// test/OtherPackageClass.java
package test;
/**
* フツーのクラス。
*/
public class OtherPackageClass
{
/**
* protectedメソッド。
*/
protected void forOverride()
{
System.out.println( "OtherPackageClass#forOverride()" );
}
/**
* 外から呼び出すためのpublicメソッド。
*/
public void output()
{
System.out.println( "OtherPackageClass#output()" );
forOverride();
}
}
// testパッケージのOtherPackageClassクラスを使用します。
import test.OtherPackageClass;
public class Sample
{
public static void main( String[] args )
{
// 同パッケージのクラスの場合。
NormalClass normalClass = new NormalClass();
// protectedメソッドを別クラスからアクセスします。
normalClass.output();
// NormalClass#output()
// このように、普通にアクセスできます。
// 他のパッケージのクラスの場合。
OtherPackageClass otherPackageClass = new OtherPackageClass();
// otherPackageClass.forOverride();
// コンパイルエラー:
// メソッド forOverride() は型 OtherPackageClass で不可視です。
// サブクラスを使用します。
otherPackageClass = new ExtendedOtherPackageClass();
otherPackageClass.output();
// OtherPackageClass#output()
// ExtendedOtherPackageClass#forOverride()
// OtherPackageClass#forOverride()
// このように、protectedメソッドは、
// サブクラスでオーバーライドすることができ、
// サブクラスから呼び出すこともできます。
}
}
/**
* フツーのクラス。
*/
class NormalClass
{
/**
* protectedメソッド。
*/
protected void output()
{
System.out.println( "NormalClass#output()" );
}
}
/**
* OtherPackageClassのサブクラス。
*/
class ExtendedOtherPackageClass extends OtherPackageClass
{
/**
* protectedメソッドをオーバーライドします。
*/
protected void forOverride()
{
System.out.println( "ExtendedOtherPackageClass#forOverride()" );
// さらに、スーパークラスの同名メソッドを
// 呼び出します。
super.forOverride();
}
}
// test/OtherPackageClass.java
package test;
/**
* フツーのクラス。
*/
public class OtherPackageClass
{
/**
* protectedメソッド。
*/
protected void forOverride()
{
System.out.println( "OtherPackageClass#forOverride()" );
}
/**
* 外から呼び出すためのpublicメソッド。
*/
public void output()
{
System.out.println( "OtherPackageClass#output()" );
forOverride();
}
}
// Sample.java // testパッケージのOtherPackageClassクラスを使用します。 import test.OtherPackageClass; public class Sample { public static void main( String[] args ) { // 同パッケージのクラスの場合。 NormalClass normalClass = new NormalClass(); // protectedメソッドを別クラスからアクセスします。 normalClass.output(); // NormalClass#output() // このように、普通にアクセスできます。 // 他のパッケージのクラスの場合。 OtherPackageClass otherPackageClass = new OtherPackageClass(); // otherPackageClass.forOverride(); // コンパイルエラー: // メソッド forOverride() は型 OtherPackageClass で不可視です。 // サブクラスを使用します。 otherPackageClass = new ExtendedOtherPackageClass(); otherPackageClass.output(); // OtherPackageClass#output() // ExtendedOtherPackageClass#forOverride() // OtherPackageClass#forOverride() // このように、protectedメソッドは、 // サブクラスでオーバーライドすることができ、 // サブクラスから呼び出すこともできます。 } } /** * フツーのクラス。 */ class NormalClass { /** * protectedメソッド。 */ protected void output() { System.out.println( "NormalClass#output()" ); } } /** * OtherPackageClassのサブクラス。 */ class ExtendedOtherPackageClass extends OtherPackageClass { /** * protectedメソッドをオーバーライドします。 */ protected void forOverride() { System.out.println( "ExtendedOtherPackageClass#forOverride()" ); // さらに、スーパークラスの同名メソッドを // 呼び出します。 super.forOverride(); } } // test/OtherPackageClass.java package test; /** * フツーのクラス。 */ public class OtherPackageClass { /** * protectedメソッド。 */ protected void forOverride() { System.out.println( "OtherPackageClass#forOverride()" ); } /** * 外から呼び出すためのpublicメソッド。 */ public void output() { System.out.println( "OtherPackageClass#output()" ); forOverride(); } }