class User {
	constructor(name, age){ // 객체를 만들어주는 생성자 메서드
		this.name = name;
		this.age = age;
	}
	showName() {
		console.log(this.name);
	}
}

const tom = new User('tom', 20);

console.log(tom);

User {name: "tom", age: 20}
	age: 20
	name: "tom"
	__proto__:
		constructor: class User
		showName: ƒ showName() // showName 은 proto 에 들어간다.
		__proto__: Object
// new 연산자를 빼 보자

const tom = User('tom', 20);
// 바로 error 가 뜬다. Class constructor User cannot be invoked without 'new'

//함수 생성자와 다른 점이다.
for (const key in tom) {
  console.log(key); // name 과 age 만 뜬다. showName 은 안뜬다. 메소드 제외
}

//함수 생성자와 다른 점이다. 함수 생성자는 showName 까지 뜬다.
//함수 생성자에서 for in 문은 프로토 타입에 포함된 property들을 전부 보여줬다. 객체가 가지고있는
//property 만 판별하기 위해선 hasOwnProperty 를 사용했어야 했다.
// 상속

class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log("drive");
  }
  stop() {
    console.log("Stop!");
  }
}

class Bmw extends Car {
  park() {
    console.log("Park");
  }
}

const myCar = new Bmw("black");
console.log(myCar);

Bmw {color: "black", wheels: 4}
	color: "black" // car 에서 선언한 color 와 wheels 가 들어있다.
	wheels: 4
	__proto__: Car
		constructor: class Bmw
		park: ƒ park() // 역시나 prototype 밑에 들어가 있다.
		__proto__: Object
			constructor: class Car
			drive: ƒ drive() // car 의 메소드다. proto에 있다.
			stop: ƒ stop()
			__proto__: Object
// 메소드 오버라이딩
class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log("drive");
  }
  stop() {
    console.log("Stop!");
  }
}

class Bmw extends Car {
  park() {
    console.log("Park");
  }
  stop() {  //  Bmw 에도 부모객체의 stop 과 같은 이름의 stop() 메소드를 만들었다.
    super.stop(); // 부모것을 사용하고 싶다.
    console.log("OFF");  // 추가로 내 것 까지 할꺼다!
  }
// 현재 Bmw 에 우리가 따로 constructor 를 선언하지 않았다.
class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log("drive");
  }
  stop() {
    console.log("Stop!");
  }
}

class Bmw extends Car {
  constructor() {    //   만들어봤다.
		//super(); // 추가 해 주면 잘 된다.
    this.navigaton = 1;
  }
  park() {
    console.log("Park");
  }
  stop() {
    super.stop();
    console.log("OFF");
  }
}

const myCar = new Bmw("black"); // error!
// Must call super constructor in derived class before accessing 'this' or returning from derived constructor
// 반드시 super 의 constructor 를 call 하는것이 우선이라고 한다. super() 로 해결!

// 그런데.. 뭔가 이상하다!

// Bmw {color: undefined, wheels: 4, navigaton: 1}
// color 에 undefined 가 들어갔다. 분명히 생성할 때 black 을 넣어줬다. 근데 왜? 자식 클래스의 constructor 에서 color를 받지 않아서!

class Bmw extends Car {
  constructor(color) {    //   만들어봤다.
		super(color); // 추가 해 주면 잘 된다.
    this.navigaton = 1;
  }
  park() {
    console.log("Park");
  }
  stop() {
    super.stop();
    console.log("OFF");
  }
}

// 우리가 Bmw 에 constructor 를 직접 작성하지 않았다면 js 에서는 다음과 같이 한다.
class Bmw extends Car {
  constructor(...args) { // default 상태이다. 자식 생성자는 반드시 부모생성자를 호출 해야 하는 것이다.
    super(...args);
  }
  park() {
    console.log("Park");
  }
}