[JAVA] OOP 2 - 상속 / 캡슐화

zirryo·2022년 7월 11일
0

⚡️ STUDY

목록 보기
6/15
post-thumbnail
week 3 / 22.07.11

Inheritance

💿 상속

기존의 클래스를 재사용하여 새로운 클래스를 작성하는 문법 요소.

  • 상위 클래스의 모든 멤버(필드,메서드,이너클래스)를 하위 클래스가 상속 받음. 생성자와 초기화 블럭은 상속되지 않음.
  • extends 를 사용하여 상속을 표현함
  • 코드 재사용을 통해 적은 양의 코드로 새로운 클래스 작성이 가능하며, 코드의 중복을 제거함.
  • 다형적 표현이 가능함.
  • 자바에서는 단일 상속(single inheritance)만 허용됨.
  • 상위 클래스에 기능 추가 및 변경이 생기는 경우, 하위 클래스의 정상 작동 여부 예측이 어려움.
    class Person {
        String name;
        int age;
        void wakeup(){
            System.out.println("일어나기");
        }
    } // extends를 이용하여 person 클래스 상속
    class Student extends Person {  
        String major;
        void coding(){
            System.out.println("코딩하기");
        }
    }
    
    public class Main {
        public static void main(String[] args){
            Person p = new Person(); // person 객체 생성
            p.name = "김자바";
            p.age = 77;
            p.wakeup();
    
            Student s = new Student(); // student 객체 생성
            s.name = "박자바"; // person 에서 상속 받음
            s.coding(); // student 의 개별 기능
            s.major = "engineering" // student 의 개별 기능
            System.out.println(s.major);
        }
    }

  • 포함관계(Composite) : 클래스의 멤버로 다른 클래스 타입의 참조변수 선언.
    • 클래스 간의 관계가 ~은 ~이다 와 같은IS-A 관계일 경우 상속,
      ~를 ~가지고 있다 와 같은HAS-A 관계일 경우 포함.
    • ex) person-student 는 상속, car-wheel은 포함.

  • Object 클래스
    • 자바 클래스 최상위에 위치한 상위 클래스.
    • 자바의 모든 클래스는 Object class 로 부터 확장된다.
    • 아무런 상속도 받지 않을 경우 자동적으로 extends Object 상속.




💿 메서드 오버라이딩

Method Overriding : 상위 클래스로부터 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것.

  1. 메서드의 선언부(메서드 이름, 매개변수, 반환타입)이 상위클래스의 그것과 완전히 일치해야한다.
  2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 한다.
  3. 예외는 상위 클래스의 메서드보다 많이 선언할 수 없다.

반드시 위의 3가지 조건을 만족해야 한다.

  • 메서드 오버라이딩의 예시
    public class Main {
        public static void main(String[] args) {
            Guitar guitar = new Guitar(); // 각각의 타입으로 선언 
            guitar.play();
    
    	    Instrument piano = new Piano(); // 상위 클래스 타입으로 선언
            piano.play();
        }
    }
    class Instrument {
        void play() {
            System.out.println("This is musical instrument");
        }
    }
    class Guitar extends Instrument {
        void play() {
            System.out.println("This is guitar");
        }
    }
    class Piano extends Instrument {
        void play() {
            System.out.println("This is piano");
        }
    }

    출력
    This is guitar
    This is piano




💿 super vs super()

  • super : 상위 클래스의 객체 호출 (상속관계를 전제로 함)
    public class Main {
        public static void main(String[] args) {
            Lower l = new Lower();
            l.callNum();
        }
    }
    
    class Upper {
        int count = 20; // super.count
    }
    
    class Lower extends Upper {
        int count = 15; // this.count
    
        void callNum() {
            System.out.println("count = " + count); // 15
            System.out.println("this.count = " + this.count); // 15
            System.out.println("super.count = " + super.count); // 20
        } // super를 이용하여 부모 객체 멤버의 값 참고
    }

  • super() : 상위 클래스의 생성자 호출 (상속관계를 전제로 함)
    public class Main {
        public static void main(String[] args) {
            Art a = new Art();
        }
    }
    
    class Major {
        Major() {
            System.out.println("Major 클래스 생성자");
        }
    }
    
    class Art extends Major { // Major 클래스로부터 상속
        Art() {    
            super(); // 상위클래스의 생성자 호출
            System.out.println("Art 클래스 생성자");
        }
    }

    출력값
    Major 클래스 생성자
    Art 클래스 생성자

    생성자 내부에서만 사용 가능하고, 반드시 첫 줄에 작성해야 함.
    모든 생성자의 첫 줄에는 반드시 this() 또는 super()를 선언해야 함.
    없는 경우 컴파일러가 자동 생성.
    상위 클래스에 기본 생성자가 없을 경우 에러가 발생.




