플러터 강좌 – 5.4 클래스 만들기

플러터(Flutter)는 구글에서 개발한 UI 툴킷으로, 단일 코드베이스를 통해 iOS, Android, 웹, 데스크탑 애플리케이션을 만들 수 있는 강력한 프레임워크입니다. 본 강좌에서는 플러터에서 클래스를 만드는 방법에 대해 깊이 있게 살펴보겠습니다. 클래스를 잘 활용하면 코드의 재사용성을 높이고, 코드의 구조를 명확히 할 수 있습니다.

1. 클래스의 기본 개념

클래스는 객체 지향 프로그래밍의 핵심 개념으로, 우리가 클래스라는 틀을 통해 특정한 속성과 기능을 갖춘 객체를 정의할 수 있습니다. 플러터에서 클래스를 만드는 방법은 다른 객체 지향 언어와 비슷합니다.

1.1 클래스의 선언

클래스를 선언할 때는 class 키워드를 사용합니다. 다음은 간단한 예제입니다.

class Animal {
    String name;
    
    Animal(this.name);
    
    void speak() {
        print('$name가(이) 소리를 냅니다!');
    }
}

위의 예제에서 Animal이라는 이름의 클래스를 정의했습니다. 이 클래스는 name이라는 속성과 speak라는 메서드를 가지고 있습니다.

1.2 생성자(Constructor)

생성자는 클래스의 인스턴스를 생성할 때 호출되는 특별한 메서드입니다. 생성자는 클래스 이름과 동일해야 하며, 기본 생성자와 명명된 생성자를 지원합니다.

class Animal {
    String name;
    
    Animal(this.name); // 기본 생성자

    Animal.named(this.name); // 명명된 생성자
}

2. 클래스의 속성 및 메서드

클래스는 속성(필드)과 메서드를 통해 데이터와 행동을 정의합니다. 속성은 클래스의 인스턴스가 가지는 데이터이며, 메서드는 이러한 데이터에 적용할 작업을 정의합니다.

2.1 속성 정의

속성을 정의할 때는 자료형을 명시할 수 있으며, 초기값을 설정할 수도 있습니다.

class Person {
    String name;
    int age;

    Person(this.name, this.age);
}

여기서 Person 클래스는 nameage라는 두 가지 속성을 가지고 있습니다.

2.2 메서드 정의

메서드는 클래스의 행동을 정의합니다. 메서드는 데이터를 받아 처리할 수 있으며, 결과를 반환할 수 있습니다.

class Person {
    String name;
    int age;

    Person(this.name, this.age);
    
    String introduce() {
        return '안녕하세요, 제 이름은 $name이고, 나이는 $age세입니다.';
    }
}

2.3 Getter와 Setter

Getter와 Setter는 클래스의 속성에 접근할 수 있는 방법을 제공합니다. 이는 데이터의 캡슐화와 보안을 목적으로 사용됩니다.

class Person {
    String _name; // private field

    Person(this._name);
    
    String get name => _name; // Getter
    set name(String newName) => _name = newName; // Setter
}

3. 클래스 상속

클래스는 다른 클래스를 상속받을 수 있으며, 이를 통해 코드의 재사용성을 높일 수 있습니다. 상속을 통해 부모 클래스의 속성과 메서드를 자식 클래스에서 사용할 수 있습니다.

3.1 상속의 예

class Animal {
    void eat() {
        print('밀가루를 먹습니다.');
    }
}

class Dog extends Animal {
    void bark() {
        print('멍멍!');
    }
}

이 예제에서 Dog 클래스는 Animal 클래스를 상속받아 eat() 메서드를 사용할 수 있습니다.

3.2 다형성(Polymorphism)

다형성은 동일한 인터페이스로 서로 다른 데이터 타입을 처리할 수 있도록 하는 개념입니다. 플러터에서 다형성을 활용하면, 다양한 형태의 오브젝트를 처리할 수 있습니다.

class Cat extends Animal {
    void bark() {
        print('야옹!');
    }
}

void makeSound(Animal animal) {
    animal.bark();
}

void main() {
    Dog dog = Dog();
    Cat cat = Cat();
    
    makeSound(dog); // 멍멍!
    makeSound(cat); // 에러 발생
}

4. 믹스인(Mixin) 사용하기

믹스인은 클래스가 다른 클래스의 메서드를 재사용할 수 있도록 해주는 기능입니다. 믹스인은 상속과는 다른 방법으로 코드 재사용을 가능하게 합니다.

mixin Flyable {
    void fly() {
        print('날아갑니다!');
    }
}

class Bird with Flyable {
    void chirp() {
        print('짹짹!');
    }
}

위의 예제에서 Bird 클래스는 Flyable 믹스인을 사용하여 fly() 메서드를 사용할 수 있게 되었습니다.

5. 정리 및 예제

클래스는 객체 지향 프로그래밍에서 필수적인 요소입니다. 이번 강좌에서 배운 내용을 통해 플러터 애플리케이션에서 클래스를 효과적으로 활용할 수 있을 것입니다. 다음은 우리가 배운 내용을 종합적으로 정리한 간단한 예제입니다.

void main() {
    Person person = Person('홍길동', 25);
    print(person.introduce());

    Dog dog = Dog();
    dog.eat();
    dog.bark();
    
    Cat cat = Cat();
    cat.eat();
    cat.bark();
}
위 코드를 실행하면, 개인 소개, 개가 먹는 소리, 고양이가 먹는 소리를 볼 수 있습니다.

이번 플러터 강좌에서는 클래스의 기본 개념부터 생성자, 메서드, 상속 및 믹스인에 이르기까지 자세히 살펴보았습니다. 이러한 내용을 바탕으로 플러터 애플리케이션을 구성해보시기 바랍니다. 앞으로도 더 많은 내용을 배우게 될 것입니다.