オブジェクト指向: 名前空間

概要

クラスを種類ごとに分ける管理方法。
名前空間を指定する事で同名のクラスを衝突せずに参照できる。
大規模なプログラム、他人に作ったプログラムを頻繁に利用するオブジェクト指向プログラムでは必須の技術

定義・参照

・名前空間は同一ファイルに複数定義可能
・名前空間は別ファイルへの定義・参照も可能
・名前空間は複数個所に分割定義可能

namespace SpaceA
{
 class A { }
 class B { }
}

namespace SpaceB
{
 class A { }
 class B { }
}

namespace SpaceA
{
 class Program
 {
  static void Main(string[] args)
  {
   クラス名を名前空間で修飾する事でクラスを指定できる
   var a1 = new SpaceA.A();
   var a2 = new SpaceA.B();
   var b1 = new SpaceB.A();
   var b2 = new SpaceB.B();
  }
 }
}

※標準ライブラリの取込<~>
※自作ライブラリの取込"~.h"
#include "stdafx.h"
#include <string>

using namespace System;

int main(array<System::String ^> ^args)
{
  名前空間:stdのstringクラスを使用
  std::string myStr1 = "AAA";
  
  // 名前空間のインポート(記述の省略が可能)
  using namespace std;
  string myStr2 = "BBB";
  
  return 0;
}

他名前空間のクラスの利用
Imports System
Imports System.Text

名前空間の定義
Namespace VB_Program

  Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     ~
    End Sub
  End Class

End Namespace

パッケージ化
クラスを指定のパッケージに所属させること。

・パッケージ名をファイルの先頭に記述
・パッケージ名のディレクトリに保存
 myjava.java
  ├ packA\classA.java
  └ packB\classB.java

※packA\classA.java
package packA;
public class classA{}

※packB\classB.java
package packB;
public class classB{}

※myjava.java
import packA.*;
import packB.*;

public class myjava
{
 public static void main (String[] args) {
  packA.classA a = new packA.classA();
  packB.classB b = new packB.classB();
 }
}

staticインポート
package com.A;
public class MyClass{
  public static void myMethod(){}
}

package com.B;
import static com.A.MyClass.test;

public class Main {
  public static void main(String[] args) {
    test();
    別パッケージ、別クラスのstaticメソッドを自クラスのメソッドの様に扱える
  }
}

namespace nameA\classA;

読み込み(重複未許可)
require_once("(名前空間)\ファイル名");
require_once("nameA\classA.php");

読み込み(重複許可)
include("(名前空間)\ファイル名");
include("nameA\classA.php");

Loop中の使用
include:○
require:×

エラー時
include:続行
require:停止

名前空間の省略(using/import)

using SpaceA;
using SpaceB;
namespace SpaceA{ class A { } }
namespace SpaceB{ class B { } }

namespace SpaceC
{
 class Program
 {
  static void Main(string[] args)
  {
   名前空間を省略できる
   var a = new A();
   var b = new B();
  }
 }
}

using SpaceA;
using SpaceB;
namespace SpaceA{ class X { } }
namespace SpaceB{ class X { } }

namespace SpaceC
{
 class Program
 {
  static void Main(string[] args)
  {
   クラスXは名前空間SpaceAとSpaceBに属している為競合する
   var a = new X(); //エラー
   var b = new X(); //エラー
   
   var a = new SpaceA.X(); //OK
   var b = new SpaceB.X(); //OK
  }
 }
}

require_once 'src/name_child/classC.php';

use src\name_child\classC;

$c = new src\name_child\classC();

$c = new classC();

別名

名前空間の別名を定義
using MyA_name = SpaceA;
名前空間に属するクラスの別名を定義
using MyA_class = SpaceA.A;

namespace SpaceA
{
 class A { public A(int prm){ } }
}

namespace SpaceC
{
 class Program
 {
  static void Main(string[] args)
  {
   MyA_name.A a = new MyA_name.A(prm: 5);
   MyA_class a = new MyA_class(prm: 5);
  }
 }
}

ネスト

ネスト=入れ子

名前空間のネスト

namespace SpaceA
{
 class A { public C(int prm) { } }

 namespace SpaceB
 {
  class B { public D(int prm) { } }
 }
}

namespace SpaceC
{
 class Program
 {
  static void Main(string[] args)
  {

   SpaceA.A a = new SpaceA.A(prm: 5);
   
   SpaceB.B b = new SpaceB.B(prm: 5);
   コンパイルエラー:ネストされた名前空間は直接参照できない
   
   SpaceA.SpaceB.B b = new SpaceA.SpaceB.B(prm: 5);
   OK
  }
 }

}

ネストされた名前空間の競合

using SpaceA;
using SpaceB;

namespace SpaceA
{
 namespace SpaceX
 {
  class X { public X(int prm) { } }
 }
}

namespace SpaceB
{
 namespace SpaceX
 {
  class X { public X(int prm) { } }
 }
}

namespace SpaceC
{
 class Program
 {
  static void Main(string[] args)
  {

   X x = new X(prm: 5);
   コンパイルエラー:ネストされた名前空間は直接参照できない

   
   SpaceX.X x = new SpaceX.X(prm: 5);
   コンパイルエラー:spaceAとspaceBで競合

   
   SpaceA.SpaceX.X xA = new SpaceA.SpaceX.X(prm: 5); OK
   SpaceB.SpaceX.X xB = new SpaceB.SpaceX.X(prm: 5); OK
  }
 }

}