2010-08-10 4 views
3

인자가없는 init 메소드를 가진 기본 Entity 클래스가있는 게임이 있다고 상상해보십시오. 이제 마법사 클래스가 생겼으나 속도와 강도 등 2 개의 매개 변수를 전달하려고합니다. AS3에서 (그리고 나는 Java와 C#을 믿는다.)이 작업을 수행 할 수 없다. 메소드 서명이 일치하지 않기 때문에 "호환되지 않는 대체"이다. 이제 대신 "initWizard"메서드를 만들 수 있지만 각 클래스의 init 메서드에 문제가있어 이름이 다를 수 있습니다.사람들은 수퍼 클래스에 다른 수의 인수를 필요로하는 하위 클래스 init 메서드를 어떻게 사용합니까?

저는 AS3, Java 또는 C#에서 작동하는 솔루션이 필요합니다.

+0

나는이 C# 및 자바의 문제라고 생각하지 않습니다. 생성자는 클래스에 속하며 재정의되지 않습니다. 대신 하위 클래스는 적절한 수의 메소드로 수퍼 클래스의 생성자를 호출합니다. 질문은 AS3과 관련되어 있으므로 태그를 지정해야합니다. – Kurt

+0

아니 내 실수했다 - 생성자가 인수의 다른 번호를 가질 수 있습니다 - 여전히 초기화 방법에 대한 답변이 필요합니다. – Iain

+0

Java에서는 동일한 이름이지만 매개 변수의 수가 다르거 나 숫자가 같지만 유형이 다른 여러 메소드를 작성할 수 있습니다. 매개 변수의 수와 유형에 따라 적절한 메소드가 호출됩니다. 예에서 마법사의 init는 Entity의 init을 재정의하지 않습니다. 마법사는 Entity가 가지고 있지 않은 메서드를 가지고 있습니다. – Kwebble

답변

1

귀하의 질문을 정확하게 이해하지 못했습니다. 그러나 자바에서 다음과 같은 컴파일 : 나는 B#init(int,int)A#init(int)의 재정의하지 않고, B#init(int) 여전히 호출 할 수 있음에 동의하지만

public class A { 
    public void init(int a) {} 
} 

public class B extends A { 

    public void init(int a, int b) 
    { 
     super.init(a); 
    } 
} 

. 실제로는 B#init(int)의 존재를 숨길 수는 없지만, 기껏해야 B으로 무시하고 호출하면 예외를 throw 할 수 있습니다.

그러나 큰 문제입니까? 메서드 시그니처는 클래스 사용 방법 계약의 일부만 캡처합니다. 코드를 좀 더 방호하고 싶다면 팩토리 메서드를 사용하여 A 또는 B의 인스턴스를 만들고 init을 보호 할 수 있습니다.

public class A { 
    protected void init(int a) {} 

    static public A create(int a) 
    { 
     A o = new A(); 
     o.init(a); 
     return o; 
    } 
} 

public class B extends A { 

    protected void init(int a, int b) 
    { 
     super.init(a); 
    } 

    static public B create(int a, int b) 
    { 
     B o = new B(); 
     o.init(a, b); 
     return o; 
    } 
} 
+0

고마워요. 기본적으로 저는 단지 내가 미쳤거나 AS3가 중요한 것을 놓치고 있는지 알고 싶었습니다. 이번에는 AS3가 중요한 것을 놓치고 있다는 대답이 있습니다. – Iain

6

AS3 메소드 오버로딩을 지원하지 않지만, 솔직히, 메소드 오버로딩은 단지 문법 설탕이며, 보통 모호함과 불일치를 소개합니다. 자바에서

는 메소드는 이름으로, AS3에서 그 이름과 서명에 의해 결정되지만, 의미,

protected void init(int a) 
protected void init(int a, int b) 

protected void init1(int a) 
protected void init2(int a, int b) 

사이에만 약간의 차이에있다 AS3에서는 클래스 당 하나의 생성자 만 이름 당 하나의 메소드가 될 수 있습니다. 그러나 생성자는 호환 가능한 서명이 필요하지 않습니다. AS3에서는이 같은 문제를 해결할 것 :

package { 
class A { 
    private var a:int; 
    public function A(a:int) { 
    this.a = a; 
    } 
    // ... probably some meaningful methods here :) 
} 
} 
package { 
class B extends A { 
    private var b:int; 
    public function B(a:int, b:int) { 
    super(a); 
    this.b = b; 
    } 
    // ... probably some other meaningful methods here as well :D 
} 
} 

당신은 또한 ewernli 제시 자바 솔루션의 문제를 피할 수 있습니다.

편집 : 그냥 보았습니다. 생성자를 사용하지 않고 대신 다른 서명으로 초기화 메소드를 사용하는 것이 좋습니다. 왜? 이는 Liskov substitution principle을 위반하는 것입니다.

EDIT2 : 나는 당신이 두 가지 옵션이 있습니다 가정 : 좋은 아닌 초기화에 대한

  1. 다른 이름을 (아이디어의 가장, 또한 서브 클래스는 부분적으로 만 작동하는지, 초기화를 노출하지 않습니다 때문에 (, 위에서 언급 한 LSP 참조)).
  2. 철학에 따라 생활하며, 모든 수업은 추상적이거나 최종이어야합니다.예 (공간 게임을 가정) :

추상 기본 클래스, 여러 구상 서브 클래스 : 지금

class ShipBase {//in Java you might wanna put the 'abstract' keyword just infront 
//... implementation of some sort 
//... maybe a protected intializer to call by subclasses 
//... no public initializer, since class is abstract 
} 
final class Fighter extends ShipBase { 
//... public initializer specific to Fighter 
//... other custom behaviour 
} 
final class Bomber extends ShipBase { 
//... I guess, this is obvious 
} 

당신이 자신을 요청할 수 있습니다 : 내가 무엇을 원하는 경우 Fighter를 기본 클래스로 (하자에 대한 예 : EliteFighter2000) 인스턴스화 가능한 클래스도 있습니다. 단순한. 단지 그렇게 할 필요는 없습니다.

class FighterBase extends ShipBase { 
    //... implementation of whatever kind of things fighters have in common 
    //... a protected intializer to call by subclasses  
} 
final class Fighter extends FighterBase { 
    //... public initializer possibly just forwarding to protected initializer 
} 
final class EliteFighter2000 extends FighterBase { 
    //... here goes all the 'elite' stuff 
} 

이것은 더 유연합니다. EliteFighter2000에 영향을 미치지 않고 간단한 Fighter을 변경하거나 FighterBase을 수정하여 모든 전투기의 공통적 인 동작을 변경하기로 결정할 수 있습니다. 상속은 일반적으로 위험한 것이며, 종종 오해되고 오용됩니다.
일반적으로이 규칙을 따르면 미묘한 문제를 피하는 데 도움이되지만, 종종 상당히 멀리 도달하는 커플 링 상속은 우려의 분리가 없기 때문에 발생할 수 있습니다. 이 경우 전투기에 공통적 인 것이 모두 FighterBase에 구현되어야하며 단순한 Fighters에 해당하는 항목은 모두 속합니다.

greetz
back2dos

+0

그래서 개체 풀링을 사용할 수 있습니다. 개체를 새로 작성한 것처럼 개체를 다시 초기화 할 수 있어야합니다. – Iain

+0

@Iain : 게시물이 업데이트되었습니다. – back2dos

관련 문제