본문 바로가기
JAVA SE/이론 및 개념

[20.07.17/Day_08] Java SE / Inheritance 상속

by 파프리카_ 2020. 7. 16.
728x90
반응형

[ review 복습 ]

  1. OOP(Object Oriented Program) or OOAD (Analysis and Design 분석설계)
    : 객체를 시스템의 기본단위로 상정하고,
      객체와 객체의 관계를 중심으로 분석설계하는 기법
  2. Object : 시스템의 기본 단위, 속성과 기능으로 구성
    * 속성 : attribute, variable, field 
    * 기능 : operation, method, function
  3. Class와 Object의 관계
    : Class는 붕어빵 틀(설계도), Object(instance)는 붕어빵

객체지향의 주요개념

  1. Encapsulation 
    : "public interface, private implementation"
    : 인터페이스는 공개하고, 구현부는 감춘다
  2. Inheritance (상속)
    : 부모 클래스(객체)의 멤버(속성, 기능)을 물려받아 사용
    : 장점) 1. 재사용성 증대 → 생산성 향상
                 2. 계층구조 형성을 통한 다형성(polymorphism) 적용 환경 제공

[ Inheritance 상속 ]

  1.  부모의 멤버(속성, 기능)를 자식이 물려받아 사용 
    →  재사용성 증대(생산성 향상)
  2. 계층구조 형성을 통한 다형성(polymorphism) 적용환경을 제공

부모 클래스 → super class

자식 클래스 → sub class

 

UML(통합 모델링 언어) 중 Class Diaram 상에서

상속관계는 일반화 generalization (is a relationship)로 표현한다.

 

참고)

- association 연관 (use a)

- aggregation 집합 (has a)

- composition 구성 (consist of)

- generalization 상속 (is a)

 

상속을 다이어그램으로 표현한 예

부모 클래스 (super class) : Employee

자식 클래스 (sub class) : Secretary / Manager / Engineer

* 부모클래스의 attribute 변수 : empNo, name, salary

     - 접근제어자 : # (protected) /  같은 클래스 내 접근만 가능하나, 상속인 경우에는 접근가능하다.

      * private의 경우 상속은 가능하나, 접근이 불가하기에 settet/getter가 필요하다.

* 각 자식 클래스의 attribute 변수 : nameOfBoss , department, skill

     - 접근제어자 : - (private)  /보안을 위해 private으로 지정하였다.

 

접근 제어자(Access Modifier)

public > protected > default > private

 

public : 어디서나 접근 가능

protected : 동일한 패키지 내에서 접근 가능하나, 상속 관계시에는 어디서나 접근 가능

default : 동일한 패키지 내에서만 접근 가능

private: : 동일한 클래스 내에서만 접근 가능 (다른 클래스에서 접근하려면, getter/setter를 이용하여  접근하여야 한다)

 

 

 extends 

: 부모 Class or Object를 확장하여 자식 Class or Object에 정의한다.

: 확장을 위한 java keyword이기 때문에 extends class는 특정 기능을 추가하고 싶을때에만 사용한다.

class Dog extends Animal {}

Dog : 자식 class (sub class)
extends : 부모 class를 자식 class에 상속해주는 java keyword
Animal : 부모 class (super class)

 

extends 사용 예시

class Animal{
	int age = 100;
	public void eat() {
		System.out.println("먹다");
	}
}
//Animal을 상속받아보자
class Person extends Animal{
	// 부모 Animal에 없는 기능을 자식 class에 구현할 수 있다
	public void study() {
		System.out.println(("사람이 공부하다"));
	}
}

public class TestInheritance1 {
	public static void main(String[] args) {
		// 자식 Person 객체를 생성
		Person p = new Person();
		p.eat(); //상속받았으므로 사용가능
		System.out.println(p.age); //상속받았으므로 사용가능
		p.study(); //자신의 메서드 당연히 사용가능
	}
}

 

 

 super ()

 : 자식 클래스(sub class)의 생성자 안에 들어가게 된다. (java keyword 중 하나이다.)

     - 생성자의 첫라인에 명시되는 코드

     - 별도로 super(); 키워드를 명시하지 않으면, 자동삽입이 default이다.

 : 부모 생성자(super class)를 호출해서, 부모객체를 실행하는 역할을 한다.

* this : 현재 객체를 호출하는 키워드

* super : 부모 객체를 호출하는 키워드

* super() : 부모 생성자를 호출하여 부모 객체를 생성

 

class A {

    A() { super();}

class B extends A {
    public int a;
    public Sting b;

