열심히 끝까지

디바이스 융합 자바(Java) day07 - 함수 모듈화,객체지향 프로그래밍,오버로딩,this. 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day07 - 함수 모듈화,객체지향 프로그래밍,오버로딩,this.

노유림 2022. 6. 15. 17:43

       << tab
[모듈화]

ex ) 
      쇼핑몰
      -> "재입고 알림"
      A상품 -> 문자알림
      B상품 -> 문자알림
      문자알림() <- 함수
                 ↓
      A상품 -> 문자알림();
      B상품 -> 문자알림();

      A-A공격 -> 기절
      B-C공격 -> 기절
      C-D공격 -> 기절
      기절() <- 함수
                ↓
      A-A공격 -> 기절();
      B-C공격 -> 기절();
      C-D공격 -> 기절();


어떤 로직을 "함수화" 시켜놓는다는 것
   : 코드의 재사용성 증가
   : 중복코드를 최소화
   : 오류의 파급효과 줄어듦
   >> "유지보수" 용이

변수의 3요소
   1. 공간의 크기
   2. 자료형
   3. 공간의 주소 -> 식별자(이름)

배열 3요소
   1. 서로 관련된 데이터
   2. 같은 자료형
   3. 개수를 분명히 알고 있어야 함

- 함수 3요소
   1. input이 몇 개인지 알아야 함
   2. output이 몇 개인지 알아야 함
   3. 기능을 분명히 알아야 함

메서드 시그니쳐 : void printE() << 웹개발때 등장하는 용어
   : 미리 익숙해져 놓을 것

모듈화 방법
   1. 메서드 시그니처 기본으로 선언
   2. 기능을 구현
   3. 기능을 위한 input, output이 있는지 생각
   4. 원래의 위치에서 모듈화한 값을 호출

   - 모듈화를 진행했다면?
     >> 함수의 기능을 유추할 수 있게 작성이 되었다면
     >> 외부에서 신호를 받고 알려주기(출력)만 하면 된다.
          : boolean 이용하여 true, false값 지정  


package class03;

import java.util.Random;

// 함수[모듈화]
public class Test01 {

       static void print(boolean flag) { // 함수의 기능을 유추할 수 있게 작성
              // 함수 3요소
              // 메서드 시그니쳐 : void printE() << 웹개발 등장 용어
              // 모듈화를 했다면 외부에서 신호를 받고 알려주기만 하면 된다
              if(flag) { // true 일때 짝수
                     System.out.println("짝수!");
              }
              else { // false 일때 홀수
                     System.out.println("홀수!");
              }
       }
       static boolean ch(int num) { // void 했다가 true/false 위해 boolean 교환
              // 정수를 입력받으면 boolean값(true/false)으로 바꿔준다.
              if(num%2==0) {
                     return true;
              }
              else {
                     return false;
              }
       }

       public static void main(String[] args) {

              // print(true);
              // print(false);

              //- 어떤 로직을 "함수화" 시켜놓는다는 것
              //  : 코드의 재사용성이 증가
              //  : 중복코드를 최소화
              //  : 오류의 파급효과 줄어듦
              //  >> "유지보수" 용이

              Random rand = new Random(); // 랜덤 함수
              int[] data = new int[5]; // 배열 초기화

              for(int i = 0; i < data.length; i++) { // 랜덤 숫자 배정
                     data[i]=rand.nextInt(100) + 1;
              }
              for(int i = 0; i < data.length; i++) { // 랜덤 숫자 배정
                     System.out.print(data[i] + " "); // 랜덤 함수 출력
              }
             System.out.println();
              for(int i = 0; i < data.length; i++) { // 랜덤 함수의 길이까지 반복
                     /*
                     if(i%2==0){
                            System.out.println("짝수");
                            // 이것 대신에 print(true);
                     }
                     else{
                            System.out.println("홀수");
                            // 이것 대신에 print(false);
                     }
                     */

                     print( ch(data[i] )); // 인자가 boolean이라 매개변수가 맞지 않아!
              }
       }
}

