클래스를 통해 특정 항목을 나타낼 수있는 기본 패키지와이 기능을 확장하려는 다른 패키지가 있다고 가정하면 szenario가 주어집니다. 외국 패키지에서 메소드를 오버로드하는 방법
(defpackage :test
(:use :cl)
(:nicknames :test)
(:export a-test-class
method-a
slot-a))
(in-package :test)
(defclass a-test-class()
((slot-a
:initform 42
:reader slot-a)))
(defmethod method-a ((a-test-class a-test-class))
(setf (slot-value a-test-class 'slot-a) 21)
a-test-class)
(defpackage :exttest
(:use :cl)
(:export extended-a-test-class
method-a))
(in-package :exttest)
(defclass extended-a-test-class (test:a-test-class)
((slot-b
:reader slot-b
:initform nil)))
(defmethod method-a ((a-test-class extended-a-test-class))
(setf (slot-value a-test-class 'slot-a) 23)
a-test-class)
지금 난 정말 anthying하지만
a-test-class
및
extended-a-test-class
의 인스턴스의 목록을 통해 가서 자신의 유형에 각각이를 변경할 기대, 그들 모두에
method-a
를 호출하도록되어하지 않는 기능을 얻었다. 예 :
(slot-a (method-a a-test-class-instance)) > 21
및
(slot-a (method-a extended-a-test-class-instance)) > 23
그러나이 일을하려고, 나는 제대로 방법-A를 호출의 문제로 실행 등 :
(defparameter *test-instance* (make-instance 'test:a-test-class))
(defparameter *ext-test-instance* (make-instance 'exttest:extended-a-test-class))
(test:slot-a (test:method-a *test-instance*))
> 21
(test:slot-a (test:method-a *ext-test-instance*))
> 21
또는
(test:slot-a (exttest:method-a *test-instance*))
(test:slot-a (exttest:method-a *ext-test-instance*))
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1002B03193}>:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION EXTTEST:METHOD-A (1)>
when called with arguments
(#<TEST:A-TEST-CLASS {10041148A3}>)
은 둘 다 정말 같이 나를 위해 작동하지 않습니다 컴파일 할 수 없거나 메소드의 효과가 원하는대로되지 않습니다. 클래스와 메소드 정의가 같은 패키지에 있다면 모든 것이 잘 작동합니다.
따라서 : 해당 패키지를 처리 할 필요없이 인스턴스에서 메소드를 호출하려면 어떻게해야합니까? 어떤 출력 내가 좋겠,에 "작업"예를 들어
(나는 그렇게 할 수 아니에요, 난이 공통 리스프에서 OO - 프로그래밍에 대한 나의 기대는 잘못된 얼마나 알고 싶습니다)이 C++ 프로그램을 코딩했습니다. CLOS는 메소드가 클래스에 "속하지"않는다는 사실 때문에 "일반적인"객체 지향 시스템과는 다른 것으로 알려져 있습니다. 하지만 (어떻게 든)에 대한 객체 지향 시스템을 기대하는 행동을 할 수있을 것입니다 /이처럼 사용할 수 :
#include <iostream>
namespace test {
class sub {
public:
virtual sub* method_a() = 0;
};
class a_test_class : public sub
{
protected:
int value;
public:
a_test_class(int val) : value(val) {
}
a_test_class* method_a() {
value = 21;
return this;
}
int get_value() {
return value;
}
};
}
namespace exttest {
class extended_a_test_class : public test::a_test_class {
public:
extended_a_test_class(int val) : a_test_class(val) { }
extended_a_test_class* method_a() {
std::cout << "calling overloaded method" << std::endl;
this->value = 23;
return this;
}
};
}
int main(int argc,const char* argv[]) {
test::a_test_class* atc = new test::a_test_class(42);
test::a_test_class* eatc = new exttest::extended_a_test_class(42);
std::cout << atc->method_a()->get_value() << std::endl;
std::cout << eatc->method_a()->get_value() << std::endl;
delete atc;
delete eatc;
}
> ./a.out
21
calling overloaded method
23
메소드는 클래스에 속하지 않을 수 있지만 일반 함수에 속합니다. 일반적인 메소드를 정의하기 전에 (defgeneric을 사용하여) 일반 함수를 정의하는 것이 일반적으로 도움이된다는 것을 알게되었습니다. 최소한 SBCL은 암시 적으로'defmethod'로 제네릭 함수를 생성 할 때 경고를줍니다. 그게 너를 도왔을거야. – Svante
@Svante 새 일반 메서드가 정의되어 있음을 알았지 만이를 방지하는 방법을 알지 못했습니다. 그러나 여전히 귀중한 조언, 감사합니다. – Sim