SQL의 종류

1. DDL: 데이터 정의 언어

CREATE TABLE users (id SERIAL, name VARCHAR(255));

ALTER TABLE users
ADD COLUMN status ENUM('active', 'inactive') DEFAULT 'active';

DROP TABLE users;

     1) 테이블 생성: CREATE TABLE

     2) 테이블 수정: ALTER TABLE

     3) 테이블 삭제: DROP TABLE

     4) 테이블 초기화: TRUNCATE TABLE

          - 데이터 초기

 

2. DML: 데이터 조작 언어

INSERT INTO users (name) VALUES (?)

SELECT name FROM users WHERE id = ?

SELECT * FROM users
WHERE status = 'active';

UPDATE users SET name = ? WHERE id = ?

     1) 데이터 선택: SELECT

     2) 조건 설정: WHERE

     3) 정렬: ORDER BY

     4) 그룹화: GROUP BY

     5) 결합: JOIN

     6) 추가: INSERT INTO

     7) 수정: UPDATE

     8) 삭제: DELETE FROM

 

3. DCL: 데이터 제어 언어

     1) 권한 부여: GRANT

     2) 권한 삭제: REVOKE

 

4) TCL

     1) 새로운 트랜잭션 생성 및 시작: BEGIN     // START TRANSACTION과 동일

     2) 하나의 트랜잭션 성공적으로 종료(DB 일관성있는 상태에 있음): COMMIT

          - COMMIT 시 수행한 트랜잭션이 로그에 저장된다.

     3) 하나의 트랜잭션 비정상적으로 종료(트랜잭션의 원자성 깨짐)되어 트랜잭션의 연산 결과 취소: ROLLBACK

 

트랜잭션

: DB 상태를 변화시키기 위해 수행하는 작업 단위이다.

- 데이터 조회, 생성, 수정, 삭제 후 최종 결과물을 만들 때까지의 하나의 작업을 트랜잭션으로 관리할 수 있다.

- 데이터 처리 중 문제 발생 시 변경 사항을 되돌린다.(rollback)

- 모든 단위 기능(조회, 수정 등...)이 성공해야 트랜잭션이 성공된다.(commit)

 

특징

1) 원자성

- 트랜잭션이 db에 모두 반영되거나 전혀 반영되지 않아야한다.

2) 일관성

- 트랜잭션의 작업 처리 결과가 항상 일관성 있어야 한다.

     - 트랜잭션 진행 동안에 db 변경 시에도 바뀐 db가 아니라 처음 진행 시 참조한 db로 진행된다.

3) 독립성

- 복수의 트랜잭션이 동시 실행돼도 서로의 연산에 관여할 수 없다.

'Language > SQL' 카테고리의 다른 글

내장형 H2 데이터베이스 사용  (0) 2025.06.26

방식 3가지

Mode H2 다운로드 여부 실행 주체 DB 저장 위치
Server Mode O 외부 로컬(파일 시스템)
In-Memory Mode X 스프링 메모리
Embedded Mode X 스프링 로컬(파일 시스템)

 

1) Server Mode

: 직접 엔진 설치해 사용한다.

- 외부 db 엔진이 구동된다.

- 애플리케이션 외부에 데이터가 저장되어 애플리케이션 종료 시에도 데이터가 유지된다.

 

2) In-Memory Mode

: 엔진을 설치하지 않고 애플리케이션 내부 엔진을 사용한다.(애플리케이션에 DB 엔진 내장)

- build.gradle 및 application.properties 설정을 통해 실행 가능하다.

# application.yml
spring:  
    datasource:    
        driver-class-name: org.h2.Driver
        url: jdbc:h2:mem:{DB 이름}
        username: sa
        password:
# application.properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:{DB 이름}
spring.datasource.username=sa
spring.datasource.password=

- 애플리케이션과 DB 엔진이 함께 실행, 종료된다.

- 애플리케이션 메모리에 데이터가 저장되어 애플리케이션 종료 시 데이터가 사라진다.

     => 단위 테스트 등에서 많이 사용한다.

 

3) Embedded Mode

: 엔진을 설치하지 않고 애플리케이션 내부 엔진을 사용한다.

- build.gradle 및 application.properties 설정을 통해 실행 가능하다.