----------------문제
int func(int a, int b, int c){
     // 가장 큰 값 1개를 반환해주는 func()
     return ????;

}

main(){
       int num1 = ?;
       int num2 = ?;
       int num3 = ?;
       
       syso(?이 가장 큰 정수입니다!
}
- 입력받을 때
package class03;

import java.util.Scanner;

public class Test {

       static int func(int a, int b, int c) {
              // 가장 큰 값 1개를 반환해주는 func()
              return a > b ? a : (b > c ? b : c); 
       }

       public static void main(String[] args) {
              Scanner sc = new Scanner(System.in);

              System.out.print("차례로 숫자 입력 : ");
              int num1 = sc.nextInt();
              int num2 = sc.nextInt();
              int num3 = sc.nextInt();

              System.out.println(func(num1, num2, num3) + "이 가장 큰 정수입니다!");
       }
}

 

- 랜덤 숫자 받기
package class03;

import java.util.Random;
import java.util.Scanner;

public class Test {

       static int func(int a, int b, int c) {
              // 가장 큰 값 1개를 반환해주는 func()
              // return a > b ? a : (b > c ? b : c); 
              if(a>b) {
                     if(a>c) {
                            return a;
                     }
                     else {
                            return c;
                     }
              }
              else {
                     if(b>c) {
                            return b;
                     }
                     else {
                            return c;
                     }
              }
       }

       public static void main(String[] args) {

              /*
              Scanner sc = new Scanner(System.in);

              System.out.print("차례로 숫자 입력 : ");
              int num1 = sc.nextInt();
              int num2 = sc.nextInt();
              int num3 = sc.nextInt();

              int NUM= func(num1, num2, num3);
              System.out.println(NUM + "이 가장 큰 정수입니다!");
              System.out.println();
              */

              Random rand = new Random();

              int num4 = rand.nextInt(100)+1;
              int num5 = rand.nextInt(100)+1;
              int num6 = rand.nextInt(100)+1;

              System.out.println();
              int RNUM = func(num4, num5, num6);
              System.out.println(RNUM + "이 가장 큰 정수입니다!");
       }
}


- 강사님의 방법
package class03;

public class Test02 {

       static int func(int a,int b,int c){
              if(a>b) {
                     if(a>c) {
                            return a;
                     }
                     else {
                            return c;
                     }
              }
              else {
                     if(b>c) {
                            return b;
                     }
                     else {
                            return c;
                     }
              }
       }

       public static void main(String[] args) {

              int num1=10;
              int num2=20;
              int num3=15;

              int NUM=func(num1,num2,num3);
              System.out.println(NUM+"이 가장 큰 정수입니다!");
       }
}

 

-------------------------


[객체지향 프로그래밍(OOP)]
과거에는...
이론 -> 실습 -> 이론

하지만 현재..
이론을 짧게 -> 실습을 길~게 충분히 익히기

이렇게 하는 이유 - 비전공자 많음에 따라..!

객체지향 프로그래밍(OOP)
4가지 특징

  1. 추상화
      : ★"객체"가 제일 중요!!!
      : 추상화를 어떻게 하느냐에 따라 앞으로의 객체를 정의할 수 있다.
      :  앞으로의 "설계"가 엄청 중요!!!

  2. 캡슐화
      : 정보은닉(이라고 쓰는 책도 많이 있다)
      : 객체를 이용할 때, 구성을 몰라도(사용법만 알아도) 호출하여 사용이 가능하다!
      : Hiding 
      : 회사에서 자체적으로 개발 혹은 오픈되어 있는 소스(기존에 있는 것 조합)
      : 오픈소스 문제 x + 내가 짠 프로그래밍에도 에러 x => 조합하는 과정에 문제
        => 조합하는 곳에만 시간을 할애하면 된다.
      : 기존에 완성된 로직 코드와 내가 만든 코드를 조합할 수 있게 해준다.
      : 개발 기간 단축 + 에러에 할애하는 시간을 단축된다.
        => 이익 증가!

  3. 상속
      ex) 계산기를 만드는 코드 + - * / 개발완료
           공학용 계산기를 만들어달라는 부탁!
           지수, 로그, sin, cos, + - * /
      : 기존에 있는 것을 그대로 가져와서 그 부분에 더 추가하여
        프로그래밍 하는 것
      : 기존의 코드를 부모로, 하위의 객체들을 생성해낼 때, "상속"받아서 만든다고 표현
      : 부모(상위)코드는 자식(하위)코드들의 공통분모가 됨

  4. 다형성
      : 주어.메서드()(메서드에 주어가 생김), 주어.함수()(함수에 주어가 생김)
      : 같은 함수를 실행하더라도 다른 결과를 볼 수 있다! 
      : 함수에 주어가 생겼기 때문에 같은 메서드더라도 주어에 따라 
        값이 달라진다.
       ex ) 주어는 다르고 함수는 같다.
             강아지.소리내기() -> 멍멍
             고양이.소리내기() -> 야옹

