simDev1234
심플하고 차분하게
simDev1234
전체 방문자
오늘
어제
  • 분류 전체보기
    • Computer Science
      • Basic Math
      • Data Structure
      • Algorithm
      • Database
      • OS
    • Language
      • Java
      • Kotlin
      • SQL
    • Framework
      • Spring
      • Orm&Mapper
      • 프로젝트로 스프링 이해하기
      • 스프링 라이브러리
    • Infra
      • Cloud
      • Docker
      • Redis
      • AWS, Azure
      • Device
    • Etc
      • CleanCoding
    • Git,Github

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 참조변수
  • null
  • JVM메모리구조
  • 404
  • 스프링
  • 자바메모리구조
  • 참조타입
  • 자바프로그래밍
  • 자바
  • scanner #next() #nextLine()
  • 자바프로그램
  • controllerTest
  • 컨트롤러

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
simDev1234
Language/Java

객체지향 언어의 특징 2_상속 (재사용 + 확장)

객체지향 언어의 특징 2_상속 (재사용 + 확장)
Language/Java

객체지향 언어의 특징 2_상속 (재사용 + 확장)

2022. 7. 20. 17:00

|  상속 (재사용 + 확장)

- 부모 - 자손의 상속 관점 보다는, 재사용과 확장으로 접근하는 것이 좋다

- 상속은, 상위 클래스의 특성을 하위 클래스에서 재사용하고, 거기에 덧붙여 확장할 수 있는 것을 말한다.

- 관계 : 상위 - 하위 / 슈퍼 - 서브

   * 상위로 갈수록 추상화, 일반화되며

   * 하위로 갈수록 구체화, 특수화된다. 

- 상속을 표현하는 문장 

구분 - 설명
포함 has a 클래스 내에서 인스턴스를 형성하여 사용
상속 is a kind of 클래스를 extends (확장하다)
구현 is able to 인터페이스를 implements (구현하다)

- 오버라이딩 : 상속 관계에 있는 상위 클래스로부터 물려 받은 메소드를 재정의한 것

 

|  상속의 장단점

장점 - 모듈화*를 통한 재사용
- 유지보수가 쉽고, 개발 시간이 단축된다.
- 코드가 통일성이 있고 간결해진다.
단점 - 상속 시 기능을 추가하고 변경할 때 버그가 발생하면 전반적인 검토가 불가피하다.
- 불필요한 기능까지 상속해야하는 경우가 있다. (특히 인터페이스의 경우)
- 상위 클래스의 구현이 하위 클래스에게 노출될 경우 캡슐화 원칙을 위반할 수 있다.
  ==> 강한 결합도 발생 

* 모듈화 : 소프트웨어를 각 기능별로 나눈 단위. 여기에서는 객체화로 보아도 무방하다.

 

|  결합도와 응집도

- 상속에 대한 이야기를 할 때 자주 나오는 이야기가 결합도와 응집도인 것 같다.

- 결합도와 응집도란 그럼 뭘까?

결합도 응집도
서로 다른 모듈 간에 상호 의존하는 정도 또는 연관된 관계 한 모듈 내부의 처리 요소들이 서로 연관되어 있는 정도
A - B 간에 결합도가 높을 경우,
- A를 변경하면,  B도 변경해야 한다.
- A를 변경한 후, B를 다른 코드에서 재사용하기 어렵다
A안에 a1, a2, a3 메소드들이 있다고 할 때,
각 메소드들이 A안에서 책임이 잘 뭉쳐져 있어
A가 독립적인 모듈로써 기능할 때 응집도가 높다고 한다.

 

- 상속에서는 여러 개의 하위 모듈이 하나의 상위 객체로부터 공통의 메소드를 사용하거나, 참조하기 때문에 지나치게 결합도가 높은 경우에는 차후에 수정을 할 때에 어려움이 발생할 수 있다. 

- 또한 상위 객체에서 접근제어자와 겟터(getter)/셋터(setter) 등으로 정보에 대한 접근을 제한하지 않았다면, 캡슐화(정보은닉)의 원칙도 깨어질 우려가 있다. 잘못하면 상속 후 하위 객체에서 상위 객체의 데이터에 접근을 할 수 있기 때문이다.

- 따라서, 상속 시 사전에 결합도와 응집도를 충분히 고려하는 게 필요하다.

 

|  상속시 메모리구조

- new 객체명() 를 통해 인스턴스를 생성할 때, 상속을 받은 경우, '나' 뿐만 아니라 '상위' 인스턴스도 함께 힙에 생성된다.

Static : 클래스 정보
Stack :
main() -> 하위 생성자 호출
Heap : 
하위 인스턴스, 상위 인스턴스

 