# application.yml
spring:
  datasource:
      driver-class-name: org.h2.Driver
      url: jdbc:h2:{DB가 저장될 경로}    
      username: sa    
      password:
# application.properties
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:~/testdb			// 경로를 ~/testdb로 설정한 예시로 ~는 홈 디렉터리를 의미하며 홈 디렉터리 아래 testdb.mv.db파일로 저장된다.
spring.datasource.username=sa
spring.datasource.password=

- 애플리케이션과 DB 엔진이 함께 실행, 종료된다.

- 애플리케이션 외부에 데이터가 저장되어(로컬)  애플리케이션 종료 시에도 데이터가 유지된다.

     => 간단한 애플리케이션에 적합하다.

'Language > SQL' 카테고리의 다른 글

SQL의 종류와 트랜잭션  (0) 2025.06.26

JAVA 명명법

종류 설명 예시
project, repository 대/소문자 구분없이 시작 MyProject
package 소문자 시작 com.sparta.homework
class 대문자 시작, 명사 사용, PascalCase class Person;
interface 대문자 시작, 형용사 사용, PascalCase interace Runnable;
method 소문자 시작, 동사 사용, camelCase calculate();
variable 소문자 시작, camelCase int number;
constant 대문자 시작, 문자 사이는 '_'로 구분 static final int MAX_COUNT = 999;

 

프로그래밍 명명 규칙

1. snake_case

: 문자와 문자 사이를 '_'로 구분하는 규칙

- python, DB Table, Column에 사용

- 대소문자

ex) program_naming

 

2. camelCase

: 문자와 문자 사이를 대문자로 이어주는 규칙

- Java, JavaScript, TypeScript에서 변수, 함수, 메서드 명명 시 사용

ex) programNaming

 

3. PascalCase

: 문자 첫 시작이 대문자이고 문자 사이를 대문자로 이어주는 규칙

- 대부분의 프로그래밍 언어에서 클래스 이름 지정 시 사용

ex) PreciseCalculator

 

4. kebab-case

: 문자와 문자 사이를 '-'로 이어주는 규칙

- 모든 단어 소문자

ex) program-naming

'Language > Java' 카테고리의 다른 글

Lamda  (0) 2025.04.21
Generic  (0) 2025.04.19
BigDecimal  (2) 2025.04.18
nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 다형성  (0) 2025.04.15

Lamda expression

: 함수형 인터페이스 안에 정의된 하나의 추상 메서드(SAM) 선언을 간결하게 표현한 것이다.

// 함수형 인터페이스: 딱 하나의 추상 메서드가 선언된 인터페이스이다. 

@FunctionalInterface
interface 함수형인터페이스명{
	//한 개의 추상 메서드
}

public class Main{
	public static void main(String[] args){
    	함수형인터페이스명 구현체명 = (메서드 매개변수) -> {
        	//메서드 본문
        }
    }
}

 

 

특징

1) 메서드 반환 타입, 이름, 매개변수 타입, return 생략 가능

//메서드 반환 타입, 이름 생략 가능
(int a, int b)->{
	return a + b;
}

// 매개변수 타입 생략 가능
(a, b)->{
	return a + b;
}

// return 생략 가능
(a, b)-> a + b;

1-1) 타입 생략이 가능한 이유

: 컴파일러가 람다 함수식을 보고 추론하여 타입을 유추한다. 

 

2) 변수에 함수 할당 가능

//함수형 인터페이스
interface Add{
	int add(int a, int b);
}

public class Main{
	public static void main(String[] args){
    	Add lamdaAdd = (x, y) -> x + y;	// 변수에 함수 할당
        lamdaAdd.add(1, 2);	//함수 사용
    }
}

 

3) 매개변수에 람다식 전달 가능

interface Add{
	int add(int a, int b);
}


public class Main{
	public static void main(String[] args){
    	int n = result((a, b) -> a + b);	//메서드 매개변수에 람다식 전달
    }

	public static int result(Add lamdaAdd){
    	return lamdaAdd.add(1, 2);
    }
}

 

4) 람다식을 반환값으로 사용 가능

interface Add{
	int add(int a, int b);
}

public class Main{
	public static void main(String[] args){
    	int fn = function();	//메서드 반환값이 람다식
        int result = fn.add(1, 2);
    }

