はじめに
この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した23日目の記録です。
動作環境
- PHP 7.1.16 (cli)
- Ruby 2.4.1p111 (2017-03-22 revision 58053)
本日学んだこと
- カプセル化について
- getterについて
- publicとprivate
カプセル化とは?
【混乱しがちなプログラミング専門用語】
— ウェブ系ウシジマくん (@Yuta_ushizima) 2018年7月10日
[カプセル化]
関連のあるデータとその使い方をひとまとめにしたもの。内部のデータを直接いじることはできないけど、使い方だけを見せる。
プログラミングによく出てくるクラスは、カプセル化したデータの最小単位。
メソッドはクラスの中で操作すること。
内部のデータをいじることはできないというのは、例えばiPhoneは液晶部分は操作できますが、本体の中身は基本的に特別な器具がないと開けることはできないですよね。
iPhone内部にあるパーツなどはユーザーがいじれないように隠すことで、予期せぬ故障を未然に防いでいることになります。
この隠すことを、プログラミングの専門用語でカプセル化と言います。
プログラミングにおいて、カプセル化を意識することは特に重要で、読みやすさだけでなく、堅牢性の高いコードを保つことができます。
publicとprivate
カプセル化には、publicとprivateがあります。publicに指定したメソッドなどは外部からアクセス可能ですが、privateを指定すると、呼び出す際にエラーとなります。
publicの場合
<?php
class Animal {
public $kind;
public function __construct($kind) {
$this->kind = $kind;
}
}
// ここから下は外部(クラスのスコープ外)
$penguin = new Animal('キングペンギン');
echo $penguin->kind; //=> キングペンギンが出力される
?>
class Animal
public #=>何も指定しなければrubyはデフォルトでpublicになる
attr_accessor :kind # attr_accessorでgetterとsetterをまとめて定義
def initialize(kind)
puts kind
end
end
# ここから下は外部(クラスのスコープ外)
penguin = Animal.new('キングペンギン')
puts penguin.kind #=>キングペンギンが出力される
privateの場合
<?php
class Animal {
private $kind;
public function __construct($kind) {
$this->name = $kind;
}
}
// ここから下は外部(クラスのスコープ外)
$penguin = new Animal('キングペンギン');
echo $penguin->kind; //=> エラー発生
?>
class Animal
private
attr_accessor :kind
def initialize(kind)
@kind = kind
end
end
# ここから下は外部(クラスのスコープ外)
penguin = Animal.new('キングペンギン')
penguin.kind #=>エラー発生
ゲッターについて
privateに設定したことで、外部(クラスの外)からプロパティやインスタンス変数にアクセスすることができなくなりました。
アクセスできない代わりに、その値を返すだけ(=取得する) のメソッドをクラス内で定義するのが一般的です。
その値を返すだけのメソッドをゲッターと呼びます。
なお、Rubyではゲッターとセッターをまとめてアクセサと呼んでいます。
<?php
class Animal {
private $kind;
public function __construct($kind) {
$this->kind = $kind;
}
public function getKind() {
return $this->kind;
}
}
// ここから下は外部(クラスのスコープ外)
$penguin = new Animal('キングペンギン');
echo $penguin->getKind(); //=> キングペンギン
?>
class Animal
def initialize(kind)
@kind = kind
end
def kind
@kind
end
end
# ここから下は外部(クラスのスコープ外)
penguin = Animal.new('キングペンギン')
p penguin.kind #=>キングペンギン
セッターとは?
privateに設定したことで、外部(クラスの外)からプロパティやインスタンス変数の値を変更することができなくなりました。
このままでは一度設定した値をずっと使うことになってしまうので、代わりにプロパティやインスタンス変数の値を変更するためのメソッドを定義します。
この値が変更できるように定義したメソッドがセッターになります。
<?php
class Animal {
private $kind;
private $count;
public function __construct($kind) {
$this->kind = $kind;
}
public function setCount($count) {
$this->count = $count;
}
public function getCount() {
return $this->count;
}
}
// ここから下は外部(クラスのスコープ外)
$penguin = new Animal('キングペンギン');
$penguin->setCount(3);
echo $penguin->getCount(); //=> 3
?>
class Animal
def initialize(kind)
@kind = kind
end
# ゲッター
def kind
@kind
end
# セッター
def kind=(value)
@kind = value
end
end
# ここから下は外部(クラスのスコープ外)
penguin = Animal.new('キングペンギン')
penguin.kind="イワトビペンギン" #=>代入しているように見えるけど、`kind=`メソッドの呼び出している。
p penguin.kind#=>セッターによって値が書き換わったので、キングペンギンではなく、イワトビペンギンが出力される。