メソッド (計算機科学)
インスタンスメソッドとクラスメソッド > インスタンスメソッドとクラスメソッドの例 > Smalltalkによる例

Smalltalkによるインスタンスメソッドとクラスメソッドの例を示す。
Object
	subclass:		#MethodSample
	instanceVariableNames:	'name'		"インスタンスオブジェクトに持たせるインスタンス変数"
	classVariableNames:	''		"クラスオブジェクトとクラスオブジェクト直属のインスタンスオブジェクトの間で共有するクラス変数"
	poolDictionaries:	''		"クラスオブジェクトとインスタンスオブジェクトの間で共有するプール変数"
	category:		'Example'.
 

"インスタンスオブジェクトのインスタンス変数を操作するメソッド(インスタンスメソッド)"
MethodSample methodsFor: 'accessing'
!
givenName

	^ name.
!
givenName: aString

	name := aString.
!!

"インスタンスオブジェクトとクラスオブジェクトを操作するメソッド(インスタンスメソッド)"
MethodSample methodsFor: 'inter-accessing'
!
name

	^ self givenName, ' ', self class familyName. 
!!

MethodSample class instanceVariableNames: 'name'.	"クラスオブジェクトに持たせるインスタンス変数"

"クラスオブジェクトのインスタンス変数を操作するメソッド(クラスメソッド)"
MethodSample class methodsFor: 'accessing'
!
familyName
	^ name.
!
familyName: aString

	name := aString.
!!

MethodSample class methodsFor: 'instance creation'
!
withGivenName: aString

	^ self
		new
			givenName: aString;
			yourself.
!!
インスタンスメソッドを実行するには、まずインスタンスオブジェクトを生成しなければならない:
| objectA objectB |

objectA := MethodSample withGivenName: 'John'.
objectB := MethodSample withGivenName: 'Joe'.
上の例では #withGivenName: により二つのインスタンスオブジェクトを生成し変数 objectA と objectB に代入している。この時点で、objectA とobjectB のインスタンス変数 name にはそれぞれ "John" と "Joe" が代入されている。
インスタンスメソッドを実行するには次のように記述する:
objectA givenName.	"'John' を返す"
objectB givenName.	"'Joe' を返す"
上の例では objectA と objectB それぞれのインスタンスオブジェクトに対し #givenName メッセージを送りインスタンスメソッドを実行している。それぞれのメソッドの返り値が異なることから、同じクラスオブジェクトに属するインスタンスオブジェクトでもインスタンス変数が持つ値は、インスタンスオブジェクト毎に異なることがわかる。
一方、クラスメソッドを実行するには、クラスオブジェクトに直接属しているため、インスタンスオブジェクトの代わりにクラスオブジェクトに対してメッセージを送る。
クラスメソッドを実行するには次のように記述する:
type := MethodSample
type familyName: 'Hillton'.
type familyName.		"'Hillton' を返す".
上の例では typeにクラスオブジェクトMethodSampleを代入して、#familyNameと#familyName:メッセージを送りクラスメソッドを実行している。
クラスオブジェクトのインスタンス変数 name は、インスタンスオブジェクトのインスタンス変数と異なり MethodSample に属する全てのインスタンスオブジェクトで共有される。
クラスオブジェクトのインスタンス変数が共有される例を示す:
| type objectA objectB |

type := MethodSample

objectA := type withGivenName: 'John'.
objectB := type withGivenName: 'Joe'.

"#nameはクラスオブジェクトに#familyNameを送っているため、異なるインスタンスオブジェクトでも'Hillton'が共有されている。"
type familyName: 'Hillton'.
objectA name.	"'John Hillton'を返す"
objectB name.	"'Joe Hillton'を返す"
クラスメソッドは、変数に代入せず直接クラス名を指定して呼び出すことが多い。特にクラスがオブジェクトではない言語においては、直接クラス名を指定する書き方しかできない。
直接クラス名を指定したクラスメソッドの呼び出しは次のように記述する:
MethodSample familyName: 'Hillton'.
MethodSample familyName.		"'Hillton' を返す".
なお、MethodSample のインスタンスオブジェクト生成するときに使用した new もクラスメソッドである。
一般的にインスタンスオブジェクトを生成する場合には new という特別な演算子を用いる言語が多い。しかし、Smalltalkの影響が強い言語やRuby等いくつかの言語ではクラスメソッドによりインスタンスオブジェクトを生成する。クラスメソッドによりインスタンスオブジェクトを生成する言語の場合、newを独自の実装に変更することができる。例えばnewを実行したとき、別のクラスオブジェクトに属するインスタンスオブジェクトを返すようにすることができる。C++のようにnewが演算子でありながら、クラスメソッド (静的メンバー関数) としてnewを定義できる言語もある。
クラスがオブジェクトになっている言語の場合、インスタンスもクラスも同じオブジェクトとして扱われるため、インスタンスメソッドとクラスメソッドでメッセージの送り方に区別はない。インスタンスメソッドの代わりにクラスメソッドを呼び出すことも、クラスメソッドの代わりにインスタンスメソッドを呼び出すこともできる。どちらのメソッドを呼び出すかは、メッセージを送った変数にインスタンスとクラスのうち、どちらのオブジェクトを代入していたかで決まる。
多くの言語ではインスタンスメソッドとクラスメソッドは同じシグネチャ (signature: 名前と引数) を定義できる。SmalltalkやObjective-Cなどメッセージが存在する言語ではメソッドの多重定義ができないため一見無理なように見えるが、メソッドが所属するオブジェクトがインスタンスとクラスで異なるため、同一のシグネチャでインスタンスメソッドとクラスメソッドを定義することができる。