	public static Add function(){
    	return (a, b) -> a + b;
    }
}

 

3~4)의 특징이 가능한 이유

: 람다식이 컴파일하면서 함수형 인터페이스의 인스턴스로 변환되기 때문이다.

 

 

한계

1) 문서화 할 수 없다.

2) 까다로운 디버깅: 문제가 어디서 발생했는지 확인하기 어렵다.

3) stream에서 람다를 사용하면 for문보다 성능이 떨어진다.

4) 람다식 남발 시 코드가 지저분해질 수 있다.

5) 재귀함수를 구축할 수 없다.

 

 

익명 클래스 방식과 람다식 방식 비교

1. 익명 클래스 방식

- 복잡하다

- 추상 메서드가 한 개 이상이더라도 사용할 수 있다.

@FunctionalInterface
interface Add{
	int add(int a, int b);
}

//익명 클래스 방식
Add a = new Add(){
    @Override
    int add(int a, int b){
    	return a + b;
    }
}

 

2. 람다식 방식

- 단순하다

- 추상 메서드가 한 개만 존재(SAM)할 때 사용할 수 있다.

@FunctionalInterface
interface Add{
	int add(int a, int b);
}

//익명 클래스 방식
Add a = (a, b) -> a + b;

 

정리

: 추상메서드가 한 개일 때 함수형 인터페이스를 구현한 익명 클래스가 사용되던 자리를 추상 메서드를 구현한 람다식으로 대체할 수 있다.

'Language > Java' 카테고리의 다른 글

JAVA 명명법  (0) 2025.05.02
Generic  (0) 2025.04.19
BigDecimal  (2) 2025.04.18
nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 다형성  (0) 2025.04.15

제네릭

문제 

1. 제네릭 없는 클래스: 재사용이 불가하다.

- 원인: 타입이 고정되어 있다.

//Integer타입으로 고정되어 있어 다른 타입으로 재사용 불가하다.(다시 생성해야 된다.)

public class NoGeneric{
	private Integer n;
    
    public NoGeneric(Integer n){
		this.n = n;
	}

	public Integer getN(){
    	return this.n;
	}
}

 

2. 제네릭 없는 클래스: 낮은 타입 안정성

- 원인: 다형성을 통해 다양한 타입 저장 가능하지만 런타임 에러가 발생할 수 있다. 사용 시 형 변환이 필요하다.

public class ObjectClass{
	private Object n;
    
    public Object(Object n){
    	this.n = n;
    }

	public Object getObject(){
    	return this.n;
    }
}

 

public class Main{
	public static void main(String[] args){
    	ObjectClass objClass = new ObjectClass("String");	//문자열
        String s = (String)objClass.getN();	//형변환 필수
    	
		objClass = new ObjectClass(10);	//정수
        String error = (String)objClass.getN();	// 에러 발생: ClassCastException
	}
}

 

 

제네릭<T>

제네릭: 타입을 미리 지정하지 않고 사용 시점에 유연하게 결정할 수 있는 문법이다.

- 클래스, 메서드 등에 사용되는 <T>타입 매개변수

//타입의 경계 지정하고 컴파일 시 해당 타입으로 캐스팅한다.

 

 

제네릭 클래스

: 클래스 선언부에 <T>가 선언된 클래스다.

 

 

제네릭 클래스 선언

public class GenericClass<T>{
	private T t;
    
    public GnericClass(T t){
    	this.t = t;
    }
	
    public T getT{
    	return this.t;
    }
}

 

 

특징

- 코드 재사용성

: 다양한 타입에서 동일한 코드로 재사용 가능하다.

// 제네릭 클래스로 String, Integer, Double 등 다양한 타입을 저장할 수 있다.

// 컴파일 시 타입소거(T->Object)
GenericClass<String> strClass = new GenericClass<>("String");
GenericClass<Integer> intClass = new GenericClass<>(65);
GenericClass<Double> doubleClass = new GenericClass<>(6.5);

 

- 타입 안정성

: 잘못된 타입 사용을 컴파일 시점에 방지한다.

// 자동 다운캐스팅
String strClass = strClass.getT();
Integer intClass = intClass.getT();
Double doubleClass = doubleClass.getT();

 

타입 소거

: 컴파일 시점에 제네릭 타입 정보를 제거하는 과정

