Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 콜백 함수
- null safety
- null 억제 연산자
- my_sql
- 배열과 리스트
- 2일차
- 추상클래스
- flutter 믹스인
- late 키워드
- ?. ?? ! late
- 다중상속
- rdbms nosql 차이
- 오늘은 1일 2쿼리
- 주말도 식지않아
- null check 연산자
- LinkedList
- MySQL
- 1일 1쿼리
- 앱개발 가보자고
- SQL
- 비동기 처리
- array
- dart
- null 병합 연산자
- mysql mongo 성능 비교
- FLUTTER
- 주말에도 1일 1쿼리
- jmeter
- 주말도 한다
- 컴포지션과 집합
Archives
- Today
- Total
subindev 님의 블로그
[Flutter] #7 Dart 기본 문법 추상 클래스 본문
Dart 프로그래밍 기초
1. 추상 클래스과 인터페이스
추상클래스란 ?
추상 클래스(Abstract Class)란 객체지향 프로그래밍에서 공통적인 특징을 정의하지만, 스스로는 인스턴스를 생성할 수 없는 클래스를 말합니다. 추상 클래스는 주로 다른 클래스들이 상속받아 사용할 수 있도록 기본 구조를 정의하기 위해 사용됩니다.
특징
- 추상 메서드(Abstract Method) 포함
- 추상 클래스는 하나 이상의 추상 메서드를 포함할 수 있습니다.
- 추상 메서드는 선언만 되어 있고, 구현(구체적인 내용)이 없는 메서드입니다.
abstract class Shape { abstract void draw(); // 추상 메서드 }
- 인스턴스 생성 불가
- 추상 클래스 자체로는 객체를 생성할 수 없습니다.
Shape shape = new Shape(); // 오류 발생
- 추상 클래스 자체로는 객체를 생성할 수 없습니다.
- 상속을 통해 구현
- 추상 클래스를 상속받은 클래스가 추상 메서드를 구현해야 합니다.
class Circle extends Shape { void draw() { System.out.println("Drawing a circle"); } }
- 추상 클래스를 상속받은 클래스가 추상 메서드를 구현해야 합니다.
- 일반 메서드와 필드 포함 가능
- 추상 클래스는 추상 메서드 외에도 일반 메서드와 멤버 변수를 포함할 수 있습니다.
abstract class Shape { String color; void setColor(String color) { this.color = color; } abstract void draw(); }
- 추상 클래스는 추상 메서드 외에도 일반 메서드와 멤버 변수를 포함할 수 있습니다.
사용 이유
- 코드 재사용성 증가
- 공통된 기능(필드와 메서드)을 추상 클래스에 정의하고, 이를 상속받아 중복 코드를 줄입니다.
- 설계 강제
- 추상 메서드는 하위 클래스가 반드시 구현해야 하므로 일관된 인터페이스를 강제할 수 있습니다.
- 유연한 확장성 제공
- 추상 클래스는 다양한 하위 클래스가 공통적인 구조를 가지면서도 각기 다른 동작을 구현하도록 유도합니다.
예시
abstract class Animal {
// 추상 메서드
abstract void sound();
// 일반 메서드
void sleep() {
System.out.println("Sleeping...");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark!");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound(); // 출력: Bark!
dog.sleep(); // 출력: Sleeping...
Animal cat = new Cat();
cat.sound(); // 출력: Meow!
}
}
추상클래스 vs 인터페이스
다중 상속 | 다중 상속 불가능 (한 클래스만 상속 가능) | 다중 구현 가능 |
메서드 구현 | 일반 메서드와 추상 메서드 모두 가질 수 있음 | 기본적으로 추상 메서드만 가짐 (Java 8 이후 default 메서드 가능) |
속성 | 인스턴스 변수 가질 수 있음 | 상수(변경 불가능한 값)만 가질 수 있음 |
인터페이스란?
- 인터페이스는 클래스나 프로그램이 서로 상호작용할 수 있도록 정의된 일종의 "규약"입니다.
- 인터페이스는 오직 추상 메서드(구현 없는 메서드)와 상수만을 포함합니다.
- 인터페이스를 구현한 클래스는 인터페이스에 정의된 모든 메서드를 반드시 구현해야 합니다.
특징
- 다중 구현 가능
- 하나의 클래스는 여러 개의 인터페이스를 동시에 구현할 수 있습니다. java에서 다중상속을 인터페이스를 이용하여 구현합니다.
- 추상 메서드만 포함
- Java 8부터는 default와 static 메서드를 포함할 수 있지만, 기본적으로 메서드는 구현부가 없습니다.
- 상수만 포함
- 인터페이스 내의 변수는 자동으로 public static final로 선언됩니다. (즉, 상수만 포함)
- 객체 생성 불가
- 인터페이스 자체로는 객체를 생성할 수 없습니다.
인터페이스 예제
1. 기본 사용 예제
// 인터페이스 정의
interface Animal {
void sound(); // 추상 메서드
void sleep();
}
// 인터페이스 구현
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Bark!");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping...");
}
}
class Cat implements Animal {
@Override
public void sound() {
System.out.println("Meow!");
}
@Override
public void sleep() {
System.out.println("Cat is sleeping...");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.sound(); // 출력: Bark!
dog.sleep(); // 출력: Dog is sleeping...
Animal cat = new Cat();
cat.sound(); // 출력: Meow!
cat.sleep(); // 출력: Cat is sleeping...
}
}
2. 다중 인터페이스 구현
// 인터페이스 정의
interface Printable {
void print();
}
interface Scannable {
void scan();
}
// 클래스가 두 인터페이스를 구현
class PrinterScanner implements Printable, Scannable {
@Override
public void print() {
System.out.println("Printing a document...");
}
@Override
public void scan() {
System.out.println("Scanning a document...");
}
}
public class Main {
public static void main(String[] args) {
PrinterScanner device = new PrinterScanner();
device.print(); // 출력: Printing a document...
device.scan(); // 출력: Scanning a document...
}
}
3. Java 8 이후 default 메서드
- default 메서드는 인터페이스 내에서 기본 구현을 제공할 수 있습니다.
- 클래스는 default 메서드를 재정의하지 않아도 됩니다.
interface Vehicle {
void start();
// Java 8부터 추가된 default 메서드
default void stop() {
System.out.println("The vehicle is stopping.");
}
}
class Car implements Vehicle {
@Override
public void start() {
System.out.println("The car is starting.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start(); // 출력: The car is starting.
car.stop(); // 출력: The vehicle is stopping.
}
}
추상 클래스 vs 인터페이스 비교
구분 추상 클래스 인터페이스
목적 | 클래스 간의 공통 기능 정의 및 상속 구조 설계 | 클래스가 따라야 할 규약(계약)을 정의 |
다중 상속/구현 | 다중 상속 불가 | 다중 구현 가능 |
메서드 | 일반 메서드와 추상 메서드 모두 포함 가능 | 기본적으로 추상 메서드만 포함 (default 메서드 예외) |
속성 | 인스턴스 변수 포함 가능 | 상수만 포함 가능 (public static final 자동 적용) |
사용 | 특정 공통 동작의 기본 구현 제공 | 클래스 간 규약을 강제 |
언제 사용해야 할까?
- 추상 클래스: 공통 동작과 필드(상태)를 공유해야 하며, 기본 구현이 필요한 경우.
- 인터페이스: 서로 다른 클래스 간의 일관된 규약을 강제하고, 다중 구현이 필요한 경우.
Dart에서의 추상클래스
abstract class Animal {
void performAction();
}
// 추상클래스를 구현할 때 implements 를 사용한다.
class Dog implements Animal {
@override
void performAction() {
print('멍멍 배고파!');
}
}
class Cat implements Animal {
@override
void performAction() {
print('야옹 배고파!');
}
}
class Fish implements Animal {
@override
void performAction() {
print('뻐끔뻐끔 배고파!');
}
}
// 동적 바인딩이란 뭘까?
void start(Animal a) {
// performAction() 메서드가 동작하게 만들고 싶다.
// 단. 강아지든, 고양이든, 물고기든 동적으로 들어 오더라도
// performAction() 호출 되게 설계해야 해!
a.performAction();
}
void start1(Cat c) {
c.performAction();
}
void start2(Dog c) {
c.performAction();
}
void start3(Fish c) {
c.performAction();
}
void main() {
start(Dog());
start(Cat());
start(Fish());
}
Quiz
추상 클래스와 동적 바인딩을 활용한 다형성 구현하기
Shape라는 추상 클래스를 정의하고, 이를 상속받은 Circle과 Rectangle 클래스가 있습니다. calculateArea 함수를 통해 동적 바인딩을 활용하여 다양한 도형의 면적을 계산할 수 있도록 구현하세요
// 추상 클래스
abstract class Shape {
// 메서드의 바디(구현부) 없다면 추상 메서드 이다.
double getArea();
}
class Circle implements Shape {
final double radius;
// 생성자는 가능한 축약형으로 만들자 - 우리의 규칙
Circle(this.radius);
// 면접을 구하는 행위를 해야 한다.
@override
double getArea() {
return 3.14 * radius * radius;
}
}
class Rectangle implements Shape {
final double width;
final double height;
Rectangle(this.width, this.height);
// 면접을 구하는 행위를 해야 한다.
@override
double getArea() {
return width * height;
}
}
// 동적 바인을 활용한 함수를 설계해보자.
// 전역 함수
void calculateArea(Shape s) {
// 전달된 도형의 면접을 출력하시오.
print(s.getArea());
}
void main() {
Shape myCircle = Circle(5.0);
Shape myRectangle = Rectangle(4.0, 6.0);
calculateArea(myCircle);
calculateArea(myRectangle);
}
'앱개발 > Flutter' 카테고리의 다른 글
[Flutter] #9 ListView, GridView, PageView 위젯 (0) | 2025.01.14 |
---|---|
[Flutter] #8 - 플러터의 핵심 철학과 프로젝트 구조 (0) | 2025.01.14 |
[Flutter] #6 Dart 기본 문법 연관관계와 믹스인 (0) | 2025.01.07 |
[Flutter] #5 Dart 기본 문법 상속과 super 키워드 (0) | 2025.01.06 |
[Flutter] #4 Dart 기본 문법 Null Safety (0) | 2025.01.06 |