# TIL: 2025-05-14 나의 힐링타임은 어디에…🥹

heeezni·2025년 5월 17일
post-thumbnail

1. 상속

상속파트는 Java와 JS 병행했는데,
둘이 상당히 비슷해서 Java 정리한 것을 링크로 남기겠음.

⬇ ⬇ ⬇ ⬇ ⬇

Java에서의 상속 1

Java에서의 상속 2

Java와 JavaScript 상속 비교

항목JavaJavaScript (ES6 기준)
클래스 선언class 키워드 사용class 키워드 사용
상속 선언extends 사용extends 사용
부모 생성자 호출선택적으로 super() 호출 가능
(필요할 때만)
반드시 super() 먼저 호출해야 함
생성자클래스 이름과 같음constructor() 메서드로 정의
멤버변수 선언클래스 블록 안에 바로 선언constructor() 안에서 선언
접근 제한자private, protected, public 지원접근 제한자 없음 (전부 public)
오버라이딩@Override로 명시 가능
(정확히 오버라이드 했는지 검증해주는 안전장치)
그냥 동일한 이름의 메서드로 덮어씀
정적(static) 멤버static 키워드 사용static 키워드 사용 (ES6부터 지원)

JavaScript의 상속에서 주목해야할 차이점

JS와 Java는 둘 다 상속관계에서 자식의 인스턴스가 초기화 되기 전에 부모의 인스턴스 초기화가 앞서야 함은 동일하지만,

✅JS에서는 자식 클래스에서 생성자 constructor()를 정의하면,
무조건 super()를 가장 먼저 호출해야 한다.
super()는 부모의 constructor()를 의미
이걸 호출해야만 this를 사용할 수 있다.

class Bird{
    constructor(color,age){
        this.color=color;
        this.age=age;
        console.log("Bird의 생성자 호출됨");
    }
}

Duck이라는 자식클래스가 Bird라는 부모클래스를 상속받을 때, 생성자를 생성하려면 super()로 무조건 부모 생성자 호출 (매개변수가 있으면 매개변수도 꼭 맞춰줘야함)

class Duck extends Bird{
    constructor(color,age){
        super(color,age); // "부모님아 먼저 초기화되세요~"
     	console.log("Duck의 생성자 호출됨");
    }
}

2. 오버라이딩

오버라이딩 시 접근 제한자 규칙

  • 자식이 부모의 메서드를 오버라이딩 할 때는
    부모의 접근 제한자보다 강력하게 설정할 수 없다! (접근범위 좁히기❌)
    (같거나 그보다 약하게 설정)
    강력함 | private < default < protected < public | 느슨함

<오버로딩과 오버라이딩>

구분오버로딩 (Overloading)오버라이딩 (Overriding)
정의같은 이름의 메서드를 매개변수리턴 타입을 다르게 정의하는 것.부모 클래스의 메서드를 자식 클래스에서 재정의하는 것.
목적메서드 이름을 재사용하여 코드 중복을 줄이기 위해.상속받은 메서드의 기능을 자식 클래스에서 변경하거나 확장하기 위해.
메서드 이름동일동일
매개변수매개변수의 개수타입이 달라야 함부모 클래스의 메서드와 매개변수가 동일해야 함
리턴 타입리턴 타입도 동일하거나 달라도 됨리턴 타입은 부모 메서드와 같아야
접근 제어자자식 클래스에서 변경 가능, 부모 클래스의 접근 제어자보다 넓게 설정 가능부모 클래스의 메서드보다 좁게 설정 불가
  • 오버로딩은 메서드 이름은 같고, 매개변수의 개수 또는 타입이 다르게 정의하는 것. (리턴 타입은 상관없음)
  • 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하여 기능을 변경하는 것.

3. 충돌체크

게임만들 때 필요한 충돌체크 코드를 만들어보자!
(ex. 총알이 물체에 닿았을 때 조건주려면 필요)

