[JAVA] JAVA 기초 | 상속(extends), 추상 클래스 (abstract), Getter / Setter

2025. 8. 6. 18:15·✏️공부/💡JAVA
728x90
반응형
더보기

노션 페이지

 

JAVA 기초 | Notion

[Day] 08.06 [Chapter] ~ 49강

www.notion.so

 

[Day] 08.06
[Chapter] ~ 49강


📌 상속(extends) 중복

로봇 오리
날다() : 오리 클래스
수영() : 고무오리 클래스

public class Main {
    public static void main(String[] args) {

        청둥오리 a청둥오리 = new 청둥오리();
        a청둥오리.날다();
        // 출력 : 오리가 날개로 날아갑니다.
        a청둥오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.

        흰오리 a흰오리 = new 흰오리();
        a흰오리.날다();
        // 출력 : 오리가 날개로 날아갑니다.
        a흰오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.

        고무오리 a고무오리 = new 고무오리();
        a고무오리.날다();
        // 출력 : 저는 날 수 없어요. ㅜㅠ
        a고무오리.수영();
        // 출력 : 오리가 둥둥 떠다닙니다.

        고무2오리 a고무2오리 = new 고무2오리();
        a고무2오리.날다();
        // 출력 : 저는 날 수 없어요. ㅜㅠ
        a고무오리.수영();
        // 출력 : 오리가 둥둥 떠다닙니다.

        로봇오리 a로봇오리 = new 로봇오리();
        a로봇오리.날다();
        // 출력 : 저는 못 날아요 ㅠㅠ
        a로봇오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.
    }
}

class 오리 {
    void 날다() {
        System.out.println("오리가 날개로 날아갑니다.");
    }

    void 수영() {
        System.out.println("오리가 오리발로 헤엄칩니다.");
    }
}

class 흰오리 extends 오리 {}

class 청둥오리 extends 오리 {}

// 메서드 재정의 라고 합니다.
// 메서드 오버라이드 라고도 합니다.
// 메서드 재정의 => 부모가 물려준 능력을 다시 구현한다.
class 고무오리 extends 오리 {
    void 날다() {
        System.out.println("저는 못 날아요 ㅠㅠ");
    }

    void 수영() {
        System.out.println("오리가 둥둥 떠다닙니다.");
    }
}

class 고무2오리 extends 고무오리 {}

// 수영 메서드를 오버라이드 해서 해결할 수 있지만 코드가 중복됨.
// 상속으로는 코드 중복을 완전히 해결할 수 없음.
class 로봇오리 extends 고무오리{
    void 수영(){
        System.out.println("오리가 오리발로 헤엄칩니다.~~");
    }
}

📌 문제점

  • 자바에서 다중상속 지원 ❌
  • 수영() || 날다() / 수영() && 날다() 재정의 ➡️ 중복 발생
  • 상속만으로는 중복 해결 불가 ❌

중복 제거 해결
“상속보다는 구성을 사용하라” ➡️ 객체의 협력

[ 예제 ]

class practice {
    public static void main(String[] args) {
       홍길동 a홍길동 = new 홍길동();
       a홍길동.자바개발();

       홍길순 a홍길순 = new 홍길순();
       a홍길순.자바개발();
       a홍길순.파이썬개발();

    }
}

class 홍길동 {
    int age;
    String name;

    void 자바개발() {
        System.out.println("자바 24 개발합니다.");
    }
    void C개발() {
        System.out.println("C언어 개발 합니다.");
    }
}
 //자바개발 중복 -> 홍길동 클래스의 참조값(홍길동연락처)으로 홍길동 불러서 해결
class 홍길순 {
    int age;
    String name;

    홍길동 홍길동연락처 = new 홍길동();

    void 자바개발() {
        홍길동연락처.자바개발();
    }
    void 파이썬개발(){
        System.out.println("파이썬 개발 합니다.");
    }
}

✅ 홍길동 클래스의 참조값(홍길동연락처)으로 홍길동 불러서 해결

  • 홍길동 객체 생성하여 해결

Q. 객체 생성 이후 다시 사용안할 것 같은데 자동 제거 되나?

A. 객체 무쓸모 -> 자바내부 Gc(가비지컬렉터)가 수거

판단 기준: 참조값이 연결되어 있는지 여부 확인 ➡️ 연결 안되어 있으면 자동 제거

 


