자바스크립트 인터페이스 구현






1. 제약사항(C# 기준)


1. 스스로의(추상클래스 자신) 객체를 가질 수 없다.

2. 선언된 인터페이스의 메서드는 상속받은 일반클래스(구현클래스)에서 반드시 전부 구현되어야 한다.

3. 추상클래스와 달리 일반 속성(Attribute) 및 메서드(Method)를 정의할 수 없다.

4. 다중상속이 가능하다.




2. 다중상속 예제 코드:


01: using System;
02: 
03: namespace ConsoleApplication2
04: {
05:         interface IMy
06:         {
07:                 void abc();
08:         }
09: 
10:         interface IYou
11:         {
12:                 void abc();
13:         }
14: 
15:         class CMy : IMy, IYou
16:         {
17:                 void IMy.abc()
18:                 {
19:                         Console.WriteLine("My");
20:                 }
21: 
22:                 void IYou.abc()
23:                 {
24:                         Console.WriteLine("You");
25:                 }               
26:         }
27: 
28:         class Program
29:         {
30:                 static void Main(string[] args)
31:                 {
32:                         CMy m = new CMy();
33:                         ((IMy)m).abc();
34:                         ((IYou)m).abc();
35:                 }
36:         }
37: }



출처: http://blog.naver.com/PostView.nhn?blogId=thx4alice&logNo=110023547339




3. 자바스크립트 인터페이스 구현


// IUser 인터페이스
var IUser = (function(){
	
	var iUser = function(){
		
		// 자기 자신의 객체 생성을 막기 위한 추가 소스
		if (this.constructor === iUser){
			throw new Error('정의된 인터페이스는 자기 자신의 객체를 가질 수 없습니다.');
		}
		else{
			return this;
		}
	};

	var prototype_members = { 
		// 메서드
		getId: function(){
		},
		setId: function(){
		}
	};
	
	for (var n in prototype_members) iUser.prototype[n] = prototype_members[n];
	
	return iUser;
	
})();


// IBoard 인터페이스
var IBoard = (function(){
	
	var iBoard = function(){
		
		// 자기 자신의 객체 생성을 막기 위한 추가 소스
		if (this.constructor === iBoard){
			throw new Error('정의된 인터페이스는 자기 자신의 객체를 가질 수 없습니다.');
		}
		else{
			return this;
		}	
	}

	var prototype_members = { 
		// 메서드
		getBoard: function(){
		},
		setBoard: function(){
		}	
	};
	
	for (var n in prototype_members) iBoard.prototype[n] = prototype_members[n];
	
	
	return iBoard;
	
})();		        


// User Entitie
var UserEntitie = new (function(){
	
	var userEntitie = function(){
		this.id = '';
        return this;	
    }
        	
   return userEntitie;
        	
}())();
  
        
        
        // 정의된 인터페이스(IUser) 메소드들을 상속받은 일반 클래스(User1)에서 구현한다.
var User1 = interfaceInherit(IUser, {
	// Repository
	getId: function(){
		return UserEntitie.id + '의 아이디 입니다.';
	},
	setId: function(id){
		UserEntitie.id = id;
		return this;
	}
});

// 정의된 인터페이스(IUser, IBoard) 메소드들을 다중 상속([IUser, IBoard]받은 일반 클래스(User2)에서 구현한다.
var User2 = interfaceInherit([IUser, IBoard], {
	// Repository
	getId: function(){
		return UserEntitie.id + '의 아이디랑꼐!!!!';
	},
	setId: function(id){
		UserEntitie.id = id;
		return this;
	},
	getBoard: function(){
		return this;
	},
	setBoard: function(){
		return this;
	}
});		        

// 인터페이스 상속(다중) 및 구현
function interfaceInherit(_interfaces, opt){
	
	var o = {};
	
	// 인터페이스 메서드 카운트
	var interfaceMethodCount = 0;        			
	// 일반클래스(구현클래스)의 인터페이스 메서드 구현 카운트
	var classMethodCount = 0;
	
	_interfaces = _interfaces.length ? _interfaces : [_interfaces];
	
	for (var i = 0, length = _interfaces.length; i < length; i++){
		
		var _interface = _interfaces[i];
	
		var F = function(){};
		
		for (var n in _interface.prototype){
			F.prototype[n] = _interface.prototype[n];
		}
	
		var $F = _interface.call(new F());
		
		for (var n in $F){
			// 인터페이스에 정의된 함수만 구현 가능하다.
			if (Object.hasOwnProperty.call(opt, n)){
				
				o[n] = opt[n];
				
				classMethodCount++;
			}
			
			interfaceMethodCount++;
		}
		
		if (interfaceMethodCount !== classMethodCount){
			// 일반 클래스(구현 클래스)에 정의된 인터페이스 메서드의 구현 메서드가 없을떄..
			throw new Error('상속된 인터페이스 메서드가 구현(모두)되지 않았습니다.');
			return {};
		}      			
	}
	
	return o;
}

alert(User1.setId('xanione').getId());
alert(User2.setId('yanione').setBoard().getBoard().getId());



예제 실행 URL:

http://jsfiddle.net/jeonseounggyun/jML3y/



참고 URL:


1. 인터페이스를 사용하는 이유는 몰까?

http://mrtint.tistory.com/679


2. 추상클래스와 인터페이스의 사용

http://blog.daum.net/question0921/1056


3. 인터페이스와 다중상속

http://warmz.tistory.com/359


4. 인터페이스 사용이유?

http://www.okjsp.pe.kr/seq/161248