업캐스팅 : 자식 클래스가 부모 클래스 타입으로 캐스팅되는 것 ( 서브 클래스가 슈퍼 클래스로 취급)
다운캐스팅 : 부모 클래스가 자식 클래스의 타입으로 캐스팅되는 것 ( 자신의 고유한 특성을 잃은 서브 클래스의 객체를 다시 복구 시켜주는 것)
//업캐스팅
class Person{
constructor(name){
this.name = name;
};
aler(){
console.log('상위클래스')
}
}
class Student extends Person{
constructor(name){
super(name);
};
aler(){
console.log('하위클래스')
}
}
let p = new Person('원래놈');
p.aler(); //상위클래스
let s = new Student("바뀐놈");
p = s; //업캐스팅
p.aler(); //하위크래스
s(자식클래스)가 p(부모클래스)로 캐스팅 되는것 :
p = s
//다운캐스팅
class Person{
constructor(name){
this.name = name;
};
aler(){
console.log('상위클래스')
}
}
class Student extends Person{
constructor(name){
super(name);
};
aler(){
console.log('하위클래스')
}
}
let p = new Person('원래놈');
let s = new Student("바뀐놈");
s.aler(); //하위클래스
s = p; //다운캐스팅
s.aler(); //상위클래스
p(부모 클래스)가 s(자식 클래스)의 타입으로 캐스팅되는 것 :
s = p
객체에서
Solid
의 원칙에 따르면 다운캐스팅을 지양하고 업캐스팅을 추천한다.
(자식이 부모의 내용을 바꾸는것은 되지만 부모가 자식의 내용을 바꾸는 것은 비추)
(자식은 부모를 대신할 수 있지만 부모는 자식을 대신할 수 없다.)
SRP Single Responsibility 단일 책임
OCP OpenClosed 개방폐쇄
LSP Liskov Substitution 업캐스팅 안전
ISP Interface Segregation 인터페이스 분리
DIP Dependency Inversion 다운 캐스팅 금지
ex) 통합
class Guitar{
constructor(serialNumber,price,maker,type,model,backWood,topWood,stringNum){
this.serialNumber = serialNumber;
this.price = price;
this.maker = maker;
this.type = type;
this.model = model;
this.backWood = backWood;
this.topWood = topWood;
this.stringNum = stringNum;
}
}
let guitar = new Guitar('e19',10000,'미사카','elec','g0','우레탄','현무암','e19-g0');
guitar.serialNumber = 'eeee'
console.log(guitar); //Guitar {serialNumber: "eeee", price: 10000, maker: "미사카", type: "elec", model: "g0", …}
우리는 Guitar 클래스를 통해 만들어진 인스턴스를 인스턴스.property 값을 통해 변경 할 수 있으나 이는 Guitar 클래스에 수정하는 책임도 관련되게 한다.
ex) 분리
class Guitar{
constructor(serialNumber,spec){
this.serialNumber = serialNumber;
this.spec = spec;
}
}
class GuitarSpec{
constructor(price,maker,type,model,backWood,topWood,stringNum){
this.price = price;
this.maker = maker;
this.type = type;
this.model = model;
this.backWood = backWood;
this.topWood = topWood;
this.stringNum = stringNum;
}
}
let spec = new GuitarSpec(10000,'미사카','elec','g0','우레탄','현무암','e19-g0');
let guitar = new Guitar('e19',spec);
spec.price = 100000000
console.log(guitar)
GuitarSpec 클래스를 통해서 해당 값들을 수정해 줄 수 있으므로 변화에 의해 변경되는 부분을 GuitarSpec class에 의해서 관리 할 수 있다.
변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 가능한 극대화
(extend사용)
ex)
class Guitar{
constructor(serialNumber,spec){
this.serialNumber = serialNumber;
this.spec = spec;
}
}
class GuitarSpec{
constructor(price,maker,type,model,backWood,topWood,stringNum){
this.price = price;
this.maker = maker;
this.type = type;
this.model = model;
this.backWood = backWood;
this.topWood = topWood;
this.stringNum = stringNum;
}
}
let guitarSpec = new GuitarSpec(10000,'미사카','elec','g0','우레탄','현무암','e19-g0');
let guitar = new Guitar('e19',guitarSpec);
class Violin{
constructor(serialNumber,spec){
this.serialNumber = serialNumber;
this.spec = spec;
}
}
class ViolinSpec{
constructor(price,maker,type,model,backWood,topWood,stringNum){
this.price = price;
this.maker = maker;
this.type = type;
this.model = model;
this.backWood = backWood;
this.topWood = topWood;
this.stringNum = stringNum;
}
}
let violinSpec = new ViolinSpec(5000,'김형욱','나무','g0','화강암','화강암','ssss-g0');
let violin = new Violin('spss',violinSpec);
console.log(guitar,violin)
ex) extends 사용하여 코드 줄이기
class StringInstrument{
constructor(serialNumber,spec){
this.serialNumber = serialNumber;
this.spec = spec;
}
}
class Spec{
constructor(price,maker,type,model,backWood,topWood,stringNum){
this.price = price;
this.maker = maker;
this.type = type;
this.model = model;
this.backWood = backWood;
this.topWood = topWood;
this.stringNum = stringNum;
}
}
class Guitar extends StringInstrument{
}
class Violin extends StringInstrument{
}
class GuitarSpec extends Spec{
}
class ViolinSpec extends Spec{
}
let guitarSpec = new GuitarSpec(10000,'미사카','elec','g0','우레탄','현무암','e19-g0');
let guitar = new Guitar('e19',guitarSpec);
let violinSpec = new ViolinSpec(5000,'김형욱','나무','g0','화강암','화강암','ssss-g0');
let violin = new Violin('spss',violinSpec);
console.log(guitar,violin)
공통된 부분을 상위클래스인
StringInstrument
와Spec
클래스로 지정해서 extends한다.
업캐스팅 관련 내용 위에 참조
어떤 클라이언트에서는 사용하지 않고, 다른 어떤 클라이언트에서는 사용하는 메소드가 있다고 하자.
이 메소드의 변경이 메소드를 사용하지 않는 클라이언트에 영향을 줄 때 인터페이스를 분리하도록 한다.
다운캐스팅 관련 : 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다