[ 문제7️⃣ 중복 제거 해결 ]

구성 방식 사용

public class Main {
    public static void main(String[] args) {

        청둥오리 a청둥오리 = new 청둥오리();
        a청둥오리.날다();
        // 출력 : 오리가 날개로 날아갑니다.
        a청둥오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.

        흰오리 a흰오리 = new 흰오리();
        a흰오리.날다();
        // 출력 : 오리가 날개로 날아갑니다.
        a흰오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.

        고무오리 a고무오리 = new 고무오리();
        a고무오리.날다();
        // 출력 : 저는 날 수 없어요. ㅜㅠ
        a고무오리.수영();
        // 출력 : 오리가 둥둥 떠다닙니다.

        고무2오리 a고무2오리 = new 고무2오리();
        a고무2오리.날다();
        // 출력 : 저는 날 수 없어요. ㅜㅠ
        a고무오리.수영();
        // 출력 : 오리가 둥둥 떠다닙니다.

        로봇오리 a로봇오리 = new 로봇오리();
        a로봇오리.날다();
        // 출력 : 저는 못 날아요 ㅠㅠ
        a로봇오리.수영();
        // 출력 : 오리가 오리발로 헤엄칩니다.
    }
}

//<---구성 방식 사용--->
class 오리날개 {
    void 사용() {
        System.out.println("오리가 날개로 날아갑니다.");
    }
}

class 고무날개 {
    void 사용() {
        System.out.println("저는 날 수 없어요. ㅜㅠ");
    }
}

class 오리발 {
    void 사용() {
        System.out.println("오리가 오리발로 헤엄칩니다.");
    }
}

class 고무발 {
    void 사용() {
        System.out.println("오리가 둥둥 떠다닙니다.");
    }
}
//<----구성방식 사용--->

class 오리 {

    오리날개 a오리날개 = new 오리날개();
    오리발 a오리발 = new 오리발();

    void 날다() {
        a오리날개.사용();
    }

    void 수영() {
        a오리발.사용();
    }
}

class 흰오리 extends 오리 {
}

class 청둥오리 extends 오리 {}

class 고무오리 extends 오리 {

    고무날개 a날개 = new 고무날개();
    고무발 a발 = new 고무발();

    void 날다() {
        a날개.사용();
    }

    void 수영() {
        a발.사용();
    }
}

class 고무2오리 extends 고무오리 {}

class 로봇오리 extends 고무오리 {

    고무날개 a날개 = new 고무날개();
    오리발 a발 = new 오리발();

    void 날다() {
        a날개.사용();
    }

    void 수영() {
        a발.사용();
    }
}

📌 상속(extends) 자동 형변환

자바개발자 a = new 홍길동();
➡️ 자바개발자 ≠ 홍길동으로 타입이 다름

public class practice {
    public static void main(String[] args) {

        홍주식회사 a홍주식회사 = new 홍주식회사();

        a홍주식회사.자바개발();
        a홍주식회사.파이썬개발();

    }
}

class 홍주식회사 {
    자바개발자 a자바개발자 = new 이순신(); // 자바개발자 != 이순신, 자동 형변환
    홍길순 a홍길순 = new 홍길순();

    void 자바개발() {
        a자바개발자.자바개발();
    }

    void 파이썬개발() {
        a홍길순.파이썬개발();
    }
}

class 자바개발자 {
    void 자바개발() {
        System.out.println("자바 개발을 합니다.");
    }
}

class 이순신 extends 자바개발자 {

    void 자바개발() {
        System.out.println("자바 개발을 합니다.");
    }
}

class 홍길동 extends 자바개발자 {
    int age;
    String name;

    void 자바개발() {
        System.out.println("자바 25 개발을 합니다.");
    }

    void C언어개발() {
        System.out.println("C언어 개발을 합니다.");
    }
}

class 홍길순 {
    int age;
    String name;

    홍길동 홍길동연락처 = new 홍길동();

    void 자바개발() {
        홍길동연락처.자바개발();
    }

    void 파이썬개발() {
        System.out.println("파이썬 개발을 합니다.");
    }
}

✅ 홍길동이 자바개발자를 상속받으면 가능 (이순신도 마찬가지)

  • 자동 형변환
    • 객체의 형변환은 상속을 통해서 이루어짐
    • 하위 타입이 상위 타입으로 갈 때 안전