|  UML 표현 (출처 : https://gmlwjd9405.github.io)

(1) Logical

출처:https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

(2) Physical

출처:https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

 

|  상속을 표현한 코드

 

동물은 이름(name)과 나이(age)가 있으며, 자신을 소개(introduce)할 수 있다.

 

 '포유류'는 동물이다. (상속)

- Mammal is a kind of Animal.

 

포유류는 다른 동물처럼 이름과 나이가 있고, 자신을 소개할 수 있다.

포유류의 포유류의 평균 최대 수명(MAX_AGE)을 갖고 있다.

 

포유류는 자신을 소개할 때, 포유류의 평균 최대 수명을 함께 소개한다.

 

package inheritance;

// 동물
public class Animal {
    String name;
    int age;

    Animal () {}

    Animal (String name, int age) {
        this.name = name;
        this.age = age;
    }

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
    }
}

// 포유류 
class Mammal extends Animal{
    final int MAX_AGE = 268;

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
        System.out.println("I can only live MAX : " + MAX_AGE);
    }
}

// 파충류
class Reptile extends Animal{
    final int MAX_AGE = 20;

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
        System.out.println("I can only live MAX : " + MAX_AGE);
    }
}

 

|  또다른 예시 코드

package inheritance;

class Vehicle {
	
	String name;
	double maxSpeed; 
	int maxCapacity;
	
	public Vehicle() {}
	
	public Vehicle(double maxSpeed, int maxCapacity) {
		super();
		this.maxSpeed = maxSpeed;
		this.maxCapacity = maxCapacity;
	}


	public void info() {
		System.out.println("== vehicle info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
	}
}

class Car extends Vehicle{
	
	final String name = "car";
	int gasDisplacement; // 배기량
	
	public Car() {}
	
	public Car(int gasDisplacement) {
		super(430,100);
		this.gasDisplacement = gasDisplacement;
	}

	public void info() {
		System.out.println("== Car info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("gasDisplacement : " + gasDisplacement);
	}
}

class Train extends Vehicle{
	
	final String name = "train";
	final static String[] ALL_LINES = {"경부선", "호남선", "전라선", 
                                           "중앙선", "경의선", "경의선"}; // 나머지 생략  
	String line; // 노선
	
	public Train() {}
	
	public Train(String line) {
		super(330, 1000);
		this.line = line;
	}

	public void info() {
		System.out.println("== Train info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("line : " + line);
	}
}

class Airplane extends Vehicle{
	
	final String name = "airplane";
	String departure;
	String arrival;
	
	public Airplane() {}
	
	public Airplane(String departure, String arrival) {
		super(1000, 200);
		this.departure = departure;
		this.arrival = arrival;
	}

	public void info() {
		System.out.println("== vehicle info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("departure : " + departure);
		System.out.println("arrival : " + arrival);
	}
}

-- 테스트 코드

package inheritance;

public class Test {
	public static void main(String[] args) {
		Car car = new Car(1000);
		car.info();
		System.out.println();
		
		Train train = new Train(Train.ALL_LINES[1]);
		train.info();
		System.out.println();
		
		Airplane air = new Airplane("Seoul", "Reykjavik");
		air.info();
		System.out.println();
	}
}
== Car info ==
name : car
maxSpeed : 430.0
maxCapacity : 100
gasDisplacement : 1000

== Train info ==
name : train
maxSpeed : 330.0
maxCapacity : 1000
line : 호남선

== vehicle info ==
name : airplane
maxSpeed : 1000.0
maxCapacity : 200
departure : Seoul
arrival : Reykjavik

 

[참조]

스프링 입문을 위한 자바 객체 지향의 원리와 이해

https://madplay.github.io/post/coupling-and-cohesion-in-software-engineering

https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

https://sujl95.tistory.com/32

 

 

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

객체지향 언어의 특징 4_캡슐화 (정보 은닉)  (0) 2022.07.22
객체지향 언어의 특징 3_다형성 (사용 편의성)  (0) 2022.07.22
객체지향 언어의 특징 1_추상화 (모델링)  (0) 2022.07.20
객체지향 프로그래밍이란?  (0) 2022.07.18
자바 설치부터 제어문까지 기본 핵심 복습  (0) 2022.07.05
  • |  상속 (재사용 + 확장)
  • |  상속의 장단점
  • |  결합도와 응집도
  •  
  • |  상속시 메모리구조
  • |  UML 표현 (출처 : https://gmlwjd9405.github.io)
  • |  상속을 표현한 코드
  • |  또다른 예시 코드
'Language/Java' 카테고리의 다른 글
  • 객체지향 언어의 특징 4_캡슐화 (정보 은닉)
  • 객체지향 언어의 특징 3_다형성 (사용 편의성)
  • 객체지향 언어의 특징 1_추상화 (모델링)
  • 객체지향 프로그래밍이란?
simDev1234
simDev1234
TIL용 블로그. * 저작권 이슈가 있는 부분이 있다면 댓글 부탁드립니다.

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.