반응형

Class 상속

[광고 누르면 오늘의 행운 상승!!]

  • 특정 객체의 프로퍼티와 메소드를 가져와 새로운 객체 사용
  1. 코드 양 축소
  2. 구조적인 코드 작성 가능
  3. 객체지향 언어에서 제공(ex , Java)

→ JavaScript는 상속에 관한 문법을 제공하지 않음 → JavaScript의 유연성으로 상속 구현 가능 → 어려움

  • JavaScript 객체 : Class 존재하지 않음 → 생성자 함수, 프로토 타입 객체 사용하여 객체 생성 → Class라 부르는 건 잘못된 표현 → 객체의 특성을 위하여 불가피하기 Class라고 부름

게임 캐릭터 객체

<<부모 클래스(Character)>>

function Charater(name,title,level){
	var name = name;
	var title = title;
	
	this.level = level || 1;
	this.power = 10;
	this.experience = 10;
	this.arms = ['검'];

	this.getName = function(){
		return name;
	};

	this.getTitle = function(){
		return title;
	};
}
Charater.prototype.toString = function(){
	return this.getTitle() + " " + this.getName();
}
Charater.prototype.valueOf = function(){
	return this.power + this.experience + this.arms.length * 5;
}
Charater.prototype.powerup = function(up){
	this.power = this.power + up;
}
Charater.prototype.expup = function(up){
	this.experience = this.experience + up;
}
Charater.prototype.addArms = function(arms){
	this.arms.push(arms);
}
Charater.prototype.levelup = function(up){
	if(up){
		this.level = this.level + up;
	} else{
		this.level = this.level + 1;
	}
}

 

<<자식 클래스 Orcs>>

Character.orcs = function(){
	var newOrc = newCharacter('orc', '일꾼');
	newOrc.arms = ['도끼'];
	return newOrc;
}

 

 

※ 클래스 상속은 어떤 클래스에서 프로퍼티와 메소드를 빌려와서 사용하는 것이다.  

 

Orc class 작성(Character Class 상속)

  • 역할 : 일꾼 객체 생성
  • 기본무기 : 도끼
  • Orc Class의 생성자 함수
function Orc(){
	this.arms = ['도끼'];
}

 

SuperClass(Character Class)의 프로퍼티, 메소드 상속

  • SuperClass의 모든 프로퍼티와 메소드 subClass의 프로토 타입으로 설정
  • 생성자의 프로토타입 프로퍼티의 값 : 객체
Orc.prototype = new Character("orc", "일꾼");

Character Class의 인스턴스 객체 : 
Character 생성자 함수와 프로토 타입으로 지정한 프로퍼티, 메소드 존재

-> Orc 프로토 타입으로 지정

Character Class의 모든 프로퍼티와 메소드 Orc Class에 상속

 

apply와 call의 첫 번째 전달인자 null

  • add.apply(null,[1,2]);
  • add.call(null,1,2);
  • null을 무시하면 이해하기 어렵지 않음
  • 함수를 특정 객체의 메소드로 실행하기 위해 사용

Orc에 전달인자 사용하여 초기화하기

  • subclass에 superclass 전달인자 사용?
  • supercalss의 생성자 함수, subclass의 메소드로 실행
    → apply메소드로 구현 가능
function Orc(name, title, level){
	Character.apply(this, arguments);
	this.arms = ['도끼'];
}

Character 생성자는 함수를 Orc 함수 메소드로 실행
arguments는 배열 형식의 전달인자

superclass의 생성자 함수 apply 메소드를 사용하여 실행시, subclass의 전달인자 처리 가능
superclass의 생성자 함수 빌려 프로퍼티 초기화 한 효과

Orc의 생성자 함수 전달인자로 초기화되는 프로퍼티 정의 안해도 됨!

 

※ superclass의 프로토타입을 상속받지 못한다 ※

superclass 생성자 사용방법 + 프로토타입 지정 방법

superclass 생성자 사용방법과 프로토타입 지정 방법을 같이 사용하면
단점을 보완할 수 있다.

function Orc(name, title, level){
	Character.apply(this, arguments);
	this.arms = ['도끼'];
}
//superclass의 생성자 : 생성자 함수에 적용

Orc.prototype = new Character(); 
//프로토타입 : superclass의 인스턴스 객체 적용

생성자 함수에 전달인자로 초기화 기능 사용, 프로토타입의 메소드 사용 가능

 

  • 문제점 : superclass의 생성자 함수에 정의된 프로퍼티와 메소드가 프로토타입 지정 시 한번 더 생성.
    → 생성자 함수에 있는 프로퍼티와 메소드라면 프로토타입까지 검사하지 않기 때문

subclass의 프로토타입을 superclass의 프로토타입으로 지정하기

  • 생성자 함수와 프로토타입에 같은 프로퍼티 들어있는 것 해결방법
    → 프로토타입에 들어 있는 생성자 함수의 프로퍼티 삭제
    → 좋은 방법이 아니다

  • subclass의 프로토타입으로 Superclass의 프로토타입 지정!