- <T>타입 매개변수가 Object로 대체된다.

- 필요에 따라 컴파일러가 자동으로 강제 다운 캐스팅 코드를 삽입해 타입 안정성을 보장한다.

 

 

제네릭 메서드

: 메서드 내부에서 사용할 타입을 유연하게 저장하는 기능으로 메서드 선언부에 <T>가 선언된다.

 

특징

: 클래스 제네릭 타입과 별개로 독립적인 타입 매개변수를 가진다.

public class GenericClass<T>{
	private T t;
    
    public GnericClass(T t){
    	this.t = t;
    }
	
    public T getT{
    	return this.t;
    }
    
    //제네릭 메서드 => <S>와 <T>는 독립적
    public<S> void printT(S s){
    	System.out.println(s);
    }
    
    //일반 메서드였다면 클래스의<T>를 따라감
}
public class Main{
	public static void main(String[] args){
    	ObjectClass objClass = new ObjectClass("String");
        
        objClass.printT("String");
        objClass.printT(65);	//에러x
        objClass.printT(6.5);	//에러x
	}
}

'Language > Java' 카테고리의 다른 글

JAVA 명명법  (0) 2025.05.02
Lamda  (0) 2025.04.21
BigDecimal  (2) 2025.04.18
nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 다형성  (0) 2025.04.15

문제

: 실수 계산 시 정확한 값이 출력되지 않는다. 

    	double d1 = 0.10000000000000000009;
    	double d2 = 0.0000000000000000001;
    	
    	System.out.println("d1 - d2 = " + (d1 - d2));

-출력-

d1 - d2 = 0.1     //예상 출력값 = 0.09999999999999999999

 

 

원인

: Java는 IEEE 754 부동 소수점 방식을 사용해 정확한 실수가 아니라 근사치를 저장한다.

 

 

해결책

: java.math.BigDecimal 클래스

- 정수 값과 정밀도(소수점 이하 자릿수)를 따로 저장해 정수 값으로 연산 후 정밀도를 적용한다.

    	//double d1 = 0.10000000000000000009;
    	//double d2 = 0.0000000000000000001;
    	
    	BigDecimal d1 = new BigDecimal("0.10000000000000000009");
    	BigDecimal d2 = new BigDecimal("0.0000000000000000001");
    	
    	//System.out.println("d1 - d2 = " + (d1 - d2));
    	System.out.println("d1 - d2 = " + d1.subtract(d2));

-출력-

d1 - d2 = 0.09999999999999999999

 

 

BigDecimal

1. BigDecimal 클래스 내부 일부

example: 5.0143

 

- intVal

: unscaledValue()에 의해 소수점 정보가 배제된 정수를 담은 BigInteger 객체가 저장된다.

// 50143

 

- scale

: scale()에 의해 소수점 자리수를 저장한다.(소수점 첫째 자리 ~ 오른쪽부터 0이 아닌 수로 끝나는 위치)

// 4

 

- precision

: precision()에 의해 총 자리수를 저장한다.(왼쪽이 0이 아닌 수로 시작하는 위치 ~ 오른쪽이 0이 아닌 수로 끝나는 위치)

// 5

 

- signum()

: 부호를 저장한다

// 1

 

 

2. 선언

: BigDecimal 이름 = new BigDecimal("값");

- import java.math.BigDecimal 필요

- 파라미터를 String으로 받는 이유: 오차가 발생할 수 있기 때문이다. //정확도

 

 

3. 연산

: 메서드 활용

example: n1, n2 연산

 

1) 덧셈

: n1.add(n2);

 

2) 뺄셈

: n1.subtract(n2);

 

3) 곱셈

: n1.multiply(n2);

 

4) 나눗셈

: n1.divide(n2, scale, roundingMode);

 

- 반올림 처리: RoundingMode의 상수 이용

상수 역할
.CEILING 올림
.FLOOR 내림
.UP 양수: 올림, 음수: 내림
.DOWN 양수: 내림, 음수: 올림
.HALF_UP 반올림(5 이상: 올림, 5 미만: 버림)
.HALF_EVEN 반올림(반올림 자리값 짝수: HALF_DOWN, 홀수: HALF_UP)
.HALF_DOWN 반올림(5 이상: 올림, 5 미만: 버림)
.UNNECESSARY 나눗셈 결과 딱 안 떨어지면 ArithmeticException 발생

 

