티스토리 뷰

클래스란 연관있는 데이터들을 한 곳에 묶어놓은 컨테이너 역할을 한다.

class Person{
name;
age; // 이름과 나이와 같은 것들은 '속성' field 필드 라고 함
speak(); // 말하기와 같은 '행동'은 method 라고 합니다. 
}

-> 클래스( fields + methods ) // 변수 + 함수 

간혹 메소드는 들어있지 않고 필드들만 있는 클래스가 있는데 그것을 데이터 클래스 라고 부릅니다. 

 

내부적으로 보일 수 있는 변수와 밖에서 보이는 변수를 나눠서 캡슐화(Encapsulation) 제공

또한 클래스를 통해서 상속 다형성*이 일어날 수 있음 이런 모든 것을 가능한 곳이 객체지향언어이다.

*다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다. 자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.

🍕Object(객체)?

- instance of a class 

- created many times 

- data in

클래스에 데이터를 넣어서 만드는 것 -> 객체(obj)

클래스를 이용해서 새로운 인스턴스를 생성하면 obj가 되는 것임

-> 클래스는 정의만 한 것이라서 메모리에 올라가지 않음 반면에 오브젝트는 데이터를 넣으면 메모리에 올라가게 됨

 

🍕class(클래스)?

- template //붕어빵 만드는 틀 같은 것, 청사진, 템플릿 등등..으로 불림 

- declare once //틀만 정의해놓고 한번만 선언

- no data in //데이터는 들어가지않고 어떤 데이터가 들어올 수 있다고 틀을 짜놓는 것

 

🍕객체 생성방법: 생성자 함수와 클래스

생성자 함수

-일반 함수에 기술적인 차이 X 

-두 관례를  따른다. 

  1. 함수 이름의 첫 글자는 대문자로 시작
  2. 반드시 new 연산자를 붙여 실행한다. 
function Person(name, position) {
    this.name = name,
    this.position = position
}
const person1 = new Person('gamza', 'noob');
클래스(Class)

▶기본문법

class MyClass {
  // 여러 메서드를 정의할 수 있음
  constructor() { ... }
  method1() { ... }
  method2() { ... }
  method3() { ... }
  ...
}

new MyClass() // 새롭게 만들어진 객체 호출
  • 객체의 기본 상태를 설정해주는 생성자 메서드 constructor()는 new에 의해 자동으로 호출되므로, 특별한 절차 없이 객체를 초기화할 수 있음

클래스 사용 예시

class User {

  constructor(name) {
    this.name = name;
  }

  sayHi() {
    alert(this.name);
  }

}

// 사용법:
let user = new User("John");
user.sayHi();

-> 새로운 객체가 생성되고 넘겨받은 인수와 함께 constructor가 자동으로 실행된다. 

⚠주의: 클래스의 메서드 사이에는 쉼표가 없습니다. -> 문법에러발생 
클래스와 관련된 표기법은 객체 리터럴 표기법과 차이가 있음
클래스에선 메서드 사이에 (구분을 위한) 쉼표를 넣지 않아도 된다.

 

🍕접근자 프로퍼티(getter , setter)

프로퍼티 종류에는 2가지가 있다.

  • 데이터 프로퍼티 (값을 저장하기 위한 프로퍼티) 
  • 접근자 프로퍼티

접근자 프로퍼티(accessor property): 값이 없고 프로퍼티를 읽거나 쓸 때 호출하는 함수를 값 대신에 지정할 수 있는 프로퍼티입니다. 접근자 프로퍼티의 본질은 함수이며 이 함수는 값을 획득(get)하고 설정(set)하는 역할을 담당한다. 외부 코드에서는 함수가 아닌 일반적인 프로퍼티처럼 보임 

 

getter와 setter를 사용하는 궁극적인 이유는 사용자의 입력값에 대해 유효성검사를 할 수 있기 때문

/ 2.Getter and Setters
class User {
  constructor(fisrtName, lastName, age) {
    this.fisrtName = fisrtName;
    this.lastName = lastName;
    this.age = age;
  }
  //this.age라는 메모리에 올라간 데이터를 읽어오는 것이 아니라 getter를 호출
  // = age 값을 할당할때, 바로 메모리의 값을 할당하는 것이 아니라 setter를 호출
  // 그러면 또 setter의 내부에서 = value를 할당할때 바로 할당하는 것이 아니라 setter를 호출
  // 이게 무한정 반복되기 떄문에 callstack 에러가 발생-> 이런 상황을 방지하기 위해서
  // getter와 setter 안에서 사용되는 변수의 이름을 다르게 수정-> 보통 앞에 언더바_를 넣어준다.
  get age() {
    return this._age;
  }
  // 값을 설정, 그렇기 때문에 인자로 value를 받아와야 함
  set age(value) {
    // if (value < 0) {
    //   throw Error('age can not be negative');
    // }

    // 위와 같이 공격적으로 써도 되고 아래처럼 삼항연산자를 통해 해도 됨
    this._age = value < 0 ? 0 : value;
  }
}
const user1 = new User('kang', 'kim', -1);
console.log(user1.age);
  • 위의 예시에서 사용자가 자신의 나이를 -1으로 설정했으나 나이에 음수값이 들어올 수 없으므로 setter를 통해 들어온 value가 0보다 작을 경우 0으로 세팅하도록 변경

 

🍕extends 키워드를 통한 클래스 상속

// 5.Inheritance 상속
// a way for one class to extends another class.
// extends 라는 키워드를 이용해서 부모 클래스에서 자식클래스로 모든 프로퍼티를 상속받는다.
// 필요한 함수만 내용을 재정의해서 사용할 수 있음 = 오버라이딩 이라고 부름

