Backend/JAVA

JAVA 코딩 객체지향프로그래밍 OOP, 클래스 Class, 함수, 메소드

쏠솔랄라 2023. 2. 16. 09:14

 

 

객체 지향 프로그래밍(OOP: Object Oriented Programming)

 

객체 중심의 프로그래밍 방식

객체끼리의 상호 작용을 통하여 프로그램을 작성하는 방식

 

부품화

캡슐화 == 클래스

속성과 기능을 하나의 캡슐처럼 묶어서 정의한 것

 

정보은닉

클래스의 멤버를 보호하기 위해 외부로부터 접근을 제한하는 것을 말한다

프로그램의 안정적 구현과 연관

 

상속성

클래스끼리 물려주거나 물려받는 것

 

다형성

하나의 클래스 객체를 여러 개의 클래스로 표현하는 것

 

 

객체(Object)

 

: 클래스(class)라는 사용자 정의 자료형을 통해 만들어지는 변수 

 

사전적 의미로는 현실세계에 존재하는 모든 것 ; 하나의 완벽한 대상체

프로그램에서의 객체는 어떠한 대상을 표현하기 위한 정보(속성)와 그 대상을 컨트롤할 수 있는 기능(메소드)을

하나의 루틴으로 묶은 개별적인 개체로 표현되는 변수

 

 

클래스

 

: 어떠한 대상을 표현하기 위한 정보(속성)와 그 대상을 컨트롤할 수 있는 기능을

하나의 블록으로 묶어 정의한 사용자 정의 자료형

 

 

형식

 

기본형식

Data + Function + 보안(정보은닉)

멤버변수 + 멤버메소드 + 접근지정자 = class

 

세부 정의 형식

class 클래스명 {

멤버변수 : 변수 선언하듯이 정의

멤버메소드 : 클래스의 기능

- 메소드 : 클래스 내부의 함수를 메소드라고 부른다

- 생성자 : 멤버변수의 값을 세팅하는 메소드

- getter : 멤버변수의 값을 반환 받는 메소드

- setter : 멤버변수의 값을 세팅하는 메소드

- user 메소드 : 사용자 필요에 의해 만드는 메소드

중첩클래스

}

 

 


 

 

함수, 메소드

 

: 소속이 없으면 함수, 소속이 있으면 메소드

 

함수 = 메소드

독립적인 기능을 실행하는 작은 프로그램

 

함수를 사용하는 목적

프로그램을 각 기증별로 구분하여 구조적 효율성 추구

 

함수의 종류

표준 함수 : c언어에서 제공하는 함수

 

사용자 정의 함수

: 프로그래머가 사용하기 위해 직접 작성한 함수

 

함수의 특징

함수는 독립적으로 실행됨

  -> 메소드가 생성되면 별개로 독립적으로 움직인다

함수는 고유한 기능을 가짐

  -> 기능은 중복되지 않는 고유한 기능을 실행하게 된다

함수는 매개 변수를 가질 수 있음

함수는 반환 값을 가질 수 있음 (단, 반환 값은 하나만 ; return문 사용)

재사용, 관리 및 수정이 편리함

 

 

멤버 메소드

 

메소드 형식

   반환 자료형 메소드명(매개변수) {코드 정의; }

 

메소드명 : 메소드를 호출할 때 사용하는 이름

- 메소드의 기능이 연상되는 단어로 이름을 지어준다

- 소문자에서 달라지는 단어의 첫글자는 대문자로 작성한다 ; 암묵적 규칙

 

반환 자료형 : 메소드가 호출되고 종료될 때 돌려주는 값의 형태

- 메소드 내부에서만들어진 갈과 값을 외부에 알려줄때

- print는 반환자료형이 필요 없음 -> 출력하면 끝!

 

 

return

- 메소드 종료

- 특정 상황이 되었을 떄 메소드를 종료시키게끔 한다

- while문에서의 break와 비슷한 역할

- 반환값이 있는 경우 뒤에 적어주면 값이 반환된다 ; 반환값은 1개만 가능

 

 

매개변수

메소드가 실행할 때 필요한 데이터의 형태를 적는 부분

메소드의 실행 재료

매개변수는 메소드의 지역변수

인자값과 매개변수의 관계는 선언과 동시에 초기화

 

 

C언어에서의 함수 호출방식
- 함수를 호출할 때 함수명만 가지고 함수 호출
- 함수명의 중복 정의 불가
- CPP에서의 함수 호출방식
- 함수를 호출할 때 함수명과 매개변수의 자료형을 참조하여 호출한다
- 함수명의 중복 정의가 가능해짐 ; 오버로드(overroad)