- 소수점 위치 변경

 

 

5) 나머지

: n1.remainder(n2);   // 결과값 음수여도 리턴

: n1.mod(n2);   // 결과값 음수면 ArithmeticException

6) 비교

: n1.compareTo(n2);

     - n1 < n2: -1

     - n1 == n2: 0

     - n1 > n2: 1

 

 

4. 형변환

example: n1 형변환

1) int

: n1.intValue();

 

2) long

: n1.longValue();

 

3) float

: n1.floatValue();

 

4) double

: n1.doubleValue();

 

5) String

: n1.toString();

 

 

5. 기본 상수

1) 0

: BigDecimal.ZERO;

 

2) 1

: BigDecimal.ONE;

 

3) 10

: BigDecimal.TEN;

'Language > Java' 카테고리의 다른 글

Lamda  (0) 2025.04.21
Generic  (0) 2025.04.19
nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 다형성  (0) 2025.04.15
OOP - 추상화  (0) 2025.04.15

문제

: 첫 입력 후 다음 입력을 받아야 하는 상황에서 입력을 받지 못하고 넘어가버린다. 

    	System.out.print("정수 입력: ");
    	sc.nextInt();
    	//sc.nextLine();
    	System.out.print("문자열 입력: ");
    	sc.nextLine();
    	System.out.println("종료");

-출력-

정수 입력: 10

문자열 입력: 종료

 

 

원인

: 버퍼에 Enter가 남아 있다.

- next(): 문자열을 입력받되 공백과 Enter를 포함하지 않고,

- nextInt(): 정수를 입력받되 공백과 Enter를 포함하지 않으며,

- nextDouble(): 실수를 입력받되 공백과 Enter를 포함하지 않는다.

=> 공백이나 Enter 입력 전까지의 문자나 숫자만 입력된다.

=> Enter가 버퍼에 남는다. 

=> 다음 입력에서 값을 입력한 것으로 인식되어 넘어가고 입력을 못 받는다. 

 

 

해결책

: nextLine()

- 공백과 Enter까지 입력을 받는다.

=> 공백을 포함해서 엔터까지 버퍼에 들어간다.

    	System.out.print("정수 입력: ");
    	sc.nextInt();
    	sc.nextLine();
    	System.out.print("문자열 입력: ");
    	sc.nextLine();
    	System.out.println("종료");

-출력-

정수 입력: 10

문자열 입력: nextLine method 사용

종료

'Language > Java' 카테고리의 다른 글

Generic  (0) 2025.04.19
BigDecimal  (2) 2025.04.18
OOP - 다형성  (0) 2025.04.15
OOP - 추상화  (0) 2025.04.15
OOP - 상속과 오버라이딩  (0) 2025.04.15

다형성

: 하나의 타입으로 여러 객체를 다룰 수 있는 기능

 

형변환(Casting)

1. 업캐스팅

: 자식 클래스의 객체를 부모 클래스 타입으로 변환하는 것

- 자동 형변환

Animal animal = new Dog();

 

특징: 자식 클래스의 고유 기능 사용 불가 

     => 부모 클래스의 멤버만 접근 가능

 

 

2. 다운캐스팅

: 부모 클래스의 객체를 자식 클래스 타입으로 변환하는 것

- 명시적 형변환: (자식 클래스 타입)

Animal animal = new Dog();
Dog dog = (Dog)animal;

 

특징: 자식 클래스 고유 기능 사용 가능 

 

 

다운 캐스팅 유의점

: 잘못된 다운캐스팅 컴파일 단계에서 감지 불가 => 런타임 시점에 ClassCastException 발생

이유: 문법적 에러는 아니기 때문

public class Main {

    public static void main(String[] args) {
        // 다운 캐스팅
        Animal dog = new Dog();
        //에러 발생x
        Cat cat1 = (Cat) dog; 
        cat1.scratch(); // 에러 발생
    }
}

 

해결책

: instanceof 사용해 미리 타입 검사

     - 객체가 특정 클래스나 인터페이스의 인스턴스인지 확인

public class Main {