[ 예제 ]

상속 관계에서는 자식 타입이 부모 타입으로 자동 형변환

public class Main {
    public static void main(String[] args) {

        무기 a무기 = new 칼(); //무기 클래스로부터 칼 클래스 생성
        // 출력 : 칼로 공격합니다.

        a무기 = new 활();  //무기 클래스로부터 활 클래스 생성
        a무기.공격();
        // 출력 : 활로 공격합니다.

    }
}

//정답
class 무기 {
    void 공격(){};
}

class 칼 extends 무기 {
    void 공격() {  //오버라이딩
        System.out.println("칼로 공격합니다.");
    }
}

class 활 extends 무기 {
    void 공격() {  //오버라이딩
        System.out.println("활로 공격합니다.");
    }
}

📌 아쉬운 점

  • 칼 클래스 & 활 클래스 ➡️ 공격 메서드 재정의 (오버라이딩)
  • 무기 클래스의 공격 메서드를 사용하지 ❌

✅
무기 클래스를 추상 클래스로,
공격 메서드를 추상 메서드로 변경

 


📌 추상 클래스(abstract)

추상 메서드를 가지는 클래스 ➡️ 객체화 불가능

추상 메서드 ➡️ 구현이 없는 메서드 (버튼 역할)

public class Main {
    public static void main(String[] args) {

        무기 a무기 = new 칼();
        a무기.공격();
        // 출력 : 칼로 공격합니다.

        a무기 = new 활();
        a무기.공격();
        // 출력 : 활로 공격합니다.
    }
}
abstract class 무기 { // 추상 클래스
    abstract void 공격(); // 추상 메서드 -> 구현이 없는 메서드. 버튼 역할만 한다.
}

class 칼 extends 무기 {

    void 공격() { // 물려 받은 추상메서드는 반드시 구현해야 한다. 오버라이딩 강제
        System.out.println("칼로 공격합니다.");
    }
}

class 활 extends 무기 {
    void 공격() {
        System.out.println("활로 공격합니다.");
    }
}

✅ 물려 받은 추상 메서드는 반드시 구현 !

  • 즉, 오버라이딩 강제

📌 접근 제한자 (private)

📍적용 대상 : 필드, 생성자, 메서드
⭕️ 접근 가능 : 클래스 내부
❌ 접근 불가능 : 클래스 외부

public class Main {
    public static void main(String[] args) {

        사람 a사람 = new 사람();

        a사람.나이세팅(10);
        a사람.이름세팅("홍길동");

        a사람.자기소개();

    }
}

class 사람 {
    private int 나이; //보호
    private String 이름; //보호

    public void 자기소개() {
        System.out.println("안녕하세요, 제 이름은 " + 이름 + "이고, 나이는 " + 나이 + "살입니다.");
    }

    public void 나이세팅(int 입력나이) {

        if(입력나이 < 0) {
            System.out.println("나이는 음수가 될 수 없습니다.");
            return;
        }

        나이 = 입력나이;
    }

    public void 이름세팅(String 입력이름) {
        이름 = 입력이름;
    }
}

✅ 객체의 올바른 작동 보장하기 위해 private으로 객체의 데이터 보호


📌 getter / setter

자바 ➡️ 기본적으로 인스턴스 변수를 private으로 보호하고 getter / setter 를 사용하는 것이 관례

✅ Getter : 내부의 멤버변수에 저장된 값을 외부로 리턴
✅ Setter : 외부로부터 데이터를 전달받아 멤버변수에 저장

public class Main {
    public static void main(String[] args) {

        사람 a사람 = new 사람();

    }
}

class 사람 {
    private int 나이;
    private String 이름;
    private String 거주지;

    public void 자기소개() {
        System.out.println("안녕하세요, 제 이름은 " + 이름 + "이고, 나이는 " + 나이 + "살입니다.");
    }

    // 단축키 cmd + n
    // 게터/세터 자동 생성 가능
    public int get나이() {
        return 나이;
    }

    public void set나이(int 나이) {
        this.나이 = 나이;
    }

    public String get이름() {
        return 이름;
    }

    public void set이름(String 이름) {
        this.이름 = 이름;
    }

    public String get거주지() {
        return 거주지;
    }

