일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Swift
- Filter
- union
- elementAt
- Foreign Key
- Kotlin
- Generic
- lifecycle
- function
- 생명주기
- collection
- list
- docker
- AWS
- MINUS
- Service
- recyclerview
- ReactNative
- enum
- LiveData
- ConstraintLayout
- docker-compose
- react native
- mongoose
- map
- Interface
- vuex
- CLASS
- animation
- class component
- Today
- Total
개발 일기
Class ? 본문
TypeScript에서 class는 JAVA와 C#와 비슷하게 생겼습니다.
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
이 클래스에서는 greeting이라는 변수 , 생성자 , greet() 이라는 함수를 가지고 있습니다.
class에 member 변수에 접근 하고 싶으면 this을 통해 접근을 할수가 있습니다.
상속 :)
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
다음과 같이 Dog라는 클래스가 Animal을 상속받아 move을 호출한걸 볼수가 있습니다.
상속할 때는 extends라는 키워드를 작성합니다.
class Animal {
name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
결과 값은 어떻게 나올까요 ?
다음과 같이 나옵니다.
Slithering...
Sammy the Python moved 5m.
Galloping...
Tommy the Palomino moved 34m.
여기에서 설명을 드리면 처음에 Snake라는 클래스를 생성합니다.
Snake는 Animal을 상속받고 있고 생성자로 name을 받고 super을 통해서 부모 생성자에게 전달하고 있습니다..
근데 여기에서 Snake가 Animal에 있는 move를 override을 했고 그 안에서 부모 move라는 함수를 호출하고 있습니다.
따라서 위와 같이 호출이 되는걸 알수가 있습니다.
private , public , protected ?
기본적으로 Typescript는 public 입니다. 그래서 다른 곳에서 자유롭게 접근이 가능했습니다.
private접근은 다음과 같이 표시할수 있습니다.
//Typescript 3.8
class Animal {
#name: string;
constructor(theName: string) { this.#name = theName; }
}
new Animal("Cat").#name; // Property '#name' is not accessible outside class 'Animal' because it has a private identifier.
or
class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}
new Animal("Cat").name; // Error: 'name' is private;
class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}
class Rhino extends Animal {
constructor() { super("Rhino"); }
}
class Employee {
private name: string;
constructor(theName: string) { this.name = theName; }
}
let animal = new Animal("Goat");
let rhino = new Rhino();
let employee = new Employee("Bob");
animal = rhino;
animal = employee; // Error: 'Animal' and 'Employee' are not compatible
위에 예제를 통해서 알수 있는 정보는 private을 통해서 접근을 제한한다는 사실입니다.
protected 같은 경우에는 상속받은 클래스에서는 자유롭게 접근이 가능하지만 그 외에는 접근이 불가능합니다.
class Person {
protected name: string;
constructor(name: string) { this.name = name; }
}
class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // error
다음과 같이 생성자에서 표시할순 있지만 상속받은 클래스가 아닌 다른 곳에서 접근을 할때는 에러가 발생합니다.
class Person {
protected name: string;
protected constructor(theName: string) { this.name = theName; }
}
// Employee can extend Person
class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let howard = new Employee("Howard", "Sales");
let john = new Person("John"); // Error: The 'Person' constructor is protected
readonly라는 키워드는 속성을 읽기 전용으로 만들수 있습니다.
따라서 선언할때 또는 생성자에서 초기화를 진행해야합니다.
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // error! name is readonly
또한 생성자로 넘겨서 바로 만들고 초기화를 할수가 있습니다.
class Octopus {
readonly numberOfLegs: number = 8;
constructor(readonly name: string) {
}
getName() : string{
return this.name
}
}
let temp = new Octopus("111")
console.log(temp.getName())
결과 값
//111
Typescript에서도 당연히 get set을 지원을 합니다. 다음과 같이 그냥 표시할수도 있지만 set할때 특정한 조건을 하고 싶은 경우에는 set을 통해서 정할수 있습니다.
class Employee {
fullName: string;
}
let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
console.log(employee.fullName);
}
const fullNameMaxLength = 10;
class Employee {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (newName && newName.length > fullNameMaxLength) {
throw new Error("fullName has a max length of " + fullNameMaxLength);
}
this._fullName = newName;
}
}
let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
console.log(employee.fullName);
}
이때까지 계속 멤버 변수를 이야기를 했다면 이제는 인스턴스 해서 쓰는것이 아닌 정적 변수로도 사용할수가 있습니다.
class Grid {
static origin = {x: 0, y: 0};
calculateDistanceFromOrigin(point: {x: number; y: number;}) {
let xDist = (point.x - Grid.origin.x);
let yDist = (point.y - Grid.origin.y);
return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
}
constructor (public scale: number) { }
}
let grid1 = new Grid(1.0); // 1x scale
let grid2 = new Grid(5.0); // 5x scale
console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
다음과 같이 Grid.origin을 통해서 바로 접근 하는것을 볼수가 있습니다.
Typescript에서 다음과 같이 추상화를 제공을 합니다.
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log("roaming the earth...");
}
}
다음과 같이 abstract을 통해서 추상화 클래스와 추상화 메소드를 제공할수가 있습니다.
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log("Department name: " + this.name);
}
abstract printMeeting(): void; // must be implemented in derived classes
}
class AccountingDepartment extends Department {
constructor() {
super("Accounting and Auditing"); // constructors in derived classes must call super()
}
printMeeting(): void {
console.log("The Accounting Department meets each Monday at 10am.");
}
generateReports(): void {
console.log("Generating accounting reports...");
}
}
let department: Department; // ok to create a reference to an abstract type
department = new Department(); // error: cannot create an instance of an abstract class
department = new AccountingDepartment(); // ok to create and assign a non-abstract subclass
department.printName();
department.printMeeting();
department.generateReports(); // error: method doesn't exist on declared abstract type
고급 기술 #
다음과 같이 추상화 클래스는 직접적으로 생성을 할수가 없고 위와 같이 추상화 클래스로 타입을 지정했을 경우에는 generateReports가 없기 때문에 에러가 발생하는걸 볼수가 있습니다.
그리고 또한 추상화 메소드는 반드시 정의를 해줘야합니다.
클래스를 다음과 같이 인터페이스로 사용이 가능합니다.
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
'컴퓨터 언어 > Typescript' 카테고리의 다른 글
Literal Types ? (0) | 2020.05.03 |
---|---|
Function ? (0) | 2020.05.03 |
Interface ? (0) | 2020.04.30 |
변수 선언 ? (0) | 2020.04.26 |
기본 Type ? (0) | 2020.04.18 |