hoon's bLog

Java private extends abstract 캡슐화, 추상클래스 본문

IT/Java

Java private extends abstract 캡슐화, 추상클래스

개발한기발자 2021. 1. 5. 16:36
반응형

안녕하세요 여러분!

지난 시간에 이어 객체지향 프로그래밍의 4가지 특징!

캡슐화, 상속, 다형성, 추상화에 대해서 예제를 통해 좀 더 구체적으로 알아보도록 하겠습니다.

캡슐화란?

모든 변수들과 메서드들을 클래스라고 불리는 단위에 모으는 것,

즉 객체 안에 데이터와 메서드를 숨기는 것을 의미합니다.

캡슐화는 의도치 않은 변화에서 데이터와 메서드의 안전을 유지하는 보안을 제공합니다.

캡슐화 = 은닉성이라는 말을 많이 들어보셨을 텐데,

프로그래머는 데이터와 메서드를 사용하거나 접근할 수 있지만 변경할 수는 없습니다.

캡슐화를 하려면?

1. 멤버 변수 앞에 접근 제어자 private를 붙입니다. (private: 자기 클래스에서만 접근할 수 있는 것 )

2. 멤버 변수에 값을 넣고 꺼내 올 수 있는 메소드를 만듭니다. (접두어 set/get을 사용해 메소드를 만든다.)

아래 예제들을 통해 한번 알아보도록 하겠습니다.

//Student Class
public class Student{
   //Student의 멤버변수 : name, id, age
	private String name;
	private int id;
	private int age;

	public void setName(String name){
		this.name = name;
	}
	
	public void setId(int id){
		this.id = id;
	}

	public void setAge(int age){
		this.age = age;
	}
	
	public String getName(){
		return name;
	}
	
	public int getId(){
		return id;
	}
	public int getAge(){
		return age;
	}
}

}

//School Class
public class School {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.setName("근둥이");
		stu.setId(1316548);
		stu.setAge(30);
		
		System.out.println("이름 :" +stu.getName());
		System.out.println("학번 :" +stu.getId());
		System.out.println("나이 :" +stu.getAge());
	}
}

실행 결과

우리는 Student 클래스의 멤버 변수들 name, id, age에 private를 붙여서 은닉화 시켰습니다.

그리고 School 클래스에서 이 Student의 멤버 변수를 조작하는 것은 this가 붙은 메서드를 활용하면 됩니다.

문제는 호출하는 것!

만약에 우리가 평소에 해왔듯이 stu.age처럼 하면 바로 오류가 발생할 것입니다.

왜냐? 은닉화 되어있기 때문에 바로 접근할 수가 없는 것이죠!!

그래서 위처럼 우리는 메서드를 이용해 간접적으로 접근하는 것입니다.

참고로 get, set이 붙은 함수를 우리는 흔히 getter / setter라고 합니다.

원하는 멤버 변수를 선언뒤, 필요한 멤버변수를 선택하시고,

아래 그림처럼 해주시면 일일이 타이핑을 치지 않아도 자동으로 생성됩니다.

이러한 클래스를 실무에서는 흔히 VO(Value Object)라고들 합니다.ㅎㅎㅎ

추후 Spring, Spring Boot를 하면서 MVC Model을 하시면서 알게 되실 겁니다 ㅎㅎㅎㅎㅎ

상속이란?

존재하는 클래스의 속성들과 메서드들을 공유하는 클래스들을 생성 가능하게 한다.

주로 코드의 재사용에 사용되고, 우리는 이미 작성된 클래스를 확장하여 사용하고 있기 때문입니다.

자신이 만들어서 상속시킬 수도 있고 JDK가 지원하는 클래스로부터 상속받아 사용 가능합니다.

- 최상위 클래스는 java.lang.Object

- 상속 키워드 : extends

상속 사용법은?

public class class이름 extends 상위class이름{

        //내용.....

}

역시 예제로 알아보는 게 빠르겠죠?

//Employee Class
public class Employee 
{
    private String empNo;    // 사원번호
    private String name;    // 이름
    private String part;    // 부서
    
    // 매개변수가 없는 생성자
    public Employee()    {    }
    
    // 매개변수 3개를갖는 생성자
    public Employee(String empNo, String name, String part)
    {
        this.empNo = empNo;
        this.name = name;
        this.part = part;
    }
    
    // getter와 setter를 이용한 값을 set해주고 return해주기
    public String getEmpNo() { return empNo; }
 
    public void setEmpNo(String empNo) { this.empNo = empNo; }
 
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public String getPart() { return part; }
 
    public void setPart(String part) { this.part = part; }
    
    // 멤버 필드의 결과값 문자열로 
    public String resultStr()
    {
        String result = "";
        
        result += "사번 : " + empNo + "\n";
        result += "이름 : " + name + "\n";
        result += "부서 : " + part + "\n";
        
        return result;
    }
}

//Manager Class, Employee Class로부터 상속받음
public class Manager extends Employee 
{
    private String position; // 직책
 
    // 매개변수 4개를 갖는 생성자
    public Manager(String empNo, String name, String part, String position) {
        setEmpNo(empNo);
        setName(name);
        setPart(part);
        this.position = position;
    }
 