    B(int a, String b) {
        super();
        this.a = a;
        this.b = b;
   
}

}

class  C extends B {
    C(int a, String b) {
        super(a, b);
    }
}

다른 main이 있는 실행 클래스에서 new B()를 실행하면,

B 객체에 앞서 A 객체 생성 B 객체 생성된다.

 

** 별도로 super(); 키워드를 명시하지 않으면, 자동삽입이 default이다.

** 만약 부모 생성자(super class의 constructor)에 매개변수가 있다면,

super() 키워드 내에 부모 생성자의 매개변수를 입력해주어야 한다.

 

 super 사용 예시 1

//super class
class Animal {
	Animal(){
		System.out.println("Animal 객체 생성");
	}
	public void eat() {
		System.out.println("먹다");
	}
}

//sub class
class Person extends Animal {
	// 생성자(constuctor) 명시
	Person() { 
		super(); //없으면 컴파일시에 자동 삽임
		//super()는 부모 생성자를 실행해서 부모객체를 실행하는 역할
		System.out.println("Person class의 객체 생성");
	}
}

// 실행 class
public class TestSuper {
	public static void main(String[] args) {
 	   	// 객체 생성 (-> 생성자실행)
		new Person();
		/* 출력값 
        	* Animal 객체 생성
		* Person class의 객체 생성
		*/
	}
}

 

super 사용 예시 2

// GrandParent class : super class
class GrandParent{
	public GrandParent() {
    		//super(); //여기에도 숨어있다.
		System.out.println("조부모 객체 생성");
	}
}

// Parent class : GrandParent의 sub class / Child의 super class
// GrandParent -> Parent 상속
class Parent extends GrandParent{
	public Parent() {
    		super(); // 자동생성됨(생략가능)
		System.out.println("부모 객체 생성");
	}
}

// Child class : Parent의 sub class
// Parent -> child 상속
class Child extends Parent{
	public Child() {
    		//super();
		System.out.println("자식 객체 생성");
	}
}

// 실행 class
public class TestSuper2 {
	public static void main(String[] args) {
		new Child();
        	/* 출력값
                * 조부모 객체 생성
                * 부모 객체 생성
                * 자식 객체 생성
                */
	}
}

 

super 사용 예시 3

// super class
class Animal{
	int age;
	Animal(int age){
		this.age = age;
	}
}

// sub class
class Person extends Animal{
	String name;
	Person(String name, int age){
		//super();
		/* error 
		 * : super는 즉 Animal의 생성자이기 때문에, 
		 * (sub class내의 super()는 super class의 생성자이다)
		 * 생성자 생성 시 필수 요소인 
		 * 매개변수 int age를 넣어야한다.
		 */
		super(age); 
		/*
		 * 이 경우에는 super();로 자동생성 되기때문에, 
		 * 부모 클래스 생성자의 매개변수를 넣은 
		 * super(매개변수); 를 반드시 넣어줘야 한다.
		 */
		this.name = name;
	}
}

// 실행 class
public class TestSuper3 {
	public static void main(String[] args) {
		Person p = new Person("아이유", 28);
		System.out.println(p.name+" "+p.age);
	}
}

 

 

 

 Method Overriding(메서드 오버라이딩) 

 : 부모 메서드를 자식에 맞게 구현부를 재정의하는 기법 

 

*사용하는 이유? 

 : User Interface 사용자의 편의성을 증대하기 위해 사용한다. *사용자(client code까지 포함)

 : 동일한 메서드명(=사용법이 동일하다/호출방법이 같으므로)

 

* 오버로딩 overloading과의 차이점

: method overloading 이란 ? 동일한 이름의 메서드를 매개변수를 다양하게 하여 여러 개 정의하는 기법

                                                            * 매개변수의 다양성 => 다양한 정보를 처리 가능 

: method overriding은?  상속받은 부모 메서드를 자신에 맞게 재정의

                                                  * 부모 메서드의 구현부 재정의

                                                  * 메서드명, 리턴타입은 부모, 자식 동일 / 접근제어자는 좁아지면 안됨(부모 public, 자식 private 불가)

 

 

method overriding 사용 예제

// super class
class Animal{
	public void eat() {
		System.out.println("먹다");
	}
}

// sub class 1
class Person extends Animal{
	Person() {super();} // 생성자는 생략 가능하다.
	// 메서드 오버라이딩 : 부모 메서드를 자신에 맞게 재정의
	public void eat() {
		System.out.println("수저를 이용");
		super.eat(); // 부모 메서드를 이용
	}
}

// sub class 2
class Dog extends Animal{
}


// 실행 class
public class TestOverriding {
	public static void main(String[] args) {
		System.out.println("**Person 실행**");
		Person p = new Person();
		p.eat();
		System.out.println("\n**Dog 실행**");
		Dog d = new Dog();
		d.eat();
		/* 출력 :
		 * **Person 실행**
		 * 수저를 이용
		 * 먹다
		 * **Dog 실행**
		 * 먹다
		 */
	}
}

 

 

 

