[Java] 6.Object-oriented Programming_객체지향②

말랑이·2023년 7월 11일
0

JAVA

목록 보기
11/13
post-thumbnail

1 상속

💜 상속(extends) : 기존 클래스 재사용 → 새로운 클래스 작성

1️⃣ 상속의 장점

  • 보다 적은 양의 코드로 새로운 클래스 작성 ✅

  • 코드 공통적으로 관리 → 코드 추가 및 변경 용이 ✅

  • 코드 재사용성 높임 + 코드 중복 제거 ➡️ 프로그램 생산성 • 유지보수에 크게 기여 ⭐️

2️⃣ 상속 구현하기

📍 새로 작성하는 클래스 뒤 → extends + 상속받는 클래스
	
    class Parent {}
    class Child extends Parent {}
  • 서로 상속관계에 있음

  • 조상클래스 : 상속해주는 클래스

  • 자손클래스 : 상속받는 클래스

3️⃣ 상속 관계

  • 자손클래스는 조상클래스의 모든 멤버를 상속받음 (포함) ⭐️
    (생성자, 초기화블럭 상속 ⛔️)

    • ① 조상클래스 변경 → 자손클래스 영향 받음 ⭕️
    • ② 자손클래스 변경 → 조상클래스 영향 안받음 ❌
  • 자손클래스 멤버개수 >= 조상클래스 멤버개수

  • 상속 : 조상클래스를 확장(extends)하는 의미 ✅

4️⃣ Java code

📍 조상클래스
class Tv {
    // 멤버(인스턴스)변수
    boolean power;
    int channel;

    // 멤버메서드
    void power() {power = !power;}
    void channelUp() {++channel;}
    void channelDown() {--channel;}
}

📍 자손클래스
class SmartTv extends Tv {
    // 멤버(인스턴스)변수
    boolean caption;

    // 멤버메서드
    void displayCaption(String text) {
        if (caption) {
            System.out.println(text);
        }
    }
}

class Object1 {
    public static void main(String[] args) {
        // 객체생성
        SmartTv smartTv = new SmartTv();

        // 객체멤버초기화
        smartTv.channel = 10; // 조상클래스로부터 상속받은 멤버
        smartTv.channelUp(); // 조상클래스로부터 상속받은 메서드 실행
        System.out.println(smartTv.channel);

        smartTv.caption = true;
        smartTv.displayCaption("Hello, mallang!");
    }
}

2 클래스 간의 포함관계

💜 클래스 간 포함관계

  • 한 클래스의 멤버변수다른클래스의 객체를 선언해 포함하는 것
  • 상속과는 다른개념
📍 기본클래스
	
    class Circle {
    	int x; // x좌표
        int y; // y좌표
        int r; // 반지름
    }
    
    class Point {
    	int x; // x좌표
        int y; // y좌표
    }
📍 Point 클래스 재사용 → Circle 클래스 작성

	class Circle {
    	Point point = new Point();
        int r;
    }
  • 클래스에 다른클래스의 객체를 생성해 멤버로 활용하는 것 → 포함관계

  • Point 클래스객체Circle 클래스에 선언 → int x + int y 활용가능 ✅


3 클래스 간의 관계결정

클래스를 작성 시,
상속관계(조상-자손)를 맺을 것인지
포함관계(다른클래스 객체 → 멤버변수 선언)를 맺을 것인지 결정

클래스 관계구분방법
상속관계~은 ~이다 (is-a)
포함관계~은 ~을 가지고있다 (has-a)
  • SportsCar는 Car이다 → 상속관계

  • Circle은 Point를 가지고있다 → 포함관계


4 단일상속

💜 클래스 단일상속

  • Java에서는 둘 이상의 클래스로부터 상속받을 수 없음 ⛔️
  • 단일상속만 허용 ✅ (하나의 조상클래스로부터만 상속가능)

1️⃣ 다중상속 허용 단점

  • 클래스 간 관계가 매우 복잡해짐 🚨

  • 상속받은 멤버 간 이름 같은 경우 → 구별할 수 있는 방법 없음

2️⃣ 단일상속 장점

  • 클래스 간 관계가 보다 명확해짐 ⭐️

  • 코드 신뢰도 향상


5 Object 클래스

💜 Object 클래스 : 모든 클래스상속계층도의 최상위에 있는 조상클래스