메소드의 오버로드
- 메소드명의 중복 정의
- 같은 기능의 메소드들을 매개변수로 구분하여 하나의 이름으로 통합적인 처리를 위해 사용

오버로드의 조건
- 반환 자료형으로는 오버로드를 할 수 없다
- 매개변수의 개수, 순서, 자료형 셋 중 하나라도 다르면 오버로드 조건에 해당
 

 


 

 

접근 지정자(접근제한자)

 

: 클래스의 멤버의 접근 범위를 지정할 수 있는 키워드

 

정보은닉과 관련 있다

멤버마다 앞부분에 적어 정의

 

종류

- private

 

- protect

상속 시 자식클래스에서는 접근 가능 ; 그 외의 외부에서는 접근 불가 ; 비공개

JAVA에서는 같은 패키지에서는 모두 접근 가능 ; 다른 패키지에서는 상속을 통한 접근만 가능

 

- package (default)

우리가 접근 지정자를 지정하지 않으면 자동으로 적용되는 접근 지정자

같은 패키지에서만 접근 가능

 

- public

클래스 내부와 외부 모두 접근 가능

별다른 제약이 없으면 멤버 메소드는 public으로 설정한다

** 클래스에는 두가지의 접근 지정자 중 쓸 수 있다

 

import를 통하여 다른 패키지에서 클래스를 이용할 수 있다

항상 하나의 파일에는 하나의 public 클래스가 존재하여야 한다

public 클래스의 명은 파일명과 동일하여야 한다

package (x)

** 패키지에서만 사용되는 클래스

 

- Setter

멤버변수의 값을 세팅하는 메소드

매개변수명은 일반적으로 멤버변수명과 동일하게 작성한다

멤버변수명을 줄여 쓰거나 앞에 _를 붙이기도 한다

일반적인 형식

void set 멤버변수명(매개변수) {코드정의;}

 

- getter

멤버변수의 값을 반환하는 메소드

형식

반환자료형 get 멤버변수명() {코드정의; (return 멤버변수;)}

  

* this:

멤버 메소드에서 자동으로 만들어지는 0번째 매개변수

자기 자신을 호출한 객체의 인스턴스 공간의 정보를 저장하는 참조형 변수

멤버 메소드 내부에서만 사용 가능

(당분간은 멤버를 부를 때 모두 적자)

 

public class Main { // 하나의 파일에는 두 개 이상의 퍼블릭 클래스를 사용할 수 없다

 

 


 

 

생성자

 

객체 생성시 단 한번만 호출되는 메소드

 

호출되는 시점 상 객체의 초기 설정을 할 때 이용

객체 생성 과정

공간 할당 -> 생성자 호출

 

1. 반환자료형이 없다

2. 메소드명은 반드시 클래스 명과 동일하여야 한다

3. 매개변수를 가질 수 있다

 

형식

클래스명(매개변수) {코드 정의}

 

 

디폴트 생성자

 

: 우리가 생성자를 정의하지 않으면 자동으로 만들어지는 생성자

 

- 객체 생성 과정의 순서 유지를 위해 만들어진다

- 코드가 존재하지 않는다 ; 아무런 기능을 하지 않는다

- 하나라도 정의하면 디폴트생성자는 만들어지지 않는다

  ex. 클래스를 생성하면 디폴트생성자는 만들어지지 않는다

 

형식

public 클래스명 (){}

 

 


 

 

Exercise 1

 

Main.java main() 메소드를 가지는 클래스
Mobile 휴대전화 클래스

(항목) 이름, 통신사, 가격
(메소드) disp(출력)
(생성자) 알아서~

클래스를 만들고 아래의 객체를 생성한 뒤 정보를 출력하시오

 

