2015-01-15 2 views
1

나는 C++에서오고 있으며 Java에서 일반 매개 변수 유형을 상속하려고합니다. 기본적으로, 나는 아래의 C++ 패턴을 모방하기 위해 노력하고있어 :Java 확장 일반 유형 매개 변수

C++에서를, 내가 할 수있는 :

#include <iostream> 

class Node 
{ 
     Node* next; 
}; 


class BaseVisitor 
{ 
    public: 
     BaseVisitor(Node* ptr) 
     { 
      std::cout<<ptr<<"\n\n"; 
      delete ptr; 
     } 
     ~BaseVisitor() {}; 

    protected: 
     virtual Node* Generate() = 0; 
}; 


class DynamicVisitor : public BaseVisitor 
{ 
    public: 
     DynamicVisitor(Node* ptr) : BaseVisitor(ptr) {} 

    protected: 
     virtual Node* Generate() 
     { 
      std::cout<<"Dynamic Visitor\n"; 
      return new Node(); 
     } 
}; 

class StaticVisitor : public BaseVisitor 
{ 
    public: 
     StaticVisitor(Node* ptr) : BaseVisitor(ptr) {} 

    protected: 
     virtual Node* Generate() 
     { 
      std::cout<<"Static Visitor\n"; 
      return NULL; 
     } 
}; 



template<typename T> 
class TestVisitor : public T //THIS is where the magic happens.. 
{ 
    public: 
     TestVisitor() : T(this->Generate()) {} //allows me to call "Generate". 
}; 

int main() 
{ 
    TestVisitor<DynamicVisitor> foo = TestVisitor<DynamicVisitor>(); 
    TestVisitor<StaticVisitor> bar = TestVisitor<StaticVisitor>(); 
} 

출력 :

나는 자바에서 같은 일을 할 수있는 방법
Dynamic Visitor 
0x605ed0 

Static Visitor 
NULL 

? 나는 시도 :이 패턴은 무엇을

public class Node { 
    Node next; 
} 

public abstract class BaseVisitor { 
    public BaseVisitor(Node n) {System.out.println(n);} 

    protected abstract Node generate(); 
} 

public class DynamicVisitor extends BaseVisitor { 
    public DynamicVisitor(Node n) { 
     super(n); 
    } 

    @Override 
    protected Node generate() { 
     return new Node(); 
    } 
} 

public class StaticVisitor extends BaseVisitor { 

    public StaticVisitor(Node n) { 
     super(n); 
    } 

    @Override 
    protected Node generate() { 
     return null; 
    } 
} 

public class TestVisitor<T extends BaseVisitor> extends T { //error.. Cannot extend "T".. No magic happens.. 
    public TestVisitor() { 
     super(this.generate()); //cannot call generate().. 
    } 
} 
  1. 라고? 나는 그것을 "Base Factory"패턴이라고 부르지 만 실제 이름이 확실하지 않으므로 무엇을 검색해야할지 확신하지 못했습니다.

  2. Java에서 C++과 동일한 작업을 수행하려면 어떻게해야합니까? Java에서 동일한 패턴을 수행하는 "방법"이 있습니까?

+0

: 여분의 인터페이스 및 클래스하지 않고,

자바 8에서
public interface NodeGenerator { Node generate(); } public class StaticGenerator implements NodeGenerator { public Node generate() { return null; } } public class DynamicGenerator implements NodeGenerator { public Node generate() { return new Node(); } } public class TestVisitor extends BaseVisitor { public TestVisitor(NodeGenerator g) { super(g.generate()); } } 

,이 좋네요 (하지만 아마도 덜 효율적) 볼 수 있습니다 : 가장 가까운는 "위임 패턴", 아마이다 C++은 zing하는 동안 java가 zing합니다. C++에서 템플릿은 기본적으로 환상적인 선행 처리 매크로이며, 다른 런타임 객체가 생성됩니다. 자바에서는 런타임에 템플릿 매개 변수가 삭제 된 형식의 클래스가 하나만 있습니다. 그것은 위와 같은 일을하는 것을 금지합니다. 그러나 익명의 클래스 나 java 8 람다를 사용하여 솔루션을 찾을 수 있습니다. –

답변

1

아니요, 자바에서는 이것을 할 수 없습니다. 죄송합니다. 의

public class TestVisitor extends BaseVisitor { 
    public TestVisitor(Supplier<Node> g) { super(g.get()); } 
} 

// ... and then you can do things like 

TestVisitor staticVisitor = new TestVisitor(() -> null); 
TestVisitor dynamicVisitor = new TestVisitor(() -> new Node()); 
+0

왜 당신은 그것이 덜 효율적이라고 제안합니까? –

+0

글쎄, 내가 어떻게 "정확하게"구현되었는지에 대해 확신하지 못하기 때문에 "가능하다"고 말했다. 내가 생각한 바는 다음과 같다 :'NodeGenerator ng = new StaticNodeGenerator(); for (int i = 0; i <10000; i ++) {new TestVisitor (ng); }'for'(int i = 0; i <10000; i ++) {new TestVisitor (() -> null); }'. 후자의 접근 방식은 10000 개의 더 많은 객체 (피할 수 있음)를 할당하고, * 아마도 *는 추가로 익명의 클래스를 10000 개 (어쩔 수없이) 생성 할 것입니다. – Dima

+0

첫 번째 예제를 익명 클래스로 대체하고 java 8 버전만큼 간결한 코드를 얻을 수 있습니다! –