TIL9 [생활코딩][스프링입문]

givemacdonalds·2023년 12월 6일
0

TIL

목록 보기
10/16

[생활코딩]

패키지

클래스가 많아짐에 따라서 같은 이름을 가진 클래스가 생겨날 가능성이 높아지고 이름의 충돌을 방지하고자 고안된 것

기본 패키지와 사용자 정의 로직

System.out.println(1);

지금까지 가장 많이 사용한 코드

  • System : 클래스
  • out : System 멤버 변수
  • println() : 메소드

자바가 제공하는 제어

접근 제어자

class A {
	public String y(){
    	return "public void y()";
    }
	private String z(){
    	return "public void z()";
    }
    public String x(){
    	return z();
    }
}
public class AccessDemo1{
	public static void main(String[] args){
    	A a = new A();
        System.out.println(a.y());
        
        //아래 코드는 오류가 발생함
        //System.out.println(a.z());
        
        System.out.println(a.x();
    }

}

public String y()
private String z() : 외부에서 접근 할 수 없기에 error가 발생함

접근 제어자를 사용하는 이유

위의 소스코드를 보면
AccessDemo1 클래스가 A 클래스에 대한 고객이고 y(),x()는 고객을 응대하는 창구가 됨
클래스 A는 x()를 통해서 z()를 사용중임

  • public : 은행의 창구
  • private : 은행의 금고

외부에서 접근 할 수 못하게 함으로써 사용자가 의도하지 않은 방법으로 내부적인 클래스의 상태를 바꾸는 불상사를 막을 수 있음

멤버들의 접근 제어자 종류

  • public
  • protected
  • default
  • private

클래스의 접근 제어자

멤버 접근 제어자와는 다르게 총 2개

public

package org.opentutorials.javatutorials.accessmodifier.inner;
public class PublicClass{}

public : 패키지와 관련된 개념
public인 클래스는 다른 패키지의 클래스에서도 사용 가능

default

package org.opentutorials.javatutorials.accessmodifier.inner;
class DefaultClass{}

default : 접근제어자를 붙이지 않으면 됨
default 클래스는 같은 패키지에서만 사용가능

1) 같은 패키지에서 클래스를 사용해보면 문제 없음

public class ClassAccess{
	PublicClass publicClass = new publicClass();
    DefaultCalss defaultClass = new DefaultCalss();
}

2) 다른 패키지에 있는 클래스를 사용하면 error가 발생함

package org.opentutorials.javatutorials.accessmodifier.outter;
import org.opentutorials.javatutorials.accessmodifier.inner.*;

public class ClassAccess{
	PublicClass publicClass = new publicClass();
    //DefaultCalss defaultClass = new DefaultCalss(); // compile error
}

추가적으로 public 클래스의 클래스 명과 소스코드의 파일명이 같아야함

파일명이 publicNameDemo.java

//public class pulicName{}
public class publicNameDemo{}

주석처리 된 부분은 오류가 발생한다.

하나의 소스코드에는 하나의 public class가 존재해야함

abstract

abstract class A{
    public abstract int b(); 

    // public abstract int c(){System.out.println("Hello")}
    // 로직을 포함하고 있는 본체
    // 이 본체가 있는 메소드는 abstract 키워드를 가질 수 없음
    
    public void d(){
    	System.out.println("world");
    }
    // 추상 클래스 내에는 추상 메소드가 아닌 메소드가 존재 할 수 있음
}
class B extends A{ // A클래스를 상속 받은 B
	public int b(){
    	return 1; // overriding
        }
}
public class AbstractDemo{
	public static void main(String[] args){
    	//A obj = new A();
        B obj = new B();
    }
}

public abstract int b();

  • class A가 갖고 있는 메소드이며 추상메소드임
  • 추상메소드의 특징은 {}이 없음(구체적인 로직을 담고 있는 본체가 없음)
  • 시그니처만 갖고 있는 추상적인 메소드
  • 추상메소드를 사용하기 위해서 반드시 overriding 해야함
class B extends A{
	public int b(){
    	return 1;
        }
}
  • class A를 상속받은 Class B가 b메소드를 정의해서 오버라이딩 해야함
  • 구체적인 구현의 책임을 사용하는 쪽에게 넘김(?)

추상 클래스 사용하는 이유

상속을 강제하기 위함
규모가 있는 프로젝트에서 주로 사용함

상황)
1. 사용자는 run이라는 메소드를 호출하면 합계와 평균을 순차적으로 실행하도록 만들고 싶어함
2. 계산 결과의 모습을 경우마다 +- 를 임의적으로 붙여서 사용하고 싶어함

abstract class Calculator{
	int left,right;
    public void setOprands(int left, int right){
    	this.left=left;
        this.right=right;
    }
    public abstract void sum(); // 사용자가 꾸미는 부분
    public abstract void avg(); // 사용자가 꾸미는 부분
    public void run(){
    	sum();
        avg();
     }
}

class CalculatorDecoPlus extends Calculator{
	public void sum(){
    	System.out.println("+ sum :"+(this.left+this.right));
        }
  	public void avg(){
    	System.out.println("+ avg :"+(this.left+this.right)/2);
}

class CalculatorDecoMinus extends Calculator{
	public void sum(){
    	System.out.println("- sum :"+(this.left+this.right));
        }
  	public void avg(){
    	System.out.println("- avg :"+(this.left+this.right)/2);
}

public class CalculatorDeme{
	public static void main{
    	CalculatorDecoPlus c1=new CalculatorDecoPlus();
        c1.setOprands(10,20);
        c1.run();
        
        CalculatorDecoMinus c2 =new CalculatorDecoMinus();
                c1.setOprands(10,20);
        c1.run();
    }
}

공통적인 부분 : run()
사용자가 임의적으로 사용하고 싶은 부분 : sum(), avg()

리팩토링

중복 되는 부분 리팩토링 해볼 수 있음

this.left+this.right 이 부분이 중복됨

abstract class Calculator{
	int left,right;
    public void setOprands(int left, int right){
    	this.left=left;
        this.right=right;
    }
    int _sum(){
    	return this.left+this.right;
    }
    int _avg(){
    	return (this.left+this.right)/2;
    }
    public abstract void sum(); 
    public abstract void avg(); 
    public void run(){
    	sum();
        avg();
     }
}

class CalculatorDecoPlus extends Calculator{
	public void sum(){
    	System.out.println("+ sum :"+ _sum());
        }
  	public void avg(){
    	System.out.println("+ avg :"+_avg());
}

class CalculatorDecoMinus extends Calculator{
	public void sum(){
    	System.out.println("- sum :"+_sum());
        }
  	public void avg(){
    	System.out.println("- avg :"+_avg());
}

public class CalculatorDeme{
	public static void main{
    	CalculatorDecoPlus c1=new CalculatorDecoPlus();
        c1.setOprands(10,20);
        c1.run();
        
        CalculatorDecoMinus c2 =new CalculatorDecoMinus();
                c1.setOprands(10,20);
        c1.run();
    }
}

중복되는 내용을 메소드화 했음
int _sum{return this.left+this.right}
this.left+this.right -> _sum()

int _avg{return (this.left+this.right)/2}
(this.left+this.right)/2 -> _avg()

defualt 접근제어자 이므로 다른 패키지에서 _sum, _avg 에 접근 불가함

[스프링입문]

회원 서비스 테스트케이스

0개의 댓글