C#とJavaにおけるアクセス修飾子の使い方|付与する際のルールは?
- プログラマー
- クラスを使ってプログラミングを行うオブジェクト指向では、アクセス修飾子ってとても大事な要素ですよね。publicやprivate以外の修飾子はあまり理解できていないです……
- プロジェクト
マネージャー - publicやprivateは修飾子の基本ですが、他の修飾子まで理解されている方って案外少ないです。ここで理解を深めていきましょう!
アクセス修飾子を付与する際のルールとは
アクセス修飾子とは何かについて、C#とJavaごとに説明いたします。また、アクセス修飾子を付与するにあたってのルールについてもコードによる具体例を交えながら解説していきます。
アクセス修飾子とはコード中で参照されるものの公開範囲を定義するためのもので、具体的にはメンバーやフィールド、クラスといったもののアクセシビリティを設定するためのキーワードになります。要件を満たす範囲でできるだけ狭いアクセス範囲を指定することが大事になります。
アクセス修飾子の活用場面4つ
C#には様々なアクセス修飾子が存在します。まず、どのような修飾子があるのか確認しておきます。
以下アセンブリという単語が出てきますが、アセンブリ とは実行可能ファイル(exe)またはライブラリ(dll)のことを指します。C# の場合ですと、1つのプロジェクトで1つのアセンブリが作成されます。
1:public修飾子
他のプロジェクトからでも参照設定がされていればアクセスができる修飾子です。どこからでもアクセスできるので便利な反面、プログラムを修正する際にはどこまで影響範囲があるのかの確認が必要となってきます。
サードパーティーのDLLを読み込んで実装する場合、ビルド段階ではなく、実行段階にならないとエラー箇所が判明しないなど、安易に使うのはあまりおすすめされていません。
2:internal
同一アセンブリ内のクラスからのみアクセス可能な修飾子です。他のプロジェクトからは、参照設定がされていてもinternalの場合はアクセス不可となります。
publicと違い修正範囲が限定されているため、同じアセンブリ内でのみ使用するならば、こちらを使う方が良いでしょう。
3:protected
クラス内部と派生クラスの内部からのみ参照可能なアクセス修飾子です。派生クラスとは、継承しているクラス(親子関係の子サイド)のことを指します。
基底クラスだけで使用する場合にはprivateとし、派生クラスにも使わせる必要がある場合はprotectedを実装します。違うアセンブリであっても継承関係にあればprotectedの参照は可能です。
4:private
クラス内部からのみ参照可能なアクセス修飾子です。外部から参照されることがなく、他のクラスの影響を受けない分、一番制限が厳しいアクセス修飾子だといえます。
クラスなどの型定義は、名前空間直下やファイル直下に書けますが、この場合に指定できるアクセス修飾子は、public と internal の2種類のみです。
また、メソッドなどのアクセス修飾子を明示的に指定しなかった場合には、自動的にprivate扱いされるので注意が必要です。
C#におけるアクセス修飾子の使い方
C#のアクセス修飾子internalとprotected internalについて解説いたします。そのほかの修飾子に関しては、Javaのものとアクセス範囲に大きな違いはあるものの、使い方に関しては大きな変化はないため省略いたします。
internalアクセス修飾子の使い方
internalアクセス修飾子の実装方法について確認していきます。
internal実装方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using System;
namespace WindowsFormsApp28
{
internal class Class1
{
internal void GetName()
{
Console.WriteLine("internal");
}
}
}
|
internal実装方法2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
using System;
using System.Windows.Forms;
namespace WindowsFormsApp28
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1 aaa = new Class1();
aaa.GetName();
}
}
}
|
protected internalアクセス修飾子の使い方
protected internalアクセス修飾子の実装方法についても確認しておきましょう。
protected internal実装方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using System;
namespace WindowsFormsApp28
{
internal class Class1
{
internal protected void GetName()
{
Console.WriteLine("internal protected");
}
}
}
|
protected internal実装方法2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
using System;
using System.Windows.Forms;
namespace WindowsFormsApp28
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1 bbb = new Class1();
bbb.GetName();
}
}
}
|
Javaにおけるアクセス修飾子の使い方3つ
Javaにおけるアクセス修飾子の使い方について解説いたします。Javaにはinternal修飾子が無いため、public、private、protectedについて紹介いたします。
1:publicアクセス修飾子の使い方
Javaにおけるpublicは、C#と同様に型またはメンバーに付与可能な修飾子です。
以下の様な例では、Sampleクラスはどのパッケージからでもアクセスすることができます。sampleValueフィールドにも直接参照・代入が可能です。
このように不用意にアクセス範囲を広げることはバグを生む可能性があるため推奨されません。
1
2
3
4
5
6
|
public class Sample () {
public int sampleValue = 0;
public Sample() {
}
}
|
2:privateアクセス修飾子の使い方
Javaにおけるprivateは、C#と同様にメンバーに付与可能な修飾子です。
以下の様な例では、sampleValueフィールドにprivateが付与されているため直接参照・代入ができないようになっています。
代わりにgetter、setterメソッドを実装することでsampleValueに誤って値をセットしてしまうことを防げます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Sample () {
private int sampleValue = 0;
public Sample() {
}
public void setSampleValue(int sampleValue){
this.sampleValue = sampleValue;
}
public int getSampleValue(){
return sampleValue;
}
}
|
3:protectedアクセス修飾子の使い方
protected修飾子の使い方について説明いたします。protected修飾子は同一パッケージまたは継承クラスでのみアクセスが可能です。異なるパッケージであっても継承していればアクセスが可能です。
継承元となるSampleクラスを作成したいと思います。sampleMethodはprotected修飾子により保護されています。
1
2
3
4
5
6
|
public class Sample {
protected void sampleMethod() {
System.out.println("sampleMethod is called");
}
}
|
継承したSubクラスが異なるパッケージに実装されていたとしてもアクセスすることができます。しかし、例にある通り継承したSubクラスのインスタンスからのみアクセスが可能です。
直接
Sample sample = new Sample();と生成したインスタンスからアクセスすることはできません。
1
2
3
4
5
6
7
8
9
10
11
|
// Sampleクラスとは異なるパッケージ配下にあると仮定
public class Sub extends Sample {
Sample sample = new Sample();
Sub sub = new Sub();
sample.sampleMethod(); // NG
sub.sampleMethod(); // OK
this.sampleMethod(); // OK
super.sampleMethod(); // OK
}
|
同一クラスから参照する場合と、サブクラスから参照する場合のそれぞれについて解説していきます。
同一クラスから参照する場合
同一クラスから参照する場合は特に制約はないためそのままアクセスすることができます。
1
2
3
4
5
6
7
8
9
|
public class Sample {
protected void sampleMethod() {
System.out.println("sampleMethod is called");
}
public void sampleMethod2() {
sampleMethod();
}
}
|
サブクラスから参照する場合
サブクラスから参照する場合は先ほどの例の通り、継承したクラスから生成したインスタンスからであればアクセスが可能です。また、superやthisといったコンストラクタからアクセスすることも可能です。
1
2
3
4
5
6
7
8
9
10
11
|
// Sampleクラスとは異なるパッケージ配下にあると仮定
public class Sub extends Sample {
Sample sample = new Sample();
Sub sub = new Sub();
sample.sampleMethod(); // NG
sub.sampleMethod(); // OK
this.sampleMethod(); // OK
super.sampleMethod(); // OK
}
|
アクセスできない場合の対処法は?
考えられる原因としては、直接継承元のクラスからアクセスしている可能性があります。
もっとも設計段階からミスを起こしている可能性が高いので、使用するクラスやパッケージの範囲を再度洗い出すと良いでしょう。
Javaのアクセス修飾子を使用したサンプルコード
Javaでのアクセス修飾子を使用した例を紹介いたします。デザインパターンの一つであるシングルトンを例にすると以下の通りです。
シングルトンパターンは生成されるインスタンスを1つに絞り、2つ以上は無駄に生成しないというものになります。設定値を集約したConfigクラスなど、インスタンスを複数作る必要のないクラスなどに有効です。
以下のように、インスタンスの生成はクラス上で行いつつ、コンストラクタをprivateにすることで生成を防ぐことができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// Singletonクラス自体は他のクラスやパッケージからアクセスされてほしいのでpublicを指定する
public class Singleton () {
// シングルトンを生成する
// 生成されたインスタンスをprivateでアクセスできないようにする
private static Singleton singleton = new Singleton();
// インスタンスを生成するコンストラクタをprivateにすることで無駄な生成を防ぐ
private Singleton (){
}
// singletonインスタンスはこのゲッターからのみアクセスできる
public Singleton getSingletonInstance() {
return singleton;
}
}
|
プログラマー
アクセス修飾子っていろいろあるのですね。アセンブリの範囲などを考慮してinternalアクセス修飾子もこれから使っていきます!
プロジェクト
マネージャーアクセス制限は、クラスがあるオブジェクト指向の言語では必ず理解が必要な事柄です。早めに理解して上手に使い分けていきましょう。
アクセス修飾子は上手に使い分けましょう
どのアクセス修飾子を使うかは、開発者が自らの判断で実装することになります。最初はpublicを使いがちですが、そこはアクセス制限をしっかり考慮して、隠蔽させることも大切なプログラミングの要素です。ここで解説したinternalを上手に使いこなして、プログラムの質を向上させていきましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円
東京都新宿区(新宿駅)
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円
東京都新宿区(新宿駅)
-
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円
神奈川県横浜市(桜木町駅)
-
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円
神奈川県横浜市(桜木町駅)
-
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円
東京都新宿区(西新宿駅)
-
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円
東京都新宿区(西新宿駅)