1️⃣ Object 클래스 상속규칙

  • 다른 클래스로부터 상속받지않는 모든 클래스
    ➡️ 자동적으로 컴파일러가 Object 클래스 상속받게 함 ✅ (단일상속 준수)

  • 다른 클래스로부터 상속받는 클래스
    ➡️ 조상클래스를 찾아 올라가다보면 결국 마지막 최상위는 Object 클래스

2️⃣ Object 클래스 활용

  • Java 모든 클래스 → Object 클래스를 상속받음

  • Object 클래스에 정의된 멤버 → 모든 클래스에서 사용 가능 ⭐️

    • toString()
    • equals(Object o)

6 오버라이딩

💜 오버라이딩(overriding) : 조상클래스로부터 상속받은 메서드내용 → 자손클래스 자신에 맞게 변경하는 것

  • 상속받은 메서드 그대로 사용 가능하지만, 자손클래스 자신에 맞게 변경해야하는 경우가 더 많음

  • 새로운 메서드 생성 ⛔️, 오버라이딩 ✅ ➡️ 객체지향언어 제대로 활용

1️⃣ Java code

📍 조상클래스
class Point {
    // 멤버(인스턴스)변수
    int x, y;

    // 멤버메서드
    String getLocation() {
        return "x : " + x + ", y : " + y; // 2차원
    }
}

📍 자손클래스
class Point3D extends Point {
    // 자손 멤버(인스턴스)변수
    int z;

    // 메서드 오버라이딩
    String getLocation() {
        return "x : " + x + ", y : " + y + ", z : " + z; // 3차원 (자손에 맞게 변경)
    }
}

class Object2 {
    public static void main(String[] args) {
        // 객체생성
        Point3D point3D = new Point3D();

        // 객체멤버초기화
        point3D.x = 10;
        point3D.y = 20;
        point3D.z = 30;

        // 오버라이딩메서드 실행
        System.out.println(point3D.getLocation());
    }
}

2️⃣ 오버라이딩 조건

  • ① 메서드선언부 (메서드이름, 매개변수, 반환타입) → 조상메서드와 일치 ✅

    • 오버라이딩은 메서드의 내용만을 새로 작성하는 것
  • ② 접근제어자 → 조상클래스 메서드보다 좁은범위로 변경불가 ⛔️

    • public > protected > default > private
    • 조상메서드와 같거나 더 크게!
  • ③ 예외 → 조상클래스 메서드 예외보다 많이 선언불가 ⛔️

    • 조상메서드 예외 2개, 자손메서드 예외 1개 → 오버라이딩 가능
    • 조상메서드보다 작거나 같게!

3️⃣ 오버로딩과 오버라이딩 차이점

📍 오버로딩 (overloading)
	- 한 클래스 내 같은 이름의 메서드 여러개 정의하는 것
    - 생성자에 많이 활용됨
    - 매개변수 개수, type 달라야함
    - 반환 type은 관계없음
📍 오버라이딩 (overriding)
	- 상속받은 메서드의 내용을 변경하는 것
    - 메서드선언부는 조상메서드와 동일해야함

class Parent {
    void parentMethod() {}
}

class Child extends Parent {
    void parentMethod() {} // 오버라이딩

    void parentMethod(int i) {} // 오버로딩 (매개변수 type)

    void childMethod() {}

    void childMethod(int i) {} // 오버로딩 (매개변수 type)
}

7 참조변수 super

💜 참조변수 super : (자손 멤버이름 = 조상 멤버이름) → 자손클래스에서 조상클래스로부터 상속받은 멤버를 참조하는데 사용

1️⃣ 참조변수 this와 super 차이점

참조변수기능
thisclass 내에서 멤버(인스턴스)변수 자기자신을 가리킴
super자손class에서 조상class 멤버(인스턴스)변수를 가리킴

2️⃣ Java code


class Parent2 {
    // 조상클래스 -> 멤버(인스턴스)변수
    int x = 10;
}

class Child2 extends Parent2 {
    // 자손클래스 -> 멤버(인스턴스)변수
    int x = 20;

    void method() {
        System.out.println("x = " + x);
        System.out.println("this.x = " + this.x); // class내 자기자신
        System.out.println("super.x = " + super.x); // 조상class 멤버변수
    }
}

class Object3 {
    public static void main(String[] args) {
        // 객체생성
        Child2 child2 = new Child2();
        // 메서드실행
        child2.method();
    }
}