// 충돌체크함수
// API 사용 예)
function collisionCheck(me,target){
    // 1. me의 위치와 크기 정보
    const me_x= parseInt(me.style.left);
    const me_y= parseInt(me.style.top);
    const me_width=parseInt(me.style.width);
    const me_height=parseInt(me.style.height);

    // 2. target의 위치와 크기 정보
    const target_x= parseInt(target.style.left);
    const target_y= parseInt(target.style.top);
    const target_width=parseInt(target.style.width);
    const target_height=parseInt(target.style.height);
  
	// 3. 충돌이 아닌 조건 중 하나라도 만족하면 false, 아니면 true
    return!(
    me_x+me_width < target_x || //me의 오른쪽이 타겟의 왼쪽보다 왼쪽에 있으면
    me_x > target_x+target_width || //me의 왼쪽이 타겟의 오른쪽보다 더 오른쪽이면 
    me_y+me_height < target_y || // me의 아래쪽이 타겟의 위보다 위에 있으면
    me_y > target_y+target_height // me의 아래쪽이 타겟의 아래보다 아래에 있으면
    )
}
  • !() 이기 때문에, 조건문 안의 "충돌이 아닌 상황" 중 하나라도 해당되면 false (충돌 아님)
    모두 해당되지 않아야 true (충돌함)
addEventListener("load", function(){
    init(); // 초기화 함수 호출 (예: box1, box2 셋팅)
    
    addEventListener("mousemove", function(e){
        // box1을 마우스 위치로 이동
        box1.style.left = e.clientX + "px";
        box1.style.top = e.clientY + "px";

        // box1과 box2 충돌 여부 체크
        let result = collisionCheck(box1, box2);
        console.log(result);  // true면 충돌, false면 비충돌

        // 결과에 따라 색상 변경
        if (result){
            box2.style.background = "yellow"; // 충돌 시 노란색
        } else {
            box2.style.background = "blue";   // 아닐 땐 파란색
        }
    });
});

4. SQL - GROUP BY, HAVING, INNER JOIN, OUTER JOIN

GROUP BY

소속된 총 사원 수가 5명 이상인 부서의 부서번호, 소속 사원수를 출력하세요

SELECT D.DEPTNO AS 부서번호, COUNT(EMPNO) AS 소속사원수
FROM EMP E, DEPT D
WHERE E.DEPTNO=D.DEPTNO
GROUP BY D.DEPTNO
HAVING COUNT(EMPNO)>=5;
  • 부서마다, 부서 별 : GROUP BY
  • GROUP BY에 명시한 컬럼만이 SELECT의 대상이 될 수 있음
    + GROUP BY에 없는 컬럼을 SELECT 하려면 반드시 집계 함수를 사용해야 함
  • 압축본(GROUP BY)에 조건을 줄 때는 WHERE이 아니라 HAVING을 사용

WHERE은 집계하기 전 필터링
HAVING은 집계한 후 조건 걸기

INNER JOIN

  • INNER JOIN : "공통인 것만 가져올거야" (교집합)
  • WHERE 대신 ON (JOIN 전용 WHERE)

SMITH가 소속된 부서의 총 사원수보다 소속 사원 수가 더 많은 부서의 부서번호, 부서명, 부서위치를 출력하세요

SELECT COUNT(EMPNO), D.DEPTNO
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO=D.DEPTNO
GROUP BY D.DEPTNO
HAVING COUNT(EMPNO)>
(SELECT COUNT(*)
FROM EMP
WHERE DEPTNO=(SELECT DEPTNO FROM EMP WHERE ENAME='SMITH'));

★ SMITH가 소속된 부서의 총 사원수보다 소속 사원 수가 더 많은 부서의 부서번호, 부서명, 부서위치를 출력하세요

SELECT DEPTNO, DNAME, LOC
FROM DEPT
WHERE DEPTNO =(
SELECT D.DEPTNO
FROM EMP E INNER JOIN DEPT D
ON E.DEPTNO=D.DEPTNO
GROUP BY D.DEPTNO HAVING COUNT(EMPNO) > (
SELECT COUNT(*) FROM EMP WHERE DEPTNO=
(SELECT DEPTNO FROM EMP WHERE ENAME='SMITH')));

참고) JOIN 단독으로 쓰면 INNER JOIN과 동일한 의미