Encapsulation

📀 캡슐화

특정 객체 안에 관련된 속성과 기능을 하나의 캡슐로 만들어 데이터를 외부로 부터 보호
목적 : 데이터 보호 / 내부적으로만 사용되는 데이터의 불필요한 외부 노출 방지


  • 패키지(Package)
    • 특정한 목적을 공유하는 클래스와 인터페이스 묶음
    • 클래스들을 그룹 단위로 묶어 효과적으로 관리함.
    • 자바에서 패키지는 하나의 디렉토리(directory)이다.
    • 코드 첫 줄에 package 패키지명으로 선언, 하지 않을 경우 이름없는 패키지에 속하게 됨.
    • 클래스의 충돌을 방지하는 역할을 함.(같은 이름의 클래스이더라도 패키지가 다르다면 충돌하지 않음)

  • Import
    • 다른 패키지 내의 클래스를 사용하기 위해 사용됨. 패키지 구문과 클래스문 사이에 선언.
    • import 뒤에 패키지명과 패키지명을 생략하고자 하는 클래스명을 작성하며, 한 패키지에서 여러 클래스를 참조할 경우 클래스명 대신 * 으로 작성하면 됨.
      import 패키지명.클래스명;  or  import 패키지명.*;

  • 접근 제어자(Access Modifier)
    • 제어자 : 클래스, 필드, 생성자에 부가적인 의미를 부여하는 키워드
    • 접근 제어자와 기타 제어자로 분류되며, 하나의 대상에 여러 제어자를 사용할 수 있으나 접근 제어자는 단 한번만 사용 가능.
    • 접근 제어자는 클래스 외부로의 불필요한 데이터 노출 방지, 외부로부터 데이터가 임의로 변경되지 않도록 보호하는 역할을 함.
      1. private : 동일 클래스에서만 접근 가능
      2. default : 동일 패키지 내에서만 접근 가능
      3. protected : 동일패키지 + 타 패키지 하위 클래스(==상속받은 클래스)에서 접근 가능
      4. public : 접근 제한 없음




📀 getter & setter

private을 통해 외부로부터의 데이터 접근을 차단한 변수를
set methodget method를 통해 데이터를 저장, 수정, 출력.

  • getter
    외부에서 객체의 데이터를 읽을 때 메소드를 사용함.
    객체 외부에서 객체의 필드 값을 사용하기 부적절한 경우, Getter 메소드로 필드값을 가공한 후 외부로 전달.
    private int price;
    
    int getPrice() {
    	return price;
    }

  • setter
    메소드의 매개값을 검증하여 유효한 값만 데이터로 저장.
    데이터는 외부에서 접근할 수 없도록 막고 메소드는 공개.
    외부에서 메소드를 통해 데이터에 접근할 수 있도록 유도.
    private int price;
    
    void setPrice(int price) {
    	this.price = price;
    }

  • getter & setter 메서드를 이용한 코드
    public class Order {
    	public static void main(String[] args) {
    		Pizza pizza = new Pizza();
    		pizza.setPrice(12000);
    		int order = pizza.getPrice();
    
    		System.out.println("피자는 "+order+"원 입니다.");
    		}
    }
    public class Pizza{
    	private int price;
    
    	public int getPrice(){
    		return price;
    	}
    
    	public void setPrice(int price){
    		this.price = price;
    	}
    }

    피자는 12000원 입니다.

0개의 댓글