 // Mobile class

public class Mobile {

 

private String name;

private String tel;

private int pri;

 

 

// 생성자

 

public Mobile (String name, String tel, int pri) {

this.name=name;

this.tel=tel;

this.pri=pri;

}

// setter

 

public void setName(String name) {

this.name=name;

}

 

public void setTel(String tel) {

this.tel=tel;

}

 

public void setPri(int pri) {

this.pri=pri;

}

 

// getter

 

public String getName() {

return name;

}

 

public String getTel() {

return tel;

}

 

public int getPri() {

return pri;

}

 

// user method

 

public void disp() {

System.out.println("모델명 : " + name);

System.out.println("통신사 : " + tel);

System.out.println("가격 : " + pri);

}

 

public void disp(int i) {

System.out.println("[" + i + "] " + "모델명 : " + name + " / 통신사 : " + tel + " / 가격 : " + pri + " 만원");

}

 

 

}

 

// Main 메소드를 가지는 class

 

public class Main {

 

public static void main(String[] args) {

 

Mobile m1 = new Mobile("G6", "LG", 70);

Mobile m2 = new Mobile("아이폰10", "KT", 80);

Mobile m3 = new Mobile("Z플립4", "SKT", 90);

m1.disp(1);

m2.disp(2);

m3.disp(3);

 

}

}

 

 

출력화면

 

 


 

 

Exercise 2

 

Main.java main
Player.java 게임 캐릭터 클래스(Player)

(항목) 아이디(id), 레벨(level), 공격력(attack), 체력(hp)
(메소드) disp(정보출력), +@(필요하다면)
(생성자) 알아서
(특징)
1. 캐릭터 생성시 레벨은 1, 공격력 5, 체력 20
2. 레벨이 증가할 경우 공격력은 3, 체력은 10씩 증가

Main에
아래의 항목을 만드시고 정보 출력
id
[1] 공유 레벨 20으로 변경 후 정보 출력
[2] 아이유 레벨 15로 변경 후 정보 출력
[3] 유인나 레벨 30으로 변경 후 정보 출력

 

// Player 클래스 생성

 

public class Player {

 

private String id;

private int lev, atk, hp;

 

public void init (String id) {

this.id=id;

this.lev=1;

this.atk=5;

this.hp=20;

}

 

// 생성자

 

public Player(String id) {

this.init(id);

}

 

// setter

 

public void setId (String id) {

if (id==null) {

id="";

}

this.id=id;

}

 

public void setLev(int lev) {

if (this.lev >= lev) {

System.out.println("잘못된 레벨입니다!");

return;

}

int gab=lev-this.lev;

this.lev=lev;

this.atk+=gab*3;

this.hp+=gab*10;

}

 

// getter

 

public String getId() {

return id;

}

 

public int getLev() {

return lev;

}

 

public int getAtk() {

return atk;

}

 

public int getHp() {

return hp;

}

 

// user method

 

public void levUp() {

this.lev++;

this.atk+=3;

this.hp+=10;

}

 

public void disp() {

if(id==null) {

System.out.println("아이디가 없습니다");

} else {

System.out.println("아이디 : " + id);

}

System.out.println("레벨 : " + lev);

System.out.println("공격력 : " + atk);

System.out.println("체력 : " + hp);

}

public void disp(int i) {

System.out.println("[" + i + "]" + " 아이디 : " + id + " / 레벨 : " + lev + " / 공격력 : " + atk + " / 체력 : " + hp );

}

 

}

 

// Main 메소드를 가지는 class 생성

public static void main(String[] args) {

Player p1 = new Player("공유");

p1.setLev(20);

 

Player p2 = new Player("아이유");

p2.setLev(15);

 

Player p3 = new Player("유인나");

p3.setLev(30);

 

p1.disp(1);

p2.disp(2);

p3.disp(3);

}

// p1을 생성하면서 p1을 매개변수로 넘겨서는 안 되고

// 그냥 생성할 때는 id만 넘기고 아래에 p1.setLev(20)를 새로 호출해야함

  

출력화면

 

// or

 

public static void main(String[] args) {

Player p1 = new Player("공유", 20);

Player p2 = new Player("아이유", 15);

Player p3 = new Player("유인나", 30);

 

p1.disp(1);

p2.disp(2);

p3.disp(3);

}

 

// 메인화면의 레벨값을 괄호 안에 넣고 Class 내에서 레벨값을 set함

// Player클래스에서 lev의 변환값을 세팅해줌

public Player(String id, int lev) {

this.init(id);

this.setLev(lev);

}

// 이렇게 해도 동일한 값 출력됨

 

 


 

 

Exercise 3

 

Main.java 메인을 갖는 클래스
Player.java 게임 캐릭터 클래스

(구성항목)
아이디(id), 공격력(atk), 체력(hp), 공격대상(target)
     atk와 hp는 양수만 설정되도록 구현( > 0) id
     atk hp 공격대상 [1] 뽀로로 10 100 타요 [2] 타요 15 80 뽀로로

[1]과 [2]를 생성하시고 정보를 출력한 뒤 서로 2번 공격하면 어떻게 되는지 구현
attack()메소드를 Player에 추가한 다음 공격하면 상대방의 체력이 내 공격력만큼 감소되도록 구현

 

// Player 클래스

public class Player {

private String id;

private int atk, hp;

private Player tar;

 

// 생성자

 

public Player (String id, int atk, int hp) {

this.id=id;

this.setAtk(atk);

this.setHp(hp);

}

 

// setter

 

public void setId (String id) {

if (id==null) {

id="";

System.out.println("잘못된 아이디입니다");

}

this.id=id;

}

 

public void setAtk (int atk) {

if(atk < 0) {

return ;

} // akt 의 값이 0보다 작을 때 return 하지 않겠다(return뒤의 값이 없기 때문에 return을 하지 않음)

this.atk=atk;

}

 

public void setHp (int hp) {

if (hp < 0) {

return;

}

this.hp=hp;

}

 

public void setTar (Player tar) {

if (tar == null) {

System.out.println("잘못된 값입니다");

return;

}

this.tar=tar;

}

 

// getter

 

public String getId () {

return id;

}

 

public int getAtk() {

return atk;

}

 

public int getHp() {

return hp;

}

 

public Player tar() {

return tar;

}

 

// user method

 

public void atk (Player atk) {

if (this.tar == null) {

System.out.println("대상이 지정되지 않았습니다");

return;

}

tar.hp-=this.atk;

}

 

public void disp(int i) {

System.out.println("[" + i + "] 아이디 : " + id + "\t 공격력 : " + atk + "\t 체력 : " + hp + "\t 타겟 : " + tar.id);

}

 

// Main 클래스

 

public class Main {

public static void main(String[] args) {

 

Player p1 = new Player("뽀로로", 10, 100);

Player p2 = new Player("타요", 15, 80);

 

p1.setTar(p2);

p2.setTar(p1);

 

for(int i =0; i<2; i++){

p1.atk(p2);

p2.atk(p1);

}

 

p1.disp(1);

p2.disp(2);

}

}

 

출력화면

 

 


 

Exercise 4

 

Main.java main()을 가지는 클래스
Mobile 휴대전화 클래스
단순히 만드는 것에 그치지 말고, 안정성을 높이기 위해 다음과 같이 강제 구현

[1] 이름은 한번 설정하면 절대로 변경할 수 없습니다 ; final
[2] 가격은 아무리 싸게 설정해도 40만원 미만은 불가능합니다
20만원으로 설정시 40만원으로 설정되도록
[3] 통신사나 가격 등은 계속 변경 설정이 가능하도록

(객체 생성 후 아래의 내용을 구현)
    name      telecom    price
[1] 갤럭시8     SKT      300000
[2] G6              LG       330000
[3] 아이폰7       KT       510000
아이폰과 갤럭시8의 가격을 비교하여 비싼 휴대폰 이름을 출력

 

// Mobile 클래스

 

public class Mobile {

final private String name;

private String tel;

private int pri;

 

// 생성자

 

public Mobile (String name, String tel, int pri) {

this.name=name;

this.tel=tel;

this.setPri(pri);

}

 

// setter

 

public void setTel (String tel) {

this.tel=tel;

}

 

public void setPri(int pri) {

if (pri <= 400000) {

this.pri = 400000;

return;

}

this.pri=pri;

}

 

// getter

 

public String getName() {

return name;

}

 

public String getTel() {

return tel;

}

 

public int pri() {

return pri;

}

 

// user method

 

public void compare (Mobile m) {

if (this.pri > m.pri) {

System.out.println(this.name);

} else if(this.pri < m.pri) {

System.out.println(m.name);

} else {

System.out.println("같다");

}

}

 

public void disp() {

System.out.println("브랜드 : " + this.name);

System.out.println("통신사 : " + this.tel);

System.out.println("가격 : " + this.pri + "원");

}

 

public void disp(int i) {

System.out.println("[" + i + "] 브랜드 : " + name + "\t 통신사 : " + tel + "\t 가격 : " + pri);

 

}

}

 

// Main 클래스

public class Main {

 

/*

final int a;

멤버 변수에서의 final

반드시 생성자에서 초기화를 해주어야 한다

초기화를 해 준 후에는 데이터 변경 불가

 

public Test01 (int a) {

this.a = a;

}

final

변수, 메소드, 클래스에 붙을 수 있다

 

* 변수 ; 한 번 설정하면 데이터 변경 불가

* 메소드 ; 오버라이드(재정의) 금지

* 클래스 ; 상속 금지

 

final int a = 10; // 설정

a = 20; // 재설정x

*/

 

public static void main (String[] args) {

 

Mobile m1 = new Mobile("갤럭시", "SKT", 300000);

Mobile m2 = new Mobile("G6", "LG", 330000);

Mobile m3 = new Mobile("아이폰8", "KT", 510000);

m1.disp(1);

m2.disp(2);

m3.disp(3);

 

m1.compare(m3);

 

}

}

 

출력화면