OUTER JOIN

  • OUTER JOIN에서 "OUTER가 되는 기준"은 바로
    "어느 테이블의 모든 데이터를 반드시 보여줄 것인가?"에 달려 있음

RIGHT OUTER JOIN

"오른쪽 테이블 기준으로 무조건 다 보여줘!
왼쪽 테이블에 매칭되는 게 없으면 NULL로 채워줘!"

  • LEFT OUTER JOIN도 마찬가지
  • OUTER는 생략가능

부서번호, 부서명, 위치, 소속 사원번호, 소속 사원명을 출력하되,
사원이 소속 되지 않은 부서까지도 포함하세요 (이 경우 사원정보는 NULL로 출력)

SELECT DEPTNO, DNAME, LOC, EMPNO, ENAME
FROM EMP E RIGHT OUTER JOIN DEPT D
ON E.DEPTNO=D.DEPTNO

5. UNION

  • UNION(연합) : 위아래로 표 합치기, 전혀 관련성 없는 것들을 짜집기
    (JOIN은 부모-자식 간 데이터 조합이지만
    UNION은 전혀 관련성 없는 데이터들을 조합하는 쿼리)

  • 조건: 관련성 없어도 위아래 자료형 통일성 있어야함
    (열의 개수, 순서, 데이터형이 같아야 함)

(JOIN은 부모-자식 간 데이터 조합이지만
UNION은 전혀 관련성 없는 데이터들을 조합하는 쿼리

SELECT ENAME, SAL FROM EMP
UNION
SELECT DNAME, DEPTNO FROM DEPT

-- 계약직과 정규직 사원을 통합 조회
SELECT NAME, '계약직' AS 구분 FROM CONTRACT_EMP
UNION
SELECT NAME, '정규직' AS 구분 FROM FULLTIME_EMP

⚠ 주의 ⚠

  • AS는 값을 바꾸는 게 아니라, 열↕ 이름을 바꾸는 것.
  • 쿼리에서 작은따옴표 ' '로 감싼 건 무조건 값(리터럴)이고,
    아무리 테이블에 동일한 이름의 컬럼이 있어도 컬럼으로 인식되지 않음

짝꿍이 내준 SQL문제 (어려웠음 ㅠㅠ)
내가 젤 어려워하는 EMPNO-MGR 관계의 사수문제 ㅠㅠ

BLAKE가 사수인 직원들의 사원번호, 사원명, 사수명, 부서번호, 부서명, 위치를 출력하세요

⭐포인트는 EMP 테이블을 E, M이라는 두 별칭으로 자기 자신과 조인하는 것 (SELF JOIN)

SELECT E.EMPNO, E.ENAME, M.ENAME AS MGR_NAME, D.DEPTNO, DNAME, LOC 
FROM EMP E 
--1️⃣ (SELF JOIN)
INNER JOIN EMP M
ON E.MGR=M.EMPNO
--2️⃣
INNER JOIN DEPT D
ON E.DEPTNO=D.DEPTNO
WHERE E.MGR=(SELECT EMPNO FROM EMP WHERE ENAME='BLAKE'); 
  • EMP E는 사원을 찾기위한 테이블
    EMP M은 사수를 찾기 위한 테이블
    ➡ 사수의 EMPNO와 사원의 MGR가 같은 사수의 ENAME이 'BLAKE'여야함 (조인1)

  • 그리고 DEPT테이블의 컬럼도 들어있으므로
    DEPT테이블과도 조인하기(조인2)


느낀 점

예전에 SQL시간이 어려울 땐 JS시간이 힐링타임이었고, JS이 빡세지면서 SQL시간이 한숨 돌리는 시간이었는데
이젠… 없다 흑흑… Java는 더 빡센데!!!!!!
그래도 내가 도파민 중독걸인데 배움으로 도파민이 뿜뿜하는 걸 느끼는 요즘이다 하하~^^
왜냐면 삶이 전~~~혀 지루하지가 않음!
완전 럭키비키잖아🍀

profile
아이들의 가능성을 믿었던 마음 그대로, 이제는 나의 가능성을 믿고 나아가는 중입니다.🌱

0개의 댓글