클래스와 객체

  ex ) 붕어빵 틀 -> 붕어빵 x N(개) 해 먹을 수 있다.
       붕어빵틀과 붕어빵의 관계
       붕어빵틀 : 붕어빵 = 1 : N
       >> 클래스 : 객체  

        ex ) 원 모양의 객체들을 앞으로 만들어보고 싶다,
           - 객체를 만들고 싶은 것이다 >> 객체지향 프로그래밍(OOP)해야 함
           - 객체를 만들기 위해서는 "클래스" 우선 정의해야 함

    : 클래스는 대문자로 지정
    : static(객체와 무관하게)가 없다객체와 무관하지 않기 때문에 static을 쓰지 않는다.
   ex ) class Circle{
             void print(){
                   System.out.println("원 객체입니다.");
             }
         } 
    : new라는 것이 객체화를 담당한다
     >> 객체화는 인스턴스화이다(객체화 == 인스턴스화)
   ex ) 
       Circle c = new Circle();
       'c'라는 원 객체 생성완료!
       String, Scanner, Random 등이 클래스  
          String(클래스) str(객체) = new String()(함수);
          Scanner sc = new Scanner(System.in);
          Random rand = new Random();
           
          sc.nextInt() 쓰는 것 처럼
          c.print(); 라고 써야 함

     멤버변수를 제대로 초기화하지 못 할 수도 있다!
       >> 생성자를 쓰는 타이밍에 같이 초기화를 하도록 만들 것!!
       ex ) Student(String str, int n1, int n2){
                   name = str;
                   num = n1;     
                   score = n2;
             } 
             Student stu1 = new Student("홍길동", 101, 95);
            
       ex ) 회원가입 할 때,
            >> 아이디, 비번, 이름, 주소...

   클래스 선언 방법
   -- new : 객체화, 인스턴스화 --> 객체 생성
   
ex )  Student(클래스) stu1(객체) = new Student()(함수);
   클래스는 Student - 괄호가 없음
   함수는 Student() - 괄호가 있음
      : new 연산자 뒤에 밖에 못 붙음
      : 클래스와 이름이 동일하고 객체를 생성할 때
        사용하기 때문에 new와 함께 쓰일 수 밖에 없다
        >> 이 메서드 "생성자"라고 부른다!!!
        >> 생성자는 함수의 한 종류!!
             >>   클래스 객체 = new 생성자();
                                           생성자의 이름 == 클래스의 이름
                                           ( 두 이름은 같다 )
       >> input은 존재하나 output은 존재하지 않는다.
              >> 생성자는 객체화할때만 쓰이기 때문에 output은 객체일 수밖에 없다.
              >> 생성자 앞에 객체를 써야하는데 이미 객체일 수 밖에 없기 때문에
                   쓰지 않는다.


--------------------
package class04;

// 클래스를 정의, 선언
class Circle{ // 클래스끼리 겹치지 않음, 붕어빵틀 완성!
       // 클래스는 대문자로 지정해주기로 약속했음
       int radius; // 멤버변수
       String name; // 멤버변수는 객체마다 고유하게 가질 수 있다.
       void print() { // static이 없어졌다. 멤버함수 == 메서드
              System.out.println(this.name + " : " + this.radius);
       }
       Circle(String name, int radius){
              this.name = name;
              this.radius = radius;
       }
}

