Perl에서 상속은 현재 패키지가 어떤 패키지(클래스)로부터 상속되는지를 나타내는 배열 @ISA를 통해 구현됩니다. 이것은 다른 많은 언어에서의 전통적인 객체 지향(OO)과는 다르며, 오히려 메서드 검색 중 부모를 동적으로 대체하는 방식입니다.
초기 Perl 버전에서는 표준 객체 접근 방식이 없었습니다. 상속을 지원하기 위해 부모 클래스가 나열된 배열 @ISA(ISA = Is A)가 도입되었습니다. Perl은 먼저 객체 자신의 클래스에서 메서드를 찾고, 그 다음 부모 클래스에서 순서대로 검색하므로, 특정 유연성을 제공하지만 고유한 문제를 발생시킵니다.
@ISA를 통한 상속 방법은 캡슐화를 쉽게 파괴합니다. 또한, 다중 상속은 메서드 충돌을 피하기 위해 부모의 순서에 주의해야 하므로 주의가 필요합니다. 메서드 검색 순서(Method Resolution Order)는 항상 명확하지 않으며, 특히 CPAN 모듈(예: Moose, base 또는 parent의 클래스)을 사용할 때 그렇습니다.
Perl에서 간단한 상속으로 배열 @ISA를 선언합니다:
package Parent; sub hello { print "부모에게서 안녕하세요! "; } package Child; our @ISA = ('Parent'); Child::hello(); # 출력: 부모에게서 안녕하세요!
실제 프로젝트에서는 상속 작업을 간소화하고 더 많은 안전성을 위해 종종 pragma base 또는 parent를 사용합니다.
@ISA를 통해 이루어집니다.BASE-pragma 또는 배열 @ISA를 사용하여 프로그램 실행 후 자식 클래스에 부모 메서드를 추가할 수 있습니까?
아니오, Perl은 스크립트 컴파일 중에 상속을 허용하며 실행 중에는 허용하지 않습니다. 만약 실행 중에 @ISA가 변경된다면, 실제로 모든 이미 선언된 객체에 영향을 미치지 않으며, 이로 인해 이상한 문제가 발생할 수 있습니다.
package Parent; sub hello { print "부모 "; } package Child; our @ISA = ('Parent'); # 객체 생성 후 @ISA를 변경하는 것은 권장되지 않습니다.
만약 여러 부모 클래스에서 @ISA에 동일한 메서드를 선언하면 어떤 일이 발생합니까?
@ISA에 지정된 순서대로 첫 번째 발견된 메서드가 호출됩니다. 이는 특히 다중 상속 시 예기치 않은 동작을 초래할 수 있습니다.
package Base1; sub hello { print "Base1 "; } package Base2; sub hello { print "Base2 "; } package Derived; our @ISA = ('Base1', 'Base2'); Derived::hello(); # 출력: Base1
@ISA에 클래스를 동적으로 추가하고 그 메서드에 접근할 수 있습니까?
네, 가능하지만, 이는 프로그램 구조를 파괴하고 메서드 해상도 및 실행 시간 오류를 초래할 수 있으므로 극도로 권장되지 않습니다.
@ISA 변경parent/base 미사용, 유지보수성을 저하시킴프로젝트에서 프로토콜 클래스에 기능을 추가하기 위해 조건에 따라 동적으로 로드되는 모듈에서 메서드를 상속하기 위해 @ISA 배열을 수동으로 변경합니다.
장점:
단점:
클래스를 확장하기 위해 pragma parent를 사용하여 부모의 순서를 엄격히 제어하고 대체할 수 있는 메서드를 명확히 정의합니다.
장점:
단점: