C ++과 Java가 유형 계층 구조와 유형 분류 체계에 관한 것이라면 Go는 구성에 관한 것입니다.
C ++과 Java가 유형 계층 구조와 유형 분류 체계에 관한 것이라면 Go는 구성에 관한 것입니다.
답변:
그는 다음과 같은 순서로 무언가를 사용할 것을 의미합니다.
class A : public B {};
Java 또는 C ++와 같은 Go에서는 다음과 같은 것을 사용합니다.
class A {
B b;
};
예, 이것은 상속과 같은 기능을 제공합니다. 위의 예제를 약간 확장 해 봅시다 :
struct B {
int foo() {}
};
struct A {
B b;
};
A a;
a.foo(); // not allowed in C++ or Java, but allowed in Go.
그러나이 작업을 수행하려면 C ++ 또는 Java에서 허용되지 않는 구문을 사용합니다. 임베드 된 오브젝트를 자체 이름없이 남겨두면 다음과 같습니다.
struct A {
B;
};
이 질문 / 문제는 이것 과 비슷합니다 .
Go에서는 실제로 OOP가 없습니다.
객체를 "특수화"하려면 컴포지션 인 임베드를 사용하여 수행하지만 일부 장점 은 상속과 부분적으로 유사합니다. 당신은 이것을 이렇게합니다 :
type ConnexionMysql struct {
*sql.DB
}
이 샘플에서 ConnexionMysql은 일종의 * sql.DB의 특수화이며 ConnexionMysql에서 * sql.DB에 정의 된 함수를 호출 할 수 있습니다.
type BaseMysql struct {
user string
password string
database string
}
func (store *BaseMysql) DB() (ConnexionMysql, error) {
db, err := sql.Open("mymysql", store.database+"/"+store.user+"/"+store.password)
return ConnexionMysql{db}, err
}
func (con ConnexionMysql) EtatBraldun(idBraldun uint) (*EtatBraldun, error) {
row := con.QueryRow("select pv, pvmax, pa, tour, dla, faim from compte where id=?", idBraldun)
// stuff
return nil, err
}
// somewhere else:
con, err := ms.bd.DB()
defer con.Close()
// ...
somethings, err = con.EtatBraldun(id)
따라서 첫눈에이 구성은 일반적인 분류 체계를 만드는 도구라고 생각할 수 있습니다.
그러나
* sql.DB에 정의 된 함수가 * sql.DB에 정의 된 다른 함수를 호출하면 ConnexionMysql에 재정의 된 함수가 존재하더라도이를 호출하지 않습니다.
고전 상속을 사용하면 종종 다음과 같은 작업을 수행합니다.
func (db *sql.DB) doComplexThing() {
db.doSimpleThing()
db.doAnotherSimpleThing()
}
func (db *sql.DB) doSimpleThing() {
// standard implementation, that we expect to override
}
즉, doComplexThing
수퍼 클래스에서 전문화 요청에 대한 조직으로 정의 합니다.
그러나 Go에서는 특수 함수가 아니라 "수퍼 클래스"함수를 호출합니다.
따라서 * sql.DB에 정의되었지만 ConnexionMySQL (또는 기타 전문화)에 재정의 된 일부 함수를 호출해야하는 알고리즘을 원한다면이 알고리즘을 * sql.DB의 함수로 정의 할 수는 없지만 다른 곳에 정의해야합니다. 이 기능은 제공된 전문화에 대한 호출 만 작성합니다.
인터페이스를 사용하여 이와 같이 할 수 있습니다.
type interface SimpleThingDoer {
doSimpleThing()
doAnotherSimpleThing()
}
func doComplexThing(db SimpleThingDoer) {
db.doSimpleThing()
db.doAnotherSimpleThing()
}
func (db *sql.DB) doSimpleThing() {
// standard implementation, that we expect to override
}
func (db ConnexionMySQL) doSimpleThing() {
// other implemenation
}
이것은 클래스 계층의 기존 재정의와는 상당히 다릅니다.
특히 두 번째 수준에서 함수 구현을 상속하는 세 번째 수준을 직접 가질 수는 없습니다.
실제로는 대부분 (직교) 인터페이스 사용을 끝내고 구현의 "수퍼 클래스"가 호출을 구성하는 대신 제공된 구현에서 호출을 구성하도록합니다.
내 경험상, 이것은 한 수준보다 더 깊은 계층이 실제로 존재하지 않게합니다.
다른 언어에서는 개념 A가 개념 B의 특수화라는 것을 볼 때 클래스 B와 클래스 A를 B의 서브 클래스로 작성하여이 사실을 구체화하는 경우가 종종 있습니다. 데이터를 중심으로 프로그래밍하면 코드에서 객체의 분류 체계를 재생산하는 데 시간이 걸리며 이것이 현실이라는 원칙에 따릅니다.
Go에서는 일반 알고리즘을 정의하고 전문화 할 수 없습니다. 일반 알고리즘을 정의하고 일반 알고리즘을 제공하고 제공된 인터페이스 구현과 작동하는지 확인해야합니다.
코더가 복잡한 해킹을 통해 복잡성이 해킹되어 로직이 최종적으로 모든 레벨을 암시하는 알고리즘을 수용하려고 시도함에 따라 점점 더 복잡 해지는 것에 놀랐습니다. 애플리케이션 모델의 개념을 수정하는 대신 생각해야합니다.