    public void set거주지(String 거주지) {
        this.거주지 = 거주지;
    }
}
public class Main {
    public static void main(String[] args) {

        사람 a사람 =new 사람(20, "홍길동", "서울");
        a사람.자기소개();

//        사람 a사람 = new 사람();
//        a사람.set나이(20);
//        a사람.set이름("홍길동");
//        a사람.set거주지("서울");
//
//
//        a사람.자기소개();

    }
}

class 사람 {
    private int 나이;
    private String 이름;
    private String 거주지;

    public void 자기소개() {
        System.out.println("안녕하세요, 제 이름은 " + 이름 + "이고, 나이는 " + 나이 + "살입니다.");
    }

    // 생성자 -> class 이름과 동일, 리턴 X
    // 올바른 객체 동작을 위한 객체 값 초기화 및 초기 세팅
    사람(int 나이, String 이름, String 거주지) {
        this.나이 = 나이;
        this.이름 = 이름;
        this.거주지 = 거주지;
    }

    // 단축키 cmd + n
    // 게터/세터 자동 생성 가능
    public int get나이() {
        return 나이;
    }

    public void set나이(int 나이) {
        this.나이 = 나이;
    }

    public String get이름() {
        return 이름;
    }

    public void set이름(String 이름) {
        this.이름 = 이름;
    }

    public String get거주지() {
        return 거주지;
    }

    public void set거주지(String 거주지) {
        this.거주지 = 거주지;
    }
}
728x90
반응형

'✏️공부 > 💡JAVA' 카테고리의 다른 글

[JAVA] Java Stream | mapToInt() 활용한 연산, finFirst(), isPresent(), orElseThrow(), Optional<>  (4) 2025.08.07
[JAVA] JAVA Stream | 명령형, 선언형, filter, map, stream, foreach, toArray, toList | 예제 ⭕️  (3) 2025.08.06
[JAVA] JAVA 기초 | static, 상속 (extends) | 예제 문제 ⭕️  (4) 2025.08.05
[JAVA] JAVA 기초 | 배열, 리스트(ArrayList<>) , 맵(Map<>), 제네릭  (3) 2025.08.04
[JAVA] JAVA 기초 | 클래스, 함수, 전역변수 vs 인스턴스 변수  (0) 2025.08.01
'✏️공부/💡JAVA' 카테고리의 다른 글
  • [JAVA] Java Stream | mapToInt() 활용한 연산, finFirst(), isPresent(), orElseThrow(), Optional<>
  • [JAVA] JAVA Stream | 명령형, 선언형, filter, map, stream, foreach, toArray, toList | 예제 ⭕️
  • [JAVA] JAVA 기초 | static, 상속 (extends) | 예제 문제 ⭕️
  • [JAVA] JAVA 기초 | 배열, 리스트(ArrayList<>) , 맵(Map<>), 제네릭
망꼬누나
망꼬누나
공부한 내용을 정리하는 공간입니다.
  • 망꼬누나
    망꼬누나의 개발 공부
    망꼬누나
  • 전체
    오늘
    어제
    • 분류 전체보기 (165)
      • ℹ️ 정보 및 실습 (19)
        • ☑️ Git & GitHub (8)
        • ☑️ 프로젝트 (6)
        • ☑️ 회고 및 후기 (5)
      • 🛠 CS (1)
      • 💻코딩 (88)
        • 💡Baekjoon (17)
        • 💡Programmers (71)
      • ✏️공부 (48)
        • 💡OS (1)
        • 💡Network (6)
        • 💡SpringBoot (9)
        • 💡JAVA (21)
        • 💡SQL (1)
        • 💡DB (2)
        • ☁️ Cloud (4)
        • 💡알고리즘 (4)
      • 📌 자격증 (6)
        • 📝정보처리기사 (3)
        • 📝SQLD (3)
  • 블로그 메뉴

    • 홈
    • github
  • 나의 GitHub Contribution 그래프
    Loading data ...
  • 인기 글

  • 태그

    프로그래머스
    코딩테스트
    자료구조
    데브코스
    AWS
    GIT
    네트워크
    트랜잭션
    Stream
    프로그래머스 #JAVA
    자바
    Set
    baekjoon
    map
    알고리즘
    S3
    백엔드
    동시성제어
    Java
    github
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.5
망꼬누나
[JAVA] JAVA 기초 | 상속(extends), 추상 클래스 (abstract), Getter / Setter
상단으로

티스토리툴바