function Orc(name, title, level){
	Character.apply(this, arguments);
	this.arms = ['도끼'];
}

Orc.prototype = Character.prototype
//superclass와 subclass의 프로토타입 공유 

이제 orc의 요소를 삭제하면 정상적으로 undefined가 반환됨.

 

  • 문제점 프로토타입 = 객체 → subclass의 프로토타입과 superclass의 프로토타입 참조로 연결

    subclass 변경시 superclass 변경됨 (반대도 가능)

객체의 복사

  • 객체를 복사하여 사용해야 서로의 값이 바뀌지 않음.
var Temp = function(){};
Temp.prototype = originalObj;
var duplicatedObj = new Temp;

duplicatedObj.a = "duplicated";
duplicatedObj.b = 2;

document.write("originalObj : ");
document.write(originalObj.a);
document.write(originalObj.b + <"br>");

document.write("duplicatedObj : ");
document.write(duplicatedObj.a);
document.write(duplicatedObj.b + <"br>");

-출력
originalObj : original1
duplicatedObj: duplicated2

 

  • 상속 코드의 단점 → 객체 복사 방법을 이용하여 해결 가능
function Orc(name, title, level){
	Character.apply(this, arguments);
	this.arms = ['도끼'];
}

var tempFunc = function(){};
tempFunc.prototype = Character.prototype
Orc.prototype = new tempFunc();

문제점 
- 임시 객체 : 전역 변수로 존재
- 가독성 문제

-> 바로 실행되는 임시 함수 작성으로 해결

 

  • 바로 실행되는 임시 함수
(function(){
	var tempFunc = function(){};
	tempFunc.prototype = Character.prototype
	Orc.prototype = new tempFunc();
}());

이름없는 임시 함수 작성
함수 뒤, ()넣어 바로 실행 가능하게

 

constructor property

  • 생성자 함수의 프로토 타입에 생성되는 프로퍼티로 객체의 생성자.
  • 프로토타입을 변경하는 방법으로 상속을 하게 되면
    서브클래스의 생성자 프로퍼티는 수퍼클래스의 것으로 바뀌게 된다.

객체 리터럴 방식으로 생성된 객체 상속

객체 복사 방식을 이용해서 모든 프로퍼티와 메소드를 상속한다.

var Super = {
	name : "이름",
	age : 1,
	gender : "모름",
	toString : function () {return this.name;}
};

var sub = copyObject(Super);

function copyObject(obj) {
		var TmpFunc = function (){};      //빈 생성자 함수
		TmpFunc.prototype = obj;          //빈 생성자 함수의 프로토 타입에 복사하려는 객체 할당
		return new TmpFunc();             //새로운 객체 생성 및 반환
}

 

mixIn

다수의 부모 객체를 순환하여 모든 프로퍼티나 메소드를 빌려와 하나의 객체로 만들어 반환

프로퍼티를 가져오기

하나 이상의 객체에서 프로퍼티를 모두 빌려오는 함수

function mixInProperty(obj){
		//var arg, prop;
		for (var arg = 1; arg < arguments.length; arg++){
			for (var prop in arguments[arg]) {
				if (arguments[arg].hasOwnProperty(prop)){
					obj[prop] = arguments[arg][prop];
				}
			}
		}
	}
함수의 전달인자 : 2개 이상
첫 번째 전달인자 : 프로퍼티가 가져와 저장되는 객체
두 번째 전달인자부터~ : 프로퍼티를 가져올 객체
	
	var first = {a:"1", b:"2"};
	var second = {c:"3", d:"4", e:"5"};
	var child = {f:"6"};
	mixInProperty(child, first, second);

Ⅰ Ⅱ Ⅲ 출력

childObj : 자신의 프로퍼티 + firstObj의 프로퍼티 + secondObj의 
프로퍼티 모두 사용

메소드 가져오기

프로퍼티와 다르게 클래스, 즉 생성자 함수를 전달 인자로 넣어줘야한다.

하나 이상의 클래스에서 메소드 모두 빌려오는 함수

function mixInMethid(cls){
		var arg, prop;
		for (var arg = 0; arg < arguments.length; arg++){
			for (var method in arguments[arg].prototype) {
				if (typeof arguments[arg].prototype[method] != "function")
					continue;
				obj.prototype[method] = arguments[arg].prototype[method];
				
			}
		}
	}
함수의 전달인자 : 2개이상
첫 번째 전달인자 : 메소드를 받을 class
두 번째 전달인자부터~ : 메소드를 빌려줄 class들 

다른점은 class를 전달인자로 받음!

JavaScript의 메소드는 대부분 프로토타입에 정의되기 때문에
프로토타입의 메소드를 빌려옴!

function first() {};
first.prototype.a = function () {
		document.write("1");
};
	
function second() {};
second.prototype.b = function () {
		document.write("2");
};
	
function child() {};
	
mixInMethod(child, first, second);
child.prototype.a();
child.prototype.b();
반응형

+ Recent posts