    public static void main(String[] args) {

        Animal animal = new Dog();

		// animal이 Cat의 인스턴스인가 확인
        if (animal2 instanceof Cat) {
            Cat cat = (Cat) animal2;
            cat.scratch();
        } else {
            System.out.println("객체가 고양이가 아닙니다.");
        }
    }
}

'Language > Java' 카테고리의 다른 글

BigDecimal  (2) 2025.04.18
nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 추상화  (0) 2025.04.15
OOP - 상속과 오버라이딩  (0) 2025.04.15
OOP - 캡슐화  (0) 2025.04.15

추상화

: 특정 계층에 필요한 본질적 특성만 유지하고 불필요한 세부사항을 숨기는 특징

 

구현

1) 추상 클래스

     - 계층적 구조 표현 및 공통 속성과 기능 재사용에 적

2) 인터페이스

     - 표준 제공에 적합

     - 인스턴스 변수 선언 불가     // 인스턴스 변수: static 키워드 붙지 않은 변수

 

 

추상 클래스

: 공통 기능을 제공하면서 하위 클래스에 특정 메서드 구현을 강제하기 위해 사용

 

선언

: abstract 키워드

 

상속

: extends 키워드

 

특징

- 최소한의 틀이자 미완성 설계도

- 객체 생성 불가

- 상속을 통해 하위 클래스에서 완성     // 자식 클래스에서 강제로 구현

- 다중 상속 불가

 

 

추상클래스와 인터페이스

  추상 클래스 인터페이스
선언 키워드 abstract interace
사용 가능 변수 no limit static final
사용가능 접근 제어자 no limit public
사용 가능 메서드 no limit abstract, default, static, private method
상속 키워드 extends implements
다중 상속 unable able(인터페이스끼리 또는 클래스에 다중구현)
공통점 1. 추상 메서드 가져야 함

2. 인스턴스화 불가능

3. 인터페이스 or 추상 클래스 상속받아 구현한 구현체의 인스턴스를 사용해야 함

4. 구현체는 반드시 추상 메서드를 구현해야 

 

'Language > Java' 카테고리의 다른 글

nextLine()으로 Scanner 입력 버퍼 비우기  (0) 2025.04.18
OOP - 다형성  (0) 2025.04.15
OOP - 상속과 오버라이딩  (0) 2025.04.15
OOP - 캡슐화  (0) 2025.04.15
Interface  (0) 2025.04.15

상속

: 클래스 간 관계를 부모(super)와 자식(sub)로 바라보는 개념

 

특징

1. 재사용성

: 부모 클래스의 내용을 물려받아 재사용

 

2. 확장

: 부모 클래스 기능 유지하면서 자식 클래스에서 기능 확장 가능

=> 자식 클래스에서 새 메서드 추가하는 것

 

 

구현

: extends 키워드

 

필요성

: 코드의 중복성 감소 및 유지보수성 향상 

 

Super

: 부모 클래스의 멤버에 접근 시 사용하는 키워드

// 부모클래스의 변수와 이름이 같은 변수를 자식클래스에 선언 가능

     => 동일 이름의 변수 있으면 자식 클래스 변수 우선

System.out.println("this.name");	// 현재클래스 name
System.out.println("super.name");	// 부모클래스 name

 

 

Super()

: 부모 인스턴스의 생성자

- 생성자는 부모 먼저 생성 후 자식이 생성

     => 자식 생성자의 첫 줄에는 super();을 통해 부모 클래스의 생성자가 먼저 호출됨()

public Child(){
     super();
    //추가 로직
}

 


오버라이딩

: 부모 메서드를 자식 클래스에서 재정의하는 것

- @Override 키워드 기재(권장)

 

특징

- 접근 제어자: 부모보다 더 강한 수준으로만 변경 가능

 

public class Parent{
	public void intoduce(){
    	System.out.println("부모님을 소개합니다.");
    }
}


class Child extends Parent{

	@Override
    void introduce(){
    	System.out.println("자식을 소개합니다.");
    }
}

'Language > Java' 카테고리의 다른 글

OOP - 다형성  (0) 2025.04.15
OOP - 추상화  (0) 2025.04.15
OOP - 캡슐화  (0) 2025.04.15
Interface  (0) 2025.04.15
final 키워드, 상수, 불변 객체  (0) 2025.04.15

+ Recent posts