    // 관리자에서 추가되는 정보를 결과 문자열로 결합
    public String addStr() {
        String result = "";
        result += "직책 : " + position + "\n";
        return result;
    }
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class Company 
{
    public static void main(String[] args)
    {
        String result = "";    // 결과 문자열
        Employee emp = null;   // Employee 객체의 레퍼런스 변수
        Manager mng = null;    // Manger 객체의 레퍼런스 변수
        String empNo = null;   // 사원 번호
        String  name = null;   // 이름
        String part = null;    // 부서
        String  position = null; // 직책
        
        // BufferedReader은 String 타입의 데이터 입력받을때 쓰임
        // Scanner은 여러 타입 입력 가능
        BufferedReader in =new BufferedReader(new InputStreamReader(System.in));
 
        try    // 예외처리를 위한 try ~ catch문 (나중이 자세히 배움)
        {
            // 정보 입력 단계
            System.out.print("사번 입력(예)A1010 : ");
            empNo = in.readLine();
            System.out.print("이름 입력(예)너구리 :");
            name = in.readLine();
            System.out.print("부서 입력(예)기획 :");
            part = in.readLine();
            System.out.print("직책 입력(예)사원-1, 대리-2, 과장-3 :");
            position = in.readLine();
        }catch(Exception e)    // 잘못입력 했을시...
        {
            System.out.println("입력 오류");
        }
        
        if (position.equals("1"))    // 직책이 사원 일경우는 사원 생략
        {
            emp = new Employee(empNo, name, part);   
            result += emp.resultStr();    // 결과값 
        }else    // 직책이 매니져급인 대리 과장일 경우
        {
            // 2일경우 대리 나머지일경우 과장
            position = (position.equals("2")) ? "대리" : "과장";    
            // 생성자
            mng = new Manager(empNo, name, part, position);
            // 결과값 넣어서 합치기
            result += mng.resultStr() + mng.addStr();
    
        }
        System.out.println(result);    // 결과 출력
    }
}

추상 메서드

정의 : 내용이 없는 메서드, 구현(정의)은 하지 않고 선언만 한 메서드

목적 : 메서드의 내용이 너무 일반적 내용이라 부모 클래스에서 구체화하여 정의할 필요 없을 경우, 추상 메서드로 선언만 하고 상속받은 자식 클래스에서 재정의하도록 할 때 사용

추상 클래스(abstract class)

정의 :

- 한 개 이상의 추상 메서드를 가지는 클래스

- 일반적인 클래스는 세부적이고, 구체적 ex) 고양잇과, 개과

- 반면 추상 클래스는 일반 클래스에 비해 구체적이지 않고 추상적 ex) 고양이, 사자, 강아지

목적 : 추상 메서드는 선언만 되고 구현이 되지 않은 불완전한 메서드이므로 객체로 생성되어서는 안 됩니다.

이런 클래스(추상 메서드가 포함된 클래스)는 추상 클래스로 선언하여 객체 생성을 금지시킵니다.

추상 클래스는 반드시 하나 이상의 추상메서드를 가지며, 객체를 생성할 수 없습니다. 하지만 슈퍼클래스로 사용할 수는 있으며 추상메서드를 사용하기 위해서는 반드지 해당 메서드를 재정의 해야만 합니다.

추상클래스 또는 추상메서드를 선언하기 위해서는 이름 앞에 abstract를 추가하면 됩니다.

추상클래스 형식

abstract class 클래스명{

      추성 메서드();

}

추상 메서드 형식

abstract 접근 제한자 반환 타입 메서드명(매개변수){

        내용,,,

}

추상 클래스와 추상 메서드 예제

public class AbstractTest {
	public static void main(String[] args) {
    	FirstCat fc = new FirstCat();
        SecondCat sc = new SecondCat();

		fc.call();
		sc.call();
	}
} //AbstractTest


abstract class Cat{ // 추상 메서드를 포함하므로 추상클래스로 선언
	abstract void call(); // 추상 메서드 선언(구현x)
	void call2(){
    	System.out.println("일반 메서드");
	}
} //Cat 추상클래스를 상속한 클래스들

class FirstCat extends Cat{
	void call(){ //추상메서드는 서브클래스에서 반드시 재정의 되어야 함
	System.out.println("첫번째 야옹이");
	}
}

class SecondCat extends Cat{
	void call(){
    	System.out.println("두번째 야옹이");
	}
}

이제야 클래스와 객체를 어느 정도 알아간 것 같습니다.

저도 실무에서 복붙으로만 쓰다가 개념을 정리하면서 알아가니 또 다른 느낌입니다.ㅎㅎㅎ

사실 지금도 제대로 정리했다고 볼 수 없지만,

'안 한 것보다는 낫다' 주의라 이렇게 한 번씩 예제를 통한 개념 정리는 정말 많은 도움이 되는 것 같습니다.

(물론 '안 하느니만 못하다'가 되어선 안 되겠죠?ㅎㅎㅎ)

읽어주셔서 감사하고,

언제나 객관적인 태클과 따끔한 충고는 환영입니다!

오늘도 포스팅 읽어주셔서 감사합니다:)

 

출처 : 자바의 정석 3rd Edition 내용 정리

728x90
반응형