class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }

  draw() {
    console.log(`drawing ${this.color} color of`);
  }

  getArea() {
    return this.width * this.height;
  }
}

class Rectangle extends Shape {}
class Triangle extends Shape {
  draw() {
    super.draw(); //supuer.을 통해 부모의 draw메소드도 호출가능 
    console.log('🔺');
  }
  getArea() {
    //필요한 함수만 재정의 - 오버라이딩
    return (this.width * this.height) / 2;
  }
}
const rect1 = new Rectangle(20, 20, 'blue');
const triangle = new Triangle(20, 30, 'pink');
rect1.draw(); 
triangle.draw();
console.log(triangle.getArea());
  • 콘솔을 확인해보면 아래와 같이 출력되는 코드의 줄이 다른 것을 확인할 수 있는데 오버라이드 해서 재정의한 메소드의 경우는 해당 코드가 재정의 된 곳(자식 클래스)에서 코드가 실행되고 나머지는 원래 정의된 곳(부모 클래스)에서 실행되고 있다. 
  • Triangle class의 경우 draw메소드를 재정의하면서 내부에 super.draw()를 통해 부모의 코드도 실행하고 있다. 그래서 107줄(Shape.draw())과 119줄(Triangle.draw()) 두개가 찍힌 것임 


  • Fields (public, private) 
  • static - 클래스만의 메소드나 속성을 만들때 사용, obj를 통해서가 아니라 클래스 자체에서 호출해서 사용
  • Inheritance ( extends ) - extends 키워드를 통해서 부모 클래스의 프로퍼티와 메소드를 자식 클래스에게 그대로 물려줄 수 있음 자식 클래스에서 원하는대로 커스텀해서 사용(오버라이딩)도 가능하며 커스텀 뒤에도 super키워드를 통해 부모클래스의 메소드를 호출할 수도있음
  • instanceOf - 객체가 해당 클래스로부터 만들어진 객체인지 확인할 수 있는 operator, 해당 클래스로부터 만들어진게 아니라면 false 반환 맞다면 true. 부모클래스가 아니라 조상클래스여도 true를 반환함

관련 정리 ▼

// 3. Fields (public, private)

// Too soon! 최근에 추가되었다고 함-> 많은 개발자가 사용하고 있지는 않음
// 최신 브라우저에서 지원하지 않는 경우가 많음 쓰려면 BABEL을 사용해야 합니다.

// constructor 를 사용하지 않고 field를 정의할 수 있음
// 퍼블릭은 외부에서 접근 가능, 프라이빗은 앞에 해시기호를
// 붙이고 외부 접근 불가(조작 전부 불가)- 클래스 내부에서만 값 조작가능
class Experiment {
  publicField = 2;
  #privateField = 0;
}
const experiment = new Experiment();
console.log(experiment.publicField); // 2
console.log(experiment.privateField); // undefined

// 4. Static properties and methods
// too soon!
// 알아두면 좋은 개념
// 새로 생성되는 객체의 데이터값과 연관있는 것 X
// 클래스 자체에서 사용되는 동일한 메소드가 있을 때 사용
// static 키워드를 붙이면 obj와 상관없이 class 자체에 연결되어 있음, obj마다 할당되는 것이 아님
// 사용할 때: 생성되는 obj와 상관없이 class 자체의 공통 기능이라면
// static과 static메소드로 지정해서 사용-> 메모리 사용 감소 효과
class Article {
  static publisher = 'Dream Coding';
  constructor(articleNumber) {
    this.articleNumber = articleNumber;
  }
  static printPublisher() {
    console.log(Article.publisher);
  }
}
const article1 = new Article(1);
const article2 = new Article(2);
console.log(article1.publicsher); // undefined, static 키워드를 통해만들었기 떄문에 obj로 접근 X
console.log(Article.publisher); //Dream Coding, 정상출력
Article.printPublisher(); //Dream Coding

// 5.Inheritance 상속
// a way for one class to extends another class.
// extends 라는 키워드를 이용해서 부모 클래스에서 자식클래스로 모든 프로퍼티를 상속받는다.
// 필요한 함수만 내용을 재정의해서 사용할 수 있음 = 오버라이딩 이라고 부름

class Shape {
  constructor(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
  }

  draw() {
    console.log(`drawing ${this.color} color of`);
  }

  getArea() {
    return this.width * this.height;
  }
}

class Rectangle extends Shape {}
class Triangle extends Shape {
  draw() {
    super.draw();
    console.log('🔺');
  }
  getArea() {
    //필요한 함수만 재정의 - 오버라이딩
    return (this.width * this.height) / 2;
  }
}
const rect1 = new Rectangle(20, 20, 'blue');
const triangle = new Triangle(20, 30, 'pink');
rect1.draw();
triangle.draw();
console.log(triangle.getArea());

// 6. Class checking: instanceOf
// obj는 class를 통해 만들어진 새로운 인스턴스이다.
// objName instanceOf className
// 왼쪽의 obj가 오른쪽의 class 인스턴스인지 확인할 수 있다.
// 왼쪽의 obj가 오른쪽의 class를 통해서 만들어진 obj인지 판별가능
// ture 와 false 리턴
console.log(rect1 instanceof Rectangle); //t
console.log(triangle instanceof Rectangle); //f
console.log(triangle instanceof Triangle); //t
console.log(triangle instanceof Shape); //t
console.log(triangle instanceof Object); // t
댓글