C#のpublic/privateとは?アクセス修飾子の違いと使い分けを初心者向けに解説
はじめに
C#を学び始めると、クラスやメソッド、変数の前に public や private というキーワードが付いているコードをよく見かけます。
C#public class Person
{
private string name;
public void SayHello()
{
Console.WriteLine("こんにちは");
}
}
この public と private は、C#のアクセス修飾子と呼ばれるものです。
アクセス修飾子は、簡単にいうと「そのクラスやメンバーを、どこから使えるようにするか」を決めるためのキーワードです。
C#では、クラスの外から自由に使わせたいものには public を付け、クラスの中だけで使いたいものには private を付けます。
初心者のうちは、
「とりあえず全部publicにしておけば動くのでは?」
「privateにすると外から使えなくなって困るのでは?」
「フィールドとプロパティの違いがよくわからない」
と感じることも多いです。
しかし、public と private の違いを理解すると、C#のクラス設計やオブジェクト指向の考え方がかなりわかりやすくなります。
この記事では、C#の public / private について、意味・違い・使い分け・コード例・よくあるエラーまで初心者向けに解説します。
1. C#のpublic/privateとは?まず結論から理解しよう
1-1. publicは「外部から使える」、privateは「クラス内部だけで使える」
C#の public と private の違いを一言でいうと、次のとおりです。
| アクセス修飾子 | 意味 |
|---|---|
| public | クラスの外部からアクセスできる |
| private | 同じクラスの内部からしかアクセスできない |
たとえば、次のようなクラスがあるとします。
C#public class User
{
public string Name;
private int age;
}
この場合、Name は public なので、クラスの外から使えます。
C#User user = new User();
user.Name = "田中";
Console.WriteLine(user.Name);
一方、age は private なので、クラスの外からは使えません。
C#User user = new User();
user.age = 20; // エラー
private なメンバーは、同じクラスの中からだけ使えます。
C#public class User
{
private int age;
public void SetAge(int value)
{
age = value;
}
}
このように、public は「外に公開するもの」、private は「内部に隠すもの」と考えると理解しやすいです。
1-2. アクセス修飾子はコードの利用範囲を決めるキーワード
public や private は、C#におけるアクセス修飾子です。
アクセス修飾子は、クラス、フィールド、プロパティ、メソッドなどに付けて、その要素をどこから利用できるかを制御します。
C#public class Sample
{
private int count;
public int Count
{
get { return count; }
}
public void Add()
{
count++;
}
private void Reset()
{
count = 0;
}
}
この例では、外部から使えるのは Count プロパティと Add メソッドです。
count フィールドと Reset メソッドは private なので、クラスの外からは直接アクセスできません。
つまりアクセス修飾子は、「何を外に見せるか」「何を内側に隠すか」を決めるための仕組みです。
1-3. 初心者がpublic/privateでつまずきやすいポイント
C#初心者が public / private でつまずきやすいポイントには、次のようなものがあります。
| つまずきやすい点 | 内容 |
|---|---|
| privateにすると使えない | 外部から直接アクセスできなくなる |
| publicにすればよいと思ってしまう | 何でも公開すると保守しにくくなる |
| フィールドをpublicにしてしまう | 値を自由に変更されて不具合の原因になる |
| プロパティの必要性がわからない | privateフィールドを安全に扱うために使う |
| 省略時のアクセス範囲を誤解する | クラスメンバーは省略すると基本的にprivateになる |
特に多いのが、「エラーを避けるために全部publicにする」という考え方です。
たしかに public にすれば外部からアクセスしやすくなります。しかし、何でも外から変更できるようにすると、コードの安全性や保守性が下がります。
C#では、基本的に「必要なものだけpublicにする」という考え方が重要です。
1-4. この記事でわかること
この記事では、次の内容を解説します。
C#のアクセス修飾子とは何か
publicの意味と使い方privateの意味と使い方publicとprivateの違い初心者向けの使い分け方
実践的なコード例
カプセル化との関係
protectedやinternalなど他のアクセス修飾子省略した場合の扱い
よくある質問
C#の public private の違いを理解したい方は、まずこの記事の内容を押さえておけば基本は十分です。
2. C#のアクセス修飾子とは
2-1. アクセス修飾子の役割
C#のアクセス修飾子は、クラスやメンバーに対して「どこからアクセスできるか」を指定するためのキーワードです。
たとえば、次のように使います。
C#public class Product
{
private int price;
public int GetPrice()
{
return price;
}
}
このコードでは、Product クラスは public なので外部から利用できます。
一方、price フィールドは private なので、Product クラスの外からは直接触れません。外部から価格を取得したい場合は、public な GetPrice メソッドを使います。
アクセス修飾子の主な役割は、次の3つです。
外部に公開する機能を明確にする
外部から変更されたくないデータを守る
コードの変更に強い設計にする
C#では、このアクセス制御によって、安全で保守しやすいプログラムを書きやすくなります。
2-2. クラス・フィールド・プロパティ・メソッドに指定できる
アクセス修飾子は、さまざまな要素に指定できます。
代表的なものは次のとおりです。
| 対象 | 例 |
|---|---|
| クラス | public class User |
| フィールド | private string name; |
| プロパティ | public string Name { get; set; } |
| メソッド | public void Run() |
| コンストラクタ | public User() |
| ネストされたクラス | private class Helper |
例を見てみましょう。
C#public class Member
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public void ShowName()
{
Console.WriteLine(name);
}
private void Log()
{
Console.WriteLine("ログを出力しました");
}
}
この例では、外部に公開する Name プロパティと ShowName メソッドには public を付けています。
一方、直接触らせたくない name フィールドや、内部処理である Log メソッドには private を付けています。
2-3. なぜアクセス範囲を制限する必要があるのか
「なぜわざわざprivateにしてアクセスを制限するのか」と疑問に思うかもしれません。
理由は、外部から何でも自由に変更できると、クラスの状態が壊れやすくなるからです。
たとえば、年齢を表す Age にマイナスの値が入ると困ります。
C#public class Person
{
public int Age;
}
このように Age を public フィールドにすると、外部から自由に変更できます。
C#Person person = new Person();
person.Age = -10; // 不正な値でも入れられてしまう
年齢が -10 というのは通常ありえません。しかし、public フィールドにしていると、このような不正な値を防げません。
そこで、フィールドを private にして、値の変更は public なメソッドやプロパティ経由にします。
C#public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value >= 0)
{
age = value;
}
}
}
}
このようにすれば、外部から Age を変更できるものの、不正な値が入らないように制御できます。
アクセス範囲を制限する目的は、「使いにくくすること」ではありません。安全に使えるようにすることです。
2-4. public/private以外のアクセス修飾子の概要
C#には、public と private 以外にもアクセス修飾子があります。
代表的なアクセス修飾子は次のとおりです。
| アクセス修飾子 | 概要 |
|---|---|
| public | どこからでもアクセスできる |
| private | 同じクラス内からのみアクセスできる |
| protected | 同じクラスまたは派生クラスからアクセスできる |
| internal | 同じプロジェクト内からアクセスできる |
| protected internal | 同じプロジェクト内、または派生クラスからアクセスできる |
| private protected | 同じプロジェクト内の派生クラスからアクセスできる |
初心者のうちは、まず public と private をしっかり理解することが大切です。
C#のクラス設計では、public と private が最も基本的で、最もよく使われます。
3. publicとは?意味・使い方・コード例
3-1. publicの基本的な意味
public は、C#のアクセス修飾子のひとつで、「外部からアクセスできる」ことを意味します。
クラス、メソッド、プロパティなどに public を付けると、他のクラスから利用できるようになります。
C#public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
この Calculator クラスと Add メソッドは public です。
そのため、別のクラスから次のように使えます。
C#Calculator calculator = new Calculator();
int result = calculator.Add(3, 5);
Console.WriteLine(result);
public は、クラスの外部に対して「この機能は使ってよいですよ」と公開するためのキーワードです。
3-2. publicを付けたメンバーにアクセスできる範囲
public を付けたメンバーは、基本的にどこからでもアクセスできます。
たとえば、次のようなクラスがあるとします。
C#public class Car
{
public string Name;
public void Drive()
{
Console.WriteLine("走ります");
}
}
この場合、Name フィールドと Drive メソッドは外部から利用できます。
C#Car car = new Car();
car.Name = "プリウス";
car.Drive();
ただし、実際の開発では public フィールドをそのまま使うことはあまり推奨されません。
外部から値を自由に変更できてしまうため、データの整合性を保ちにくくなるからです。
そのため、外部に公開する値にはフィールドではなく、プロパティを使うのが一般的です。
3-3. publicフィールド・publicプロパティ・publicメソッドの違い
public は、フィールド、プロパティ、メソッドに付けられます。
それぞれの違いを整理すると、次のようになります。
| 種類 | 例 | 役割 |
|---|---|---|
| publicフィールド | public int Age; | データを直接公開する |
| publicプロパティ | public int Age { get; set; } | データを安全に公開する |
| publicメソッド | public void Run() | 外部から呼び出す操作を公開する |
publicフィールドの例です。
C#public class Person
{
public int Age;
}
これは外部から直接値を読み書きできます。
C#Person person = new Person();
person.Age = 20;
publicプロパティの例です。
C#public class Person
{
public int Age { get; set; }
}
見た目はフィールドのように使えますが、内部的には値の取得や設定を制御できます。
C#Person person = new Person();
person.Age = 20;
Console.WriteLine(person.Age);
publicメソッドの例です。
C#public class Person
{
public void SayHello()
{
Console.WriteLine("こんにちは");
}
}
これは外部から処理を呼び出すために使います。
C#Person person = new Person();
person.SayHello();
C#では、外部に公開するデータには public プロパティ、外部から実行してほしい処理には public メソッドを使うのが基本です。
3-4. publicのコード例
public の基本的な使い方を、実際のコードで確認しましょう。
C#public class Student
{
public string Name { get; set; }
public void Introduce()
{
Console.WriteLine($"私の名前は{Name}です。");
}
}
この Student クラスでは、Name プロパティと Introduce メソッドが public です。
外部から次のように使えます。
C#Student student = new Student();
student.Name = "佐藤";
student.Introduce();
実行結果は次のようになります。
私の名前は佐藤です。
public にすることで、別のクラスからそのプロパティやメソッドを利用できるようになります。
3-5. publicを使うべきケース
public を使うべきなのは、外部から利用されることを前提にしたものです。
具体的には、次のようなケースです。
| publicにするもの | 理由 |
|---|---|
| 外部から作成したいクラス | 他の場所からインスタンス化するため |
| 外部から取得したい値 | 画面表示や処理に使うため |
| 外部から変更してよい値 | 入力値や設定値を受け取るため |
| 外部から呼び出す操作 | クラスの機能として提供するため |
たとえば、商品の価格を取得したい場合は、価格を public プロパティで公開します。
C#public class Product
{
public int Price { get; set; }
}
また、注文を確定する処理を外部から呼び出したい場合は、メソッドを public にします。
C#public class Order
{
public void Complete()
{
Console.WriteLine("注文を確定しました");
}
}
public は「外部から使ってほしいもの」に付ける、と考えると判断しやすくなります。
3-6. publicを使いすぎると起こる問題
public は便利ですが、使いすぎると問題が起こります。
たとえば、すべてのフィールドを public にしたクラスを考えてみましょう。
C#public class BankAccount
{
public int Balance;
}
この場合、外部から残高を自由に変更できます。
C#BankAccount account = new BankAccount();
account.Balance = 10000;
account.Balance = -5000;
銀行口座の残高が外部から自由にマイナスにできてしまうのは危険です。
このように、何でも public にすると次のような問題が起こります。
| 問題 | 内容 |
|---|---|
| 不正な値が入る | 年齢や金額などに不正値を設定できる |
| 変更箇所が増える | どこから値が変わったのか追いにくい |
| 修正に弱くなる | 内部構造を変えると外部コードにも影響する |
| クラスの責任が曖昧になる | 外部に公開する必要がないものまで使われる |
public は必要なものだけに使うことが大切です。
4. privateとは?意味・使い方・コード例
4-1. privateの基本的な意味
private は、「同じクラスの内部からだけアクセスできる」ことを意味するアクセス修飾子です。
外部のクラスから直接アクセスされたくないフィールドやメソッドに使います。
C#public class Counter
{
private int count;
}
この count フィールドは private なので、Counter クラスの外からはアクセスできません。
C#Counter counter = new Counter();
counter.count = 10; // エラー
private は、クラスの内部状態や内部処理を隠すために使います。
4-2. privateを付けたメンバーにアクセスできる範囲
private を付けたメンバーにアクセスできるのは、同じクラスの中だけです。
C#public class Counter
{
private int count;
public void Add()
{
count++;
}
public int GetCount()
{
return count;
}
}
この例では、count は private ですが、同じ Counter クラス内にある Add メソッドや GetCount メソッドからはアクセスできます。
外部からは count に直接アクセスできません。
C#Counter counter = new Counter();
counter.Add();
Console.WriteLine(counter.GetCount());
このように、private なデータを外部から使いたい場合は、public なメソッドやプロパティを経由して扱います。
4-3. privateフィールドとクラス内部での利用
C#では、フィールドを private にすることがよくあります。
フィールドとは、クラスが持つデータのことです。
C#public class Person
{
private string name;
private int age;
}
このようにフィールドを private にすると、外部から直接変更できなくなります。
そして、値の取得や変更はプロパティを使って行います。
C#public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
外部からは次のように使えます。
C#Person person = new Person();
person.Name = "山田";
Console.WriteLine(person.Name);
フィールド自体は隠し、必要な操作だけを公開することで、安全で管理しやすいコードになります。
4-4. privateのコード例
private を使った基本的なコード例を見てみましょう。
C#public class BankAccount
{
private int balance;
public void Deposit(int amount)
{
if (amount > 0)
{
balance += amount;
}
}
public int GetBalance()
{
return balance;
}
}
この例では、balance フィールドが private です。
そのため、外部から残高を直接変更することはできません。
C#BankAccount account = new BankAccount();
account.Deposit(10000);
Console.WriteLine(account.GetBalance());
実行結果は次のようになります。
10000
外部から残高を増やすには Deposit メソッドを使う必要があります。
これにより、amount > 0 という条件を通った場合だけ残高を増やすことができます。
4-5. privateを使うべきケース
private を使うべきなのは、外部に直接見せる必要がないものです。
具体的には、次のようなものです。
| privateにするもの | 理由 |
|---|---|
| フィールド | 値を直接変更されないようにする |
| 内部処理用メソッド | 外部から呼び出す必要がないため |
| 計算途中の値 | クラス内部だけで使うため |
| 補助的な処理 | publicメソッドの内部で使うため |
| 外部に知られたくない実装 | 後から変更しやすくするため |
たとえば、消費税込み価格を計算するクラスを考えます。
C#public class PriceCalculator
{
private decimal taxRate = 0.1m;
public decimal CalculateWithTax(decimal price)
{
return price + CalculateTax(price);
}
private decimal CalculateTax(decimal price)
{
return price * taxRate;
}
}
CalculateWithTax は外部から使うメソッドなので public です。
一方、CalculateTax は内部の補助処理なので private にしています。
4-6. privateにするメリット
private にするメリットは、単にアクセスできなくすることだけではありません。
主なメリットは次のとおりです。
| メリット | 内容 |
|---|---|
| 不正な変更を防げる | 外部から勝手に値を変えられない |
| 修正しやすくなる | 内部実装を変えても外部への影響が少ない |
| 使い方が明確になる | 外部から使うべき機能だけ見える |
| バグを減らせる | 値の変更ルートを限定できる |
| カプセル化できる | オブジェクト指向らしい設計になる |
特に重要なのは、内部実装を変更しやすくなることです。
外部に公開していない private メンバーは、他のクラスから使われていません。そのため、後から名前を変えたり、処理内容を変更したりしやすくなります。
private は、コードを守るための大切な仕組みです。
5. publicとprivateの違いを比較表で理解する
5-1. public/privateのアクセス範囲の違い
public と private の一番大きな違いは、アクセスできる範囲です。
| 比較項目 | public | private |
|---|---|---|
| 同じクラス内からアクセス | できる | できる |
| 別のクラスからアクセス | できる | できない |
| 外部に公開される | される | されない |
| 主な用途 | 外部に提供する機能 | 内部データや内部処理 |
| 保守性 | 使いすぎると下がる | 高めやすい |
コードで見ると、次のようになります。
C#public class Sample
{
public int PublicValue;
private int PrivateValue;
public void Test()
{
PublicValue = 1; // OK
PrivateValue = 2; // OK
}
}
同じクラス内では、public も private もアクセスできます。
しかし、外部クラスからは違いが出ます。
C#Sample sample = new Sample();
sample.PublicValue = 1; // OK
sample.PrivateValue = 2; // エラー
private はクラスの外からアクセスできません。
5-2. 外部クラスからアクセスできるかの違い
次の例で、外部クラスからのアクセスの違いを確認しましょう。
C#public class User
{
public string Name;
private string password;
}
別のクラスから Name にはアクセスできます。
C#User user = new User();
user.Name = "tanaka";
しかし、password にはアクセスできません。
C#user.password = "abc123"; // エラー
パスワードのような重要な情報を外部から自由に変更できると危険です。
そのため、パスワードを設定したい場合は、専用の public メソッドを用意するのが一般的です。
C#public class User
{
private string password;
public void ChangePassword(string newPassword)
{
if (newPassword.Length >= 8)
{
password = newPassword;
}
}
}
このようにすれば、8文字以上の場合だけパスワードを変更できます。
private にすることで、外部からの不適切な操作を防げます。
5-3. 変更しやすさ・保守性への影響
public と private は、コードの保守性にも大きく関係します。
public なメンバーは、他のクラスから使われる可能性があります。そのため、後から名前や仕様を変えると、呼び出し側のコードも修正が必要になることがあります。
一方、private なメンバーは同じクラス内からしか使われません。そのため、外部への影響を気にせず変更しやすいです。
たとえば、次のような private メソッドがあります。
C#private int CalculateTax(int price)
{
return price / 10;
}
このメソッドはクラス内部だけで使われるため、後から計算方法を変えても外部コードには影響しません。
C#private int CalculateTax(int price)
{
return (int)(price * 0.1);
}
外部から使われる必要がないものは private にしておくと、後から修正しやすくなります。
5-4. 初心者向けの覚え方
C#の public / private は、次のように覚えるとわかりやすいです。
| アクセス修飾子 | 覚え方 |
|---|---|
| public | みんなが使える公開機能 |
| private | 自分のクラスだけが使う内部情報 |
たとえるなら、クラスを「家」と考えると理解しやすいです。
public は玄関や呼び鈴のようなものです。外の人が使ってよい入口です。
private は家の中の収納や金庫のようなものです。外の人に直接触らせるものではありません。
クラスも同じで、外部から使ってよい機能だけを public にし、内部で管理したいデータや処理は private にします。
5-5. public/privateの使い分け早見表
public と private の使い分けを早見表にすると、次のようになります。
| 対象 | おすすめ | 理由 |
|---|---|---|
| クラス外から呼び出すメソッド | public | 外部に提供する機能だから |
| クラス内部だけで使うメソッド | private | 外部に公開する必要がないから |
| フィールド | private | 直接変更を防ぐため |
| 外部から読み書きする値 | publicプロパティ | 値の扱いを制御しやすいため |
| 計算途中の変数 | private | 内部処理だけで使うため |
| パスワードや残高など重要な値 | private | 不正な変更を防ぐため |
基本方針は、「まずprivateにする。必要なものだけpublicにする」です。
この考え方を覚えておけば、C#のアクセス修飾子で迷いにくくなります。
6. public/privateの使い分け方
6-1. 基本はprivate、外部に公開するものだけpublicにする
C#で public / private を使い分けるときの基本は、次の考え方です。
基本はprivate。
外部から使う必要があるものだけpublic。
最初から何でも public にするのではなく、「これは本当に外部から使う必要があるか」を考えます。
たとえば、次のようなクラスがあるとします。
C#public class Order
{
private int totalPrice;
public int TotalPrice
{
get { return totalPrice; }
}
public void AddItem(int price)
{
if (price > 0)
{
totalPrice += price;
}
}
}
この例では、totalPrice は private です。
外部から直接変更されると、合計金額が不正になる可能性があるためです。
外部には、合計金額を取得する TotalPrice プロパティと、商品を追加する AddItem メソッドだけを公開しています。
このように、クラスの内部状態は隠し、必要な操作だけを公開するのが基本です。
6-2. フィールドはprivate、値の取得・変更はプロパティで行う
C#では、フィールドは基本的に private にします。
そして、外部から値を取得・変更する必要がある場合は、public プロパティを用意します。
悪い例です。
C#public class Person
{
public int Age;
}
このコードでは、Age にどんな値でも代入できます。
C#Person person = new Person();
person.Age = -1;
良い例です。
C#public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value >= 0)
{
age = value;
}
}
}
}
このようにすると、マイナスの年齢が設定されるのを防げます。
C#では自動実装プロパティもよく使います。
C#public class Person
{
public string Name { get; set; }
}
ただし、値のチェックが必要な場合は、private フィールドとプロパティを組み合わせるとよいです。
6-3. メソッドをpublicにする判断基準
メソッドを public にするかどうかは、「外部から呼び出すべき操作か」で判断します。
たとえば、次のような注文クラスを考えます。
C#public class Order
{
public void Complete()
{
Console.WriteLine("注文を確定しました");
}
private void CalculateTotal()
{
Console.WriteLine("合計金額を計算しました");
}
}
Complete は、外部から注文を確定するための操作なので public です。
一方、CalculateTotal は注文確定処理の内部で使う補助処理であれば、private にします。
メソッドを public にする判断基準は次のとおりです。
| 判断基準 | publicにする? |
|---|---|
| 外部から直接呼び出す必要がある | public |
| クラスの機能として提供したい | public |
| 内部処理の一部でしかない | private |
| 他のpublicメソッドからだけ呼ばれる | private |
| 後から自由に変更したい実装部分 | private |
外部に公開するメソッドが少ないほど、クラスの使い方はシンプルになります。
6-4. クラス内部だけで使う処理はprivateメソッドにする
クラス内部だけで使う処理は、private メソッドにします。
たとえば、メール送信前にメールアドレスをチェックする処理を考えます。
C#public class MailService
{
public void Send(string email)
{
if (IsValidEmail(email))
{
Console.WriteLine("メールを送信しました");
}
}
private bool IsValidEmail(string email)
{
return email.Contains("@");
}
}
Send は外部から使う機能なので public です。
IsValidEmail は Send の内部で使うチェック処理なので private です。
外部から IsValidEmail を直接呼び出す必要がないなら、private にしておくほうがよいです。
C#MailService service = new MailService();
service.Send("test@example.com");
service.IsValidEmail("test@example.com"); // エラー
これにより、外部に見える機能を必要最小限にできます。
6-5. 実務でよく使われる設計パターン
実務のC#では、次のような形がよく使われます。
C#public class Customer
{
private string name;
private int point;
public string Name
{
get { return name; }
}
public int Point
{
get { return point; }
}
public Customer(string name)
{
this.name = name;
point = 0;
}
public void AddPoint(int value)
{
if (value > 0)
{
point += value;
}
}
private bool CanUsePoint(int value)
{
return value > 0 && point >= value;
}
}
この設計では、次のように役割が分かれています。
| メンバー | アクセス修飾子 | 役割 |
|---|---|---|
name | private | 内部で保持する名前 |
point | private | 内部で保持するポイント |
Name | public | 外部から名前を取得する |
Point | public | 外部からポイントを取得する |
Customer | public | インスタンスを作る |
AddPoint | public | 外部からポイントを追加する |
CanUsePoint | private | 内部でポイント利用可否を判定する |
このように、フィールドを private にし、外部から必要な操作だけを public にするのが、実務でもよく使われる基本形です。
7. public/privateを使った実践コード例
7-1. 悪い例:すべてpublicにしてしまうコード
まずは、すべてを public にしてしまう悪い例を見てみましょう。
C#public class BankAccount
{
public string OwnerName;
public int Balance;
public void Deposit(int amount)
{
Balance += amount;
}
public void Withdraw(int amount)
{
Balance -= amount;
}
}
このコードは一見わかりやすく見えます。
しかし、外部から Balance を自由に変更できてしまいます。
C#BankAccount account = new BankAccount();
account.OwnerName = "田中";
account.Balance = 10000;
account.Balance = -999999; // 不正な値を入れられる
これでは、口座残高のルールを守れません。
また、Withdraw メソッドにも問題があります。
C#account.Withdraw(20000);
残高が足りない場合でも、そのまま引き出せてしまいます。
すべてを public にすると、外部から自由に操作されすぎて、クラスの安全性が下がります。
7-2. 良い例:privateフィールドとpublicプロパティを使うコード
次に、private フィールドと public プロパティを使った良い例を見てみましょう。
C#public class BankAccount
{
private string ownerName;
private int balance;
public string OwnerName
{
get { return ownerName; }
}
public int Balance
{
get { return balance; }
}
public BankAccount(string ownerName)
{
this.ownerName = ownerName;
balance = 0;
}
public void Deposit(int amount)
{
if (amount > 0)
{
balance += amount;
}
}
public bool Withdraw(int amount)
{
if (amount > 0 && balance >= amount)
{
balance -= amount;
return true;
}
return false;
}
}
この例では、ownerName と balance は private です。
外部から直接変更できません。
C#BankAccount account = new BankAccount("田中");
account.Deposit(10000);
bool result = account.Withdraw(3000);
Console.WriteLine(account.OwnerName);
Console.WriteLine(account.Balance);
Console.WriteLine(result);
実行結果は次のようになります。
田中
7000
True
Balance は public プロパティで取得できますが、外部から直接変更はできません。
C#account.Balance = -1000; // エラー
これにより、残高は Deposit と Withdraw のルールに従ってのみ変更されます。
7-3. privateメソッドで内部処理を隠すコード
次は、private メソッドで内部処理を隠す例です。
C#public class Order
{
private int itemPrice;
private int quantity;
public Order(int itemPrice, int quantity)
{
this.itemPrice = itemPrice;
this.quantity = quantity;
}
public int GetTotalPrice()
{
int subtotal = CalculateSubtotal();
int tax = CalculateTax(subtotal);
return subtotal + tax;
}
private int CalculateSubtotal()
{
return itemPrice * quantity;
}
private int CalculateTax(int subtotal)
{
return (int)(subtotal * 0.1);
}
}
外部から使うのは GetTotalPrice だけです。
C#Order order = new Order(1000, 3);
Console.WriteLine(order.GetTotalPrice());
一方、CalculateSubtotal や CalculateTax は内部計算用のメソッドなので、private にしています。
C#order.CalculateTax(3000); // エラー
このように、外部に公開する必要がない処理は private にして隠します。
すると、外部のコードはシンプルになります。
C#int total = order.GetTotalPrice();
利用者は、内部で小計や税額をどう計算しているかを知らなくても使えます。
7-4. コンストラクタと組み合わせた使い方
public / private はコンストラクタともよく組み合わせて使います。
コンストラクタとは、クラスからインスタンスを作るときに呼ばれる特別なメソッドです。
C#public class User
{
private string name;
private int age;
public User(string name, int age)
{
this.name = name;
if (age >= 0)
{
this.age = age;
}
}
public string Name
{
get { return name; }
}
public int Age
{
get { return age; }
}
}
この例では、name と age は private フィールドです。
値は public コンストラクタで初期化します。
C#User user = new User("佐藤", 25);
Console.WriteLine(user.Name);
Console.WriteLine(user.Age);
外部から Name と Age は取得できますが、直接変更はできません。
C#user.Age = 30; // エラー
このようにすると、インスタンス作成時に必要な値だけを設定し、その後は勝手に変更されない設計にできます。
また、コンストラクタ自体を private にすることもあります。
C#public class AppConfig
{
private AppConfig()
{
}
}
これは、外部から自由にインスタンス化されたくない場合などに使われます。
初心者のうちは、まず public コンストラクタでインスタンスを作り、フィールドは private にする基本形を覚えるとよいです。
7-5. エラー例から学ぶアクセスできない原因
private メンバーに外部からアクセスしようとすると、コンパイルエラーになります。
C#public class Sample
{
private int number;
}
外部から次のように書くとエラーです。
C#Sample sample = new Sample();
sample.number = 10;
これは、number が private で、Sample クラスの外からアクセスできないためです。
解決方法は、number を単純に public にすることではありません。
外部から値を扱う必要があるなら、プロパティやメソッドを用意します。
C#public class Sample
{
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
}
これで外部からは次のようにアクセスできます。
C#Sample sample = new Sample();
sample.Number = 10;
Console.WriteLine(sample.Number);
エラーが出たときは、まず「アクセスしようとしているメンバーが private になっていないか」を確認しましょう。
そして、本当に外部からアクセスすべきものなのかを考えます。
8. public/privateとカプセル化の関係
8-1. カプセル化とは何か
C#の public / private を理解するうえで重要なのが、カプセル化です。
カプセル化とは、オブジェクトの内部データや内部処理を隠し、外部には必要な操作だけを公開する考え方です。
たとえば、銀行口座クラスでは、残高そのものを外部から直接変更させるのではなく、入金や出金という操作を通して変更します。
C#public class BankAccount
{
private int balance;
public void Deposit(int amount)
{
if (amount > 0)
{
balance += amount;
}
}
public bool Withdraw(int amount)
{
if (amount > 0 && balance >= amount)
{
balance -= amount;
return true;
}
return false;
}
public int Balance
{
get { return balance; }
}
}
この例では、balance を private にして隠し、Deposit、Withdraw、Balance だけを public にしています。
これがカプセル化の基本です。
8-2. privateで内部状態を隠す理由
private は、カプセル化を実現するために重要です。
クラスが持つ内部状態を外部から直接変更できると、不正な状態になる可能性があります。
たとえば、次のようなクラスは危険です。
C#public class GamePlayer
{
public int Hp;
}
外部からHPを自由に変更できます。
C#GamePlayer player = new GamePlayer();
player.Hp = 100;
player.Hp = -50;
HPがマイナスになると、ゲームのルールとしておかしい場合があります。
そこで、HPを private にします。
C#public class GamePlayer
{
private int hp;
public int Hp
{
get { return hp; }
}
public void Damage(int value)
{
if (value > 0)
{
hp -= value;
if (hp < 0)
{
hp = 0;
}
}
}
}
このようにすると、HPの変更は Damage メソッドを通して行われます。
private によって内部状態を守ることで、クラスのルールを維持できます。
8-3. publicで必要な操作だけ公開する理由
public は、外部から使う必要がある操作だけに付けます。
外部に公開する操作が多すぎると、クラスの使い方が複雑になります。
たとえば、次のようなクラスを考えます。
C#public class Report
{
public void Create()
{
LoadData();
FormatData();
Print();
}
private void LoadData()
{
Console.WriteLine("データを読み込みました");
}
private void FormatData()
{
Console.WriteLine("データを整形しました");
}
private void Print()
{
Console.WriteLine("レポートを出力しました");
}
}
外部から使う必要があるのは Create メソッドだけです。
内部で行う LoadData、FormatData、Print は private にしています。
外部の利用者は、次のようにシンプルに使えます。
C#Report report = new Report();
report.Create();
内部処理をすべて public にすると、使う側がどの順番で呼べばよいのか迷ってしまいます。
必要な操作だけを public にすると、クラスの使い方が明確になります。
8-4. 保守しやすいコードにするための考え方
保守しやすいコードを書くには、外部に公開する範囲を小さくすることが大切です。
public なメンバーは、他のコードから使われる可能性があります。
そのため、後から変更すると影響範囲が広くなりがちです。
一方、private なメンバーは、同じクラスの中だけを確認すればよいので、変更しやすいです。
たとえば、内部の税計算メソッドを変更する場合を考えます。
C#private int CalculateTax(int price)
{
return (int)(price * 0.1);
}
このメソッドが private であれば、外部から直接使われていません。
そのため、次のように変更しても影響範囲はクラス内に限定されます。
C#private int CalculateTax(int price)
{
decimal taxRate = 0.1m;
return (int)(price * taxRate);
}
保守しやすいコードにするには、「外に見せる必要がないものは隠す」という意識が重要です。
8-5. オブジェクト指向初心者が押さえるべきポイント
オブジェクト指向初心者が public / private で押さえるべきポイントは、次の3つです。
| ポイント | 内容 |
|---|---|
| データはなるべくprivateにする | 外部から直接変更されないようにする |
| 操作は必要なものだけpublicにする | クラスの使い方を明確にする |
| 内部処理はprivateメソッドにする | 実装を隠して変更しやすくする |
クラスは、単なる変数の集まりではありません。
データと操作をまとめ、外部に対して安全な使い方を提供するものです。
そのために、public と private を使い分けます。
public は外部との接点、private は内部の仕組みです。
このイメージを持つと、C#のクラス設計が理解しやすくなります。
9. public/private以外のアクセス修飾子も簡単に理解する
9-1. protectedとは
protected は、同じクラスと、そのクラスを継承した派生クラスからアクセスできるアクセス修飾子です。
C#public class Animal
{
protected string name;
}
public class Dog : Animal
{
public void SetName(string value)
{
name = value;
}
}
この例では、name は protected です。
Animal クラスの中からアクセスできるだけでなく、Animal を継承した Dog クラスからもアクセスできます。
一方、外部からはアクセスできません。
C#Dog dog = new Dog();
dog.name = "ポチ"; // エラー
protected は、継承を使った設計でよく登場します。
初心者のうちは、「継承先から使えるprivateに近いもの」と考えると理解しやすいです。
9-2. internalとは
internal は、同じプロジェクト、正確には同じアセンブリ内からアクセスできるアクセス修飾子です。
C#internal class Helper
{
public void Run()
{
Console.WriteLine("処理を実行しました");
}
}
internal を付けたクラスやメンバーは、同じプロジェクト内では使えますが、別のプロジェクトからは基本的に使えません。
たとえば、ライブラリを作るときに、外部の利用者には公開したくないけれど、プロジェクト内部では使いたいクラスに internal を付けることがあります。
C#internal class FileParser
{
public void Parse()
{
Console.WriteLine("ファイルを解析しました");
}
}
internal は、アプリケーションやライブラリの内部実装を隠したい場合に便利です。
9-3. protected internalとは
protected internal は、少し複雑なアクセス修飾子です。
これは、次のどちらかに当てはまる場合にアクセスできます。
同じアセンブリ内からアクセスできる
別アセンブリでも派生クラスからアクセスできる
つまり、protected と internal の条件を広めに組み合わせたものです。
C#public class BaseClass
{
protected internal void Show()
{
Console.WriteLine("protected internalです");
}
}
同じプロジェクト内であれば、派生クラスでなくてもアクセスできます。
また、別プロジェクトであっても、派生クラスであればアクセスできます。
初心者のうちは、protected internal をすぐに使う機会は少ないです。
まずは public、private、必要に応じて protected、internal を理解すれば十分です。
9-4. private protectedとは
private protected は、同じアセンブリ内にある派生クラスからだけアクセスできるアクセス修飾子です。
つまり、次の両方を満たす必要があります。
同じアセンブリ内である
派生クラスである
C#public class BaseClass
{
private protected void Show()
{
Console.WriteLine("private protectedです");
}
}
public class DerivedClass : BaseClass
{
public void Test()
{
Show();
}
}
private protected は、protected internal よりもアクセス範囲が狭いです。
protected internal は「同じアセンブリ、または派生クラス」ですが、private protected は「同じアセンブリ、かつ派生クラス」です。
初心者向けの学習では優先度は高くありませんが、C#にはこのような細かいアクセス制御もあると知っておくとよいです。
9-5. 初心者はまずpublic/privateを優先して覚えればよい理由
C#には複数のアクセス修飾子がありますが、初心者はまず public と private を優先して覚えれば問題ありません。
理由は、日常的なクラス設計で最もよく使うのが public と private だからです。
基本的なクラスでは、次のような使い分けが中心になります。
C#public class Sample
{
private int value;
public int Value
{
get { return value; }
}
public void SetValue(int value)
{
this.value = value;
}
}
外部に公開するクラスやメソッドは public。
内部で保持するフィールドや補助メソッドは private。
この基本がわかれば、C#のクラスはかなり読みやすくなります。
protected や internal は、継承やプロジェクト分割を学ぶ段階で少しずつ理解すれば大丈夫です。
10. アクセス修飾子を省略した場合の扱い
10-1. クラスメンバーの既定はprivate
C#では、クラスメンバーのアクセス修飾子を省略すると、基本的に private として扱われます。
C#public class Sample
{
int number;
void Show()
{
Console.WriteLine(number);
}
}
このコードの number フィールドと Show メソッドは、アクセス修飾子を省略しています。
しかし、実際には次のように書いた場合と同じです。
C#public class Sample
{
private int number;
private void Show()
{
Console.WriteLine(number);
}
}
そのため、外部からはアクセスできません。
C#Sample sample = new Sample();
sample.Show(); // エラー
初心者のうちは、「クラスの中で何も付けなければprivateになる」と覚えておくとよいです。
10-2. クラスの既定はinternal
クラスのアクセス修飾子を省略した場合、トップレベルのクラスは internal として扱われます。
C#class Sample
{
}
これは次のように書いた場合と同じです。
C#internal class Sample
{
}
つまり、同じプロジェクト内からは使えますが、別のプロジェクトからは基本的に使えません。
外部のプロジェクトから利用されるライブラリのクラスとして公開したい場合は、明示的に public を付けます。
C#public class Sample
{
}
なお、クラスの中に定義するネストされたクラスの場合は、既定のアクセス範囲が private になります。
C#public class Outer
{
class Inner
{
}
}
この Inner は、private class Inner と同じ扱いです。
10-3. インターフェース内のメンバーの扱い
C#のインターフェース内のメンバーは、基本的に public として扱われます。
C#public interface ILogger
{
void Log(string message);
}
この Log メソッドは、明示的に public と書いていなくても、インターフェースの外部に公開されるメンバーです。
クラスで実装するときは、通常 public を付けます。
C#public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
次のように public を付けずに実装すると、エラーになる場合があります。
C#public class ConsoleLogger : ILogger
{
void Log(string message)
{
Console.WriteLine(message);
}
}
クラスメンバーは省略すると private になるため、インターフェースの public なメンバーを正しく実装できないからです。
初心者のうちは、インターフェースを実装するメソッドには public を付ける、と覚えておくとよいです。
10-4. 省略せず明示したほうがよい理由
C#では、アクセス修飾子を省略してもコンパイルできる場合があります。
しかし、初心者のうちは省略せずに明示することをおすすめします。
理由は、コードの意図がわかりやすくなるからです。
C#public class Sample
{
private int count;
public void Add()
{
count++;
}
}
このように書くと、count は内部用、Add は外部公開用だとすぐにわかります。
一方、次のように省略すると、慣れていない人にはアクセス範囲がわかりにくくなります。
C#class Sample
{
int count;
void Add()
{
count++;
}
}
C#に慣れるまでは、public や private を明示して書くと、読みやすく安全なコードになります。
10-5. よくある勘違いと注意点
アクセス修飾子の省略でよくある勘違いは、次のようなものです。
| 勘違い | 正しい理解 |
|---|---|
| 省略するとpublicになる | クラスメンバーは基本的にprivateになる |
| クラスも省略するとpublicになる | トップレベルクラスはinternalになる |
| privateでも外部から何とか使える | 通常は直接アクセスできない |
| インターフェース実装でもpublicは不要 | 通常はpublicが必要 |
| publicにすれば設計として正しい | 必要なものだけpublicにするべき |
特に注意したいのは、メソッドのアクセス修飾子を省略してしまうケースです。
C#public class Service
{
void Execute()
{
Console.WriteLine("実行しました");
}
}
この Execute は private です。
外部から呼び出したい場合は、明示的に public を付けます。
C#public class Service
{
public void Execute()
{
Console.WriteLine("実行しました");
}
}
「なぜ外部から呼べないのか」と思ったときは、アクセス修飾子が省略されていないか確認しましょう。
11. public/privateに関するよくある質問
11-1. フィールドはpublicにしてもよい?
基本的には、フィールドは public にしないほうがよいです。
理由は、外部から自由に値を変更できてしまうからです。
C#public class Person
{
public int Age;
}
この場合、次のように不正な値を入れられます。
C#Person person = new Person();
person.Age = -10;
通常は、フィールドを private にして、必要に応じて public プロパティを用意します。
C#public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value >= 0)
{
age = value;
}
}
}
}
ただし、定数のように変更されない値を公開する場合は、public const や public static readonly を使うことがあります。
C#public class MathValues
{
public const double Pi = 3.14159;
}
初心者のうちは、「フィールドはprivate、外部公開はプロパティ」と覚えておくのがおすすめです。
11-2. privateにした変数を外部から使いたい場合は?
private にした変数を外部から使いたい場合は、public なプロパティやメソッドを用意します。
たとえば、次のような private フィールドがあるとします。
C#public class User
{
private string name;
}
外部から名前を取得・変更したい場合は、プロパティを追加します。
C#public class User
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
読み取りだけ許可したい場合は、get だけを用意します。
C#public class User
{
private string name;
public string Name
{
get { return name; }
}
public User(string name)
{
this.name = name;
}
}
外部から値を変更されたくない場合は、読み取り専用プロパティにすると安全です。
C#User user = new User("田中");
Console.WriteLine(user.Name);
user.Name = "佐藤"; // エラー
private な値を外部から使う場合は、「直接触らせる」のではなく、「安全な入口を用意する」と考えましょう。
11-3. publicクラスの中にprivateメンバーは作れる?
はい、作れます。
むしろ、public クラスの中に private メンバーを作るのは非常に一般的です。
C#public class Product
{
private int price;
public int Price
{
get { return price; }
set
{
if (value >= 0)
{
price = value;
}
}
}
}
この例では、Product クラス自体は public なので外部から使えます。
しかし、price フィールドは private なので、外部から直接アクセスできません。
C#Product product = new Product();
product.Price = 1000; // OK
product.price = 1000; // エラー
public クラスは「外部から使えるクラス」という意味です。
その中のすべてのメンバーが自動的に public になるわけではありません。
クラスが public でも、フィールドやメソッドごとに public / private を指定できます。
11-4. privateメソッドはテストできる?
private メソッドは、通常は外部から直接呼び出してテストしません。
基本的には、その private メソッドを使っている public メソッドを通してテストします。
たとえば、次のようなクラスがあります。
C#public class Calculator
{
public int CalculateTotal(int price)
{
return price + CalculateTax(price);
}
private int CalculateTax(int price)
{
return (int)(price * 0.1);
}
}
この場合、CalculateTax を直接テストするのではなく、CalculateTotal をテストします。
C#Calculator calculator = new Calculator();
int result = calculator.CalculateTotal(1000);
Console.WriteLine(result);
private メソッドは内部実装です。
内部実装を直接テストしすぎると、実装を少し変えただけでテストが壊れやすくなります。
ただし、private メソッドの処理が複雑すぎる場合は、別のクラスに切り出して public メソッドとしてテストできる形にすることもあります。
初心者のうちは、「privateメソッドはpublicメソッド経由でテストする」と覚えておくとよいです。
11-5. public/privateはパフォーマンスに影響する?
通常、public と private の違いがアプリケーションのパフォーマンスに大きな影響を与えることはほとんどありません。
public / private は、主に設計や保守性、安全性のために使うものです。
たとえば、次の2つのフィールドがあったとしても、
C#public int PublicValue;
private int privateValue;
アクセス修飾子の違いだけで、処理速度を気にする場面はほとんどありません。
大切なのは、パフォーマンスよりも次の点です。
| 観点 | 内容 |
|---|---|
| 安全性 | 不正な値を防げるか |
| 保守性 | 後から変更しやすいか |
| 可読性 | クラスの使い方がわかりやすいか |
| 設計 | 外部に公開する範囲が適切か |
public と private は、速度を上げるためではなく、良い設計にするために使うものです。
まとめ
C#の public と private は、アクセス修飾子の中でも特に基本となるキーワードです。
public は、クラスの外部からアクセスできるようにするために使います。
C#public void Run()
{
Console.WriteLine("実行します");
}
一方、private は、同じクラスの内部からだけアクセスできるようにするために使います。
C#private int count;
public と private の違いを整理すると、次のようになります。
| アクセス修飾子 | 意味 | 主な用途 |
|---|---|---|
| public | 外部からアクセスできる | 外部に公開するクラス、プロパティ、メソッド |
| private | クラス内部からだけアクセスできる | フィールド、内部処理、補助メソッド |
C#では、基本的にフィールドは private にし、外部から必要な操作だけを public にします。
C#public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
このようにすることで、外部から安全に値を扱えるようになります。
初心者が特に覚えておきたいポイントは、次の3つです。
publicは外部に公開するものに使うprivateはクラス内部だけで使うものに使う基本は
private、必要なものだけpublicにする
public と private は、C#のオブジェクト指向やカプセル化を理解するうえで欠かせない考え方です。
最初は難しく感じるかもしれませんが、「外に見せるものはpublic、内側に隠すものはprivate」と考えると理解しやすくなります。