 java.lang 라이브러리  

 

java.lang.Object

: java 클래스의 최상위 클래스 (java 계층구조의 root)

> 특정한 클래스를 상속받지 않으면, 자동으로 extends Object를 통해 Object 클래스를 상속받게 된다.

   즉, 모든 자바 클래스(객체)는 Object의 자식이 된다.

       * 모든 자바 클래스(객체)는 Object의 기능을 가지게 된다.

 

**

java.lang 라이브러리(패키지)는 자동으로 실행이 되기 때문에,

java.lang.Object는 Object만 적어도 진행이 된다. (String 또한 java.lang안에 포함된 것이다.)

 

 

[ java.lang.Object의 메서드들 ]

  • getclass() 
    > 어느 class로부터 가져온 객체인지 확인
  • toString() 
    > 기본 기능 : 객체의 주소값을 반환해줌
    > 주기능 : 자식 class에서 toString() 메서드를 오버라이딩해서 사용
                       * 실제값(객체의 속성정보)을 반환하도록 재정의해서 사용한다.

java.lang 사용 예제 1 ( getclass() )

// super class
class Parent { // extends Object
	Parent() {
		super(); // 생략가능=자동생성 (생성자 매개변수가 없으면)
		System.out.println("Parent 객체 생성");
	}
}

// sub class
class Child extends Parent {
	Child() { // 생략가능=자동생성
		super(); // 생략가능=자동생성 (생성자 매개변수가 없으면)
		System.out.println("Child 객체 생성");
	}
}

class Car {
}

// 실행 class
public class TestObjectClass {
	public static void main(String[] args) {
		Child c = new Child(); 
		/* 출력값 :
		 * Parent 객체 생성
		 * Child 객체 생성
		 */
		
		// getClass(): 어느 class로부터 가져온 객체인지 확인
		System.out.println(c.getClass());
		/* 출력값 :
		 * class step1.Child
		 */
		
		Car car = new Car();
		System.out.println(car.getClass());
		/* 출력값 :
		 * class step1.Car
		 */
	}
}

 

java.lang 사용 예제 2 ( toString() )

class Employee{
	public String empId;
	public String name;
	
	public Employee(String empId, String name) {
		super(); //Object class의 기능 호출
		this.empId = empId;
		this.name = name;
	}
    
	// toString()의 기능을 실제값(객체의 속성정보)을 반환하도록 재정의해준다.
	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", name=" + name + "]";
	}
	
	
}

// 실행 class
public class TestToString2 {
	public static void main(String[] args) {
		Employee e = new Employee("200", "마우스");
        
		// Employee 에서 toStrng()을 오버라이딩 했으므로,
		// 오버라이딩한 자신의 메서드가 호출된다.
		System.out.println(e); //println()메서드가 내부적으로 toString()을 호출
		System.out.println(e.toString());
		// 위 두 라인은 동일한 결과를 출력
		/* 출력값:
		 * Employee [empId=200, name=마우스]
		 * Employee [empId=200, name=마우스]
		 */
	}
}

 

 

* 참고 링크 )

https://docs.oracle.com/javase/8/docs/api/

 

 


▶ super 사용 예시 3의 실행 순서

  1. 처음에 실행 class의 main method로 가게 됨
  2. person p = new Person() 명령을 통해,
    > Heap 메모리 영역에 Person과 Animal이 저장된다. 
    *사실은 Object → Animal → Person순으로 저장된다. (Heap영역에 제일 먼저 생성되는 것은 Object이다)
    > person p  객체에 new Person의 Heap 메모리에 저장된 것의 주소를 Stack 메모리에 저장하게 됨.
  3. Person class로 가게 됨.  
  4. super()를 통해 부모 클래스(Parent)의 생성자에 가서, 부모 객체를 호출하게됨 
  5.  Parent의 super를 통해 Animal class의 부모 생성자를 찾게 됨. 그러나 별도의 상속관계 표현이 없기 때문에 자동으로  상속관계를 준다. 
  6.  Animal class는 Object class를 상속한 것이다. (class Animal = class Parent extends Object)
    * 모든 java의 class는 Object class를 상속받은 것이다.

    * Object class는 최상위 클래스이다.

 

 

 

728x90
반응형