public class Test03 {

       static void f() {
              System.out.println("주어없이 바로 호출하여 이용하는 함수");
       }

       public static void main(String[] args) {
              // [ 객체지향 프로그래밍 ]

              // 원 모양의 객체들을 앞으로 만들어보고 싶다.
              // 객체를 만들고 싶은 것 -> 객체지향 프로그래밍(OOP)해야 함
              // 객체를 만들기 위해서는 "클래스"를 우선 정의해야 함
              Circle c1 = new Circle("도넛", 10);
              Circle c2 = new Circle("피자", 50);
              // c 원 객체 생성 완료!
              // 객체화 == 인스턴스화

              /*
              c1.radius=10;
              c1.name = "도넛";

              c2.radius = 50;
              c2.name = "피자";
              */

              c1.print();
              c2.print();
       }
}

----------------------
package class04;

class Student{ // 클래스
       // 생성자는 함수의 한 종류
       //  -> 생성자는 객체화할 때만 쓰이니까, output은 객체일 수 밖에 없다.
       // input은 존재하나 output이 없다!
       Student(String str, int n1, int n2){ // 함수 
              // Student 앞에 객체를 써야 하는데 이미 객체일 수밖에 없기 때문에 안쓴다.
              name = str;
              num = n1;
              score = n2;
       }

       String name;
       int num;
       int score;
       void showInfo() {
              System.out.println(name + "학생은 " + num + "번 : " + score + "점");
       }
}

public class Test04 {
       public static void main(String[] args) {

              Student stu1 = new Student("임꺽정", 100, 80);
              Student stu2 = new Student("홍길동", 101, 95);

              // 멤버변수 초기화 작업 제대로 하기 위해서는 생성자를 쓰는 타이밍에
              // 초기화를 같이 하게 만들어 쓸 수 있도록 할 것
              /*
              stu2.name = "홍길동";
              stu2.num = 101;
              stu2.score = 95;

              stu1.showInfo();
              stu2.showInfo();
              */
       }
}
---this.넣은 코드
package class04;

class Student{ // 클래스
       // 생성자는 함수의 한 종류
       //  -> 생성자는 객체화할 때만 쓰이니까, output은 객체일 수 밖에 없다.
       // input은 존재하나 output이 없다!
       Student(String name, int num, int score){ // 함수 
              // Student 앞에 객체를 써야 하는데 이미 객체일 수밖에 없기 때문에 안쓴다.
              this.name = name;
              this.num = num;
              this.score = score;
       }

       String name;
       int num;
       int score;
       void showInfo() {
              System.out.println(this.name + "학생은 " + this.num + "번 : " + this.score + "점");
       }
}

public class Test04 {
       public static void main(String[] args) {

              Student stu1 = new Student("임꺽정", 100, 80);
              Student stu2 = new Student("홍길동", 101, 95);

              // 멤버변수 초기화 작업 제대로 하기 위해서는 생성자를 쓰는 타이밍에
              // 초기화를 같이 하게 만들어 쓸 수 있도록 할 것
              /*
              stu2.name = "홍길동";
              stu2.num = 101;
              stu2.score = 95;

              stu1.showInfo();
              stu2.showInfo();
              */
       }
}

-----------강사님의 순식간에 짠 코드...
package class04;

class Person{ // 클래스는 객체를 생성하려고 만듦!
       String name;
       int age;
       void showInfo() {
              System.out.println(name + "님은 " + age + "살입니다.");
       }
       // 생성자가 아무것도 정의되어있는 것이 없다면, 기본으로 기본 생성자를 제공해줌!
       // 생성자를 1개 이상 정의하면, 더이상 기본 생성자가 제공되지 않음!!
       Person(){
              name = "무명";
              age = 1;
       }
       Person(String s, int i){
              name = s;
              age = i;
       }
       // 생성자 오버로딩
}

public class Test05 {