8 조상클래스 생성자 super()

💜 참조변수 super : 생성자는 상속이 되지 않으므로, 조상의 생성자를 호출하는데 사용함

1️⃣ this()와 super() 차이점

생성자기능
this()같은 class 내에서 생성자 오버로딩 → 다른 생성자를 호출함
super()조상의 생성자를 호출함

2️⃣ super() 사용이유

  • 생성자는 상속이 되지 않음

  • class 자신에 선언된 변수 → 자신의 생성자가 초기화를 책임져야 함

3️⃣ Java code

📍 this() 예시

	class Car2 {
    	// 멤버(인스턴스)변수
    	String color;
    	String gearType;
    	int door;

    	// 생성자
    	Car2(String color, String gearType, int door) {
        	this.color = color;
        	this.gearType = gearType;
        	this.door = door;
    	}

    	// 생성자호출
    	Car2() { // 위의 생성자 호출 -> 초기화
        	this("white", "auto", 4);
    	}

    	Car2(String color) { // 위의 생성자 호출 -> 초기화 (color만 따로 초기화)
        	this(color, "auto", 4);
    	}
	}
📍 super() 예시

	class Point2 {
    	// 조상클래스 -> 멤버(인스턴스)변수
    	int x, y;

    	// 생성자
    	Point2 (int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class Point3D2 extends Point2 {
        // 자손클래스 -> 멤버(인스턴스)변수
        int z;

        // 생성자
        Point3D2 (int x, int y, int z) {
            super(x, y); // 조상생성자 호출 Point2(int x, int y) {}
            this.z = z;
        }
    }

    class Object4 {
        public static void main(String[] args) {
            // 객체생성
            Point3D2 point3D2 = new Point3D2(1, 2, 3);
            System.out.println("x = " + point3D2.x + ", y = " + point3D2.y + ", z = " + point3D2.z);
        }
    }

9 패키지

💜 패키지(package) : 클래스의 묶음 → 클래스 or 인터페이스를 포함함

1️⃣ 패키지 특징

  • 서로 관련된 class → 그룹단위로 묶음 ➡️ 효율적으로 관리함

  • 같은 이름의 class라도 서로 다른 패키지에 존재가능 ✅

  • class full name : 패키지명 + 클래스명

  • 하나의 디렉토리와 같은 개념

2️⃣ 패키지 선언

📍 package 패키지명;

3️⃣ 패키지 선언규칙

  • 패키지 선언문 → 소스파일(.java) 주석 및 공백 제외, 첫번째 문장에 작성 ⭐️

  • 하나의 소스파일(.java) → 패키지 단 한번만 선언가능

  • 클래스명과 구분을 위해 소문자사용

  • 패키지 선언 ❌ → 이름없는 패키지에 자동으로 속함


10 import문

💜 import문 : 다른 패키지 class 사용 시 → 컴파일러에게 다른 소스파일에 사용된 class의 패키지에 대한 정보를 제공

  • 소스코드 작성 시, 다른 패키지 class 사용 → 패키지명이 포함된 class 이름을 사용해야함

  • import문으로 사용할 class 패키지 미리 명시 → 패키지명 생략가능 ✅

📍 import문 사용 ❌
java.util.Date today = new java.util.Date();

📍 import문 사용 ✅
import java.util.Date;

Date today = new Date(); // 패키지 생략가능

1️⃣ import문 선언

📍 import 패키지명.class;
	// 사용하는 class마다 모두 선언해야함

📍 import 패키지명.*;
	// 패키지 하위 모든 class 사용가능
    // 실행 시 성능차이 없음
  • package문import문class선언문

  • package문과 달리, import문은 여러번 선언가능

2️⃣ static import문

  • static 멤버 호출 시, 클래스이름(패키지명 + 클래스명) 생략 가능

  • static 멤버 변수 or 메서드

  • * 사용 → 하위 모든 static 멤버 사용가능

  • 메서드 괄호 () → 생략함

import static java.lang.System.out;
import static java.lang.Math.*;

class Object5 {
    public static void main(String[] args) {
        // System.out.println(Math.random());
        out.println(random());

        // System.out.println("Math.PI : " + Math.PI);
        out.println("Math.PI : " + PI);
    }
}
profile
🐰 I'm Sunyeon-Jeong, mallang

0개의 댓글