본문 바로가기
프로그래밍/PHP

PHP 클래스 상속(Inheritance)

by pentode 2018. 4. 9.

이번에 알아볼 내용은 PHP 에서 클래스(class)를 사용할 때 객체간에 부모, 자식 관계를 가지도록 해주는 상속(inheritance)에 대해서 알아보겠습니다.

 

상속(inheritance)을 부모 - 자식 관계로 표현하는 것은 무리가 없어 보입니다. 자식이 부모로부터 뭔가를 물려 받는것이 상속이기 때문입니다. 중요한 것은 자식이 부모로부터 모든 것을 물려 받았기 때문에 자식은 원래 자신의 것도 있고, 물려 받은것도 있으므로 부모보다 더 많은 것을 가진다는 것입니다.

 

프로그래밍 언어적인 측면에서의 설명은 좀 다르게 할 수 있습니다. 어떤 객체를 만드는데 있어서 공통적인 부분을 뽑아서 부모로 하고, 개개의 객체에 특징적인 부분은 자신이 가지고 있도록 만드는 것이 상속 관계가 됩니다. 부모, 자식간에 재산을 물려 주는 것과 비슷한 부분이 있어 상속이라는 말을 붙인것 같습니다.

 

예를 들어 보겠습니다.

 

사각형(Rectangle) 클래스와 삼각형(Triangle)클래스를 만들어 보겠습니다. 기본적인 클래스의 작성 방법은 "PHP 클래스(class) 기본 사용하기" 를 참조하세요.

 

사각형(Rectangle)과 삼각형(Triangle) 클래스는 점 네 개와 점 세 개를 가지고, draw 메소드가 호출되면 이 점들을 이어서 도형을 그린다고 가정합니다. 점은 Point 클래스로 만들어 졌습니다. 멤버로 점의 x, y 좌표 를 가지고 있습니다. 멤버 변수를 private 로 선언해서 외부에서 직접 다룰 수 없도록 캡슐화(encapsulation ) 해야 겠지만 여기서는 코드를 단순화하기 위해서 멤버를 public 으로 선언했습니다.

 

사각형 객체가 멤버로 점 객체를 가지는 것처럼 한 객체가 다른 객체를 멤버 변수로 가지는 것을 객체간에 "has-a" 관계가 있다고 합니다. "Rectangle has a Point" 가 되는 것입니다.

 

<?php
class Point {
	public $xpos;
	public $ypos;
	public function __construct($x, $y) {
		$this->xpos = $x;
		$this->ypos = $y;
	}
}

class Rectangle {
	public $pointArray;
	public function __construct($points) {
		$this->pointArray = $points;
	}

	public function draw() {
		print_r($this->pointArray);
		echo("draw rectangle");
	}
}

class Triangle {
	public $pointArray;
	public function __construct($points) {
		$this->pointArray = $points;
	}

	public function draw() {
		print_r($this->pointArray);
		echo("draw triangle");
	}
}

$rect = new Rectangle(array(new Point(0, 0), new Point(5, 0), new Point(5, 5), new Point(0, 5)));
$tri = new Triangle(array(new Point(1, 0), new Point(2, 1), new Point(0, 1)));

$rect->draw();
$tri->draw();
?>

 

 

사각형 클래스와 삼각형 클래스는 공통으로 점에 대한 배열을 가지고 있습니다. 이러한 공통을 부모 객체로 뽑아내어서 상속 관계를 만들어 보겠습니다. 부모가 될 클래스의 이름을 Shape 라고 하겠습니다. 이런 상속관계를 "is-a" 관계라고 합니다. "Rectangle is a Shape" 가 되겠습니다.

 

<?php
class Shape {
	protected $pointArray;

	public function __construct($points) {
		$this->pointArray = $points;
	}
}

class Rectangle extends Shape {
	public function draw() {
		print_r($this->pointArray);
		echo("draw rectangle");
	}
}

class Triangle extends Shape {
	public function draw() {
		print_r($this->pointArray);
		echo("draw triangle");
	}
}
?>

 

멤버가 가질 수 있는 접근제어자는 public, protected, private 입니다. Shape 클래스의 $pointArray 는 protected로 선언했습니다. protected 는 상속시에만 접근가능하게 됩니다. 외부 에서는 접근할 수 없고, 자식 객체인 Rectangle와 Triangle 에서는 자신의 멤버 변수 처럼 $this->pointArray 로 사용할 수 있습니다.

 

public 으로 선언이 되었다면 자식 객체에서 동일하게 사용할 수 있고, 외부에서도 동일하게 사용할  수 있습니다. 만약 private로 선언이 되었다면 상속이 되지 않습니다. 자식 클래스에서 봤을 때는 없는 것과 같습니다.

 

멤버 변수 뿐만아니라 메소드와 생성자도 상속이 됩니다. 접근제어자도 멤버변수와 동일하게 동작합니다. 생성자도 상속이되므로 상속관계 이전과 동일하게 객체를 생성할 수 있습니다.

 

자식 클래스에도 생성자를 작성하면 부모의 생성자가 상속되지 않습니다. 이부분은 오버라이딩을 알아볼때 다시 나오게 되겠습니다.

반응형