       public static void main(String[] args) {

              Person p1 = new Person("홍길동", 21);
              Person p2 = new Person(); // 인자가 없는 생성자인 기본(디폴트) 생성자가 존재

              p1.showInfo();
              p2.showInfo();
       }
}
-----------this. 넣은 것  
package class04;

class Person{ // 클래스는 객체를 생성하려고 만듦!
       String name;
       int age;
       void showInfo() {
              System.out.println(this.name + "님은 " + this.age + "살입니다.");
       }
       // 생성자가 아무것도 정의되어있는 것이 없다면, 기본으로 기본 생성자를 제공해줌!
       // 생성자를 1개 이상 정의하면, 더이상 기본 생성자가 제공되지 않음!!
       Person(){
              name = "무명";
              age = 1;
       }
       Person(String name, int age){
              this.name = name;
              this.age = age;
       }
       // 생성자 오버로딩
}

public class Test05 {

       public static void main(String[] args) {

              Person p1 = new Person("홍길동", 21);
              Person p2 = new Person(); // 인자가 없는 생성자인 기본(디폴트) 생성자가 존재

              p1.showInfo();
              p2.showInfo();
       }
}

----------------------------------


아무것도 입력안하고
그냥 기본값으로 넣어주고 싶은데
매개변수가 없는 생성자를 하나 더 만들어도 되나?

ex ) 피카츄 
     => 객체를 다룰 때 꼭 필요한 정보
     => 만약 입력하지 않는다면 피카츄(기본값)으로 들어간다.

>> 예시처럼 만약 값이 정의되어있는 것이 없다면
     인자가 없는 생성자(=기본(디폴트) 생성자)가 생성된다.
>> 하지만 생성자가 1개 이상 정의하면, 더이상 기본 생성자가 제공되지 않음!
>> 그렇기 때문에 생성자를 하나 만들었지만 기본 생성자도 있었으면 한다면
     직접 만들어 줄 것!!!
>> 이렇게 이름은 같은데 두 개(혹은 그 이상)씩 만들어지는 것
      "생성자 오버로딩" 이라고 한다

 

------------------문제
class Car{
   // ?????
}

main(){
   Car c1=new Car();
   Car c2=new Car("홍길동",120);
   Car c3=new Car("임꺽정");

   c1.show();
// 무명님 자동차 최대속력: 200
   c2.show();
// 홍길동님 자동차 최대속력: 120
   c3.show();
// 임꺽정님 자동차 최대속력: 200
}

package class04;

class Car{ // Car 클래스 생성
       String name; // 차 소유자 이름
       int speed; // 최대 속력

       Car(){ // 기본 생성자
              this.name = "무명";
              this.speed = 200;
       }
       Car(String s, int i){ // 이름과 스피드가 들어간 생성자, 오버로딩
              this.name = s;
              this.speed = i;
       }
       Car(String s){ // 이름만 들어간 생성자, 오버로딩
              this.name = s;
              this.speed = 200;
       }
       void show(){ // 출력문
              System.out.println(name + "님 자동차 최대속력 : " + speed);
       }
}

public class Test06 {
       public static void main(String[] args) {
              // 객체 생성
              Car c1 = new Car(); 
              Car c2 = new Car("홍길동", 120);
              Car c3 = new Car("임꺽정");

              // 출력 실시
              c1.show();
              c2.show();
              c3.show();
       }
}
------------
게시글

글 번호
작성자
작성일
제목
내용
조회수
추천수
>> 프로그래밍
package class06;

class Board{
       int num;
       String writer;
       String reg;
       String title;
       String content;
       int cnt;
       int fav;

       Board(int num, String writer, String reg, String title, String content, int cnt, int fav){
              this.num = num; // 갈색은 지역변수(매개변수)
              this.writer = writer;
              this.reg = reg;
              this.title = title;
              this.content = content;
              this.cnt = cnt;
              this.fav = fav;

              // this.

              // = 내 객체 안의

              // this.num

              // == 내 객체 안의 num변수 == 멤버변수
       }
}

public class Test07 {
       public static void main(String[] args) {
              Board b1 = new Board(1, "홍길동", "6월", "연습", "글내용", 0, 0);

              System.out.println(b1.writer);
       }
}