자바의정석 6

ChoRong0824·2023년 5월 25일
0

Java

목록 보기
22/31
post-thumbnail

JavaStudy 23.05.23
자바의 정석 chapter 6를 읽고 느낀점을 저만의 방식으로 정리 및 포스팅했습니다.


필자가 독자에게 '전달 하고싶은 생각'

너무 객체지향 개념에 얽매여서 고민하기 보다는,
일단 프로그램을 기능적으로 완성한 다음, 어떻게 하면 보다 객체지향적으로 코드를 개선할 수 있을지를 고민하여 점차 개선해 나가는 것이 좋습니다.

즉, 다양한 프로젝트 경험이 쌓여야 한다는 것입니다.

--> 문법공부 및 이론 공부가 어느정도 끝났다면, 이제는 다양한 프로젝트를 진행하여 부딪혀보고, 코드 개선을 고민하는 " 과정 " 을 겪음으로써 성장한다는 것입니다.

다시 말해, 처음부터 이론을 완벽하게 100 % 이해한다는 것은 불가능합니다.
또한, 이론을 많이 안다고 해서 좋은 설계를 할 수 있는 것은 아닙니다.
예시를 들어, 축구를 잘하려고 축구 공부만 엄청 했습니다.(축구를 하지않고)
어떻게 드리블을 하고, 어떻게 패스를 넣어야할 지 등등 정말 이론은 잘 압니다.
메시, 호날두보다 더 잘아실겁니다.
BUT, 여기서 제일 중요한 것은 실제 축구는 못한다는 것입니다.
공을 단 한 번도 터치도 안해봤는데 어느정도의 힘으로 공을 찰 지도 모르는데 어떻게 잘 할 수 있는지 필자는 감히 생각하기 어렵습니다.
즉, 필자가 하고싶은 말은, 이론은 100 % 정돈 아니지만, 기본적인 것들만 익히고, (축구 예) 파울 기준, 옾 사이드 기준 등을 익히고 축구를 많이 해봐야 한다는 것입니다.
또한, 사람의 기억장치는 휘발성입니다. (주관적)
완벽하게 외웠다고 생각해도, 시간이 지나면 까먹게됩니다.
따라서, 많이 사용해봐야 합니다.

결론 : 프로젝트를 많이 해보자 !


재밌는 코드 문제, 출력 값을 말해보세요

class Toy{
    String name;


    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}
class Test{
    public static void main(String[]args){
        Toy t1 = new Toy();
        Toy t2 = new Toy();

        t1.name ="베트맨";
        System.out.println(t1.name);
        t2.name ="슈퍼맨";
        t2 =t1;
        System.out.print(t2.name);
    }
}

참조변수

참조 변수(Reference variable)는 프로그래밍 언어에서 변수에 할당된 메모리 주소를 가리키는 변수를 말합니다. 즉, 참조 변수는 객체 또는 데이터 구조의 인스턴스를 참조하기 위해 사용되는 변수입니다.

일반적으로 참조 변수는 객체 지향 프로그래밍에서 사용됩니다. 객체는 클래스의 인스턴스로, 클래스는 객체를 생성하기 위한 템플릿입니다. 참조 변수를 사용하여 객체를 참조하면 해당 객체에 접근하고 수정할 수 있습니다.

다른 말로 하면, 참조 변수는 객체의 주소를 저장하고 있는 변수로서, 객체에 대한 참조를 통해 해당 객체에 접근하고 조작할 수 있게 해줍니다. 참조 변수는 객체의 소멸과 독립적으로 존재하며, 여러 참조 변수가 동일한 객체를 가리킬 수도 있습니다.

예를 들어, Java 언어에서 다음과 같이 객체를 생성하고 참조 변수를 사용할 수 있습니다:

MyClass obj = new MyClass();
위 예제에서 obj는 MyClass라는 클래스의 인스턴스를 참조하기 위한 참조 변수입니다. new 키워드를 사용하여 MyClass의 새로운 객체를 생성하고, 이 객체의 메모리 주소가 obj에 할당됩니다. 이제 obj를 통해 MyClass 객체에 접근하고 해당 객체를 조작할 수 있습니다.

참조 변수의 중요한 특징은 객체의 상태를 변경할 수 있다는 것입니다. 따라서 참조 변수를 통해 객체에 접근하고 조작하면 다른 참조 변수도 동일한 객체를 참조하고 있을 때 그 변경 사항을 볼 수 있습니다. 이는 객체 간의 데이터 공유와 객체 지향 프로그래밍의 핵심 개념 중 하나입니다.


변수와 메서드에서

멤버변수를 제외한 나머지 변수들은 모두 지역변수이며,
멤버변수 중 static이 붙은 것은 클래스변수,
붙지 않은 것은 인스턴스 변수입니다.
전역변수 : 클래스 변수는 public을 앞에 붙이면 같은 프로그램 내에서 어디서나 접근할 수 있는 '전역변수'의 성질을 갖습니다.


클래스 멤버와 인스턴스 멤버간의 참조와 호출

class Test{
	void instanceMethod(){}
    static void stMethod(){} // static 메서드
    
    static void stMethod2(){
    	instanceMethod(); // ERR
	}
}

이유 : (메모리 입장에서) 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스 멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수 있기 때문

class Test2{
	int iv;
    static int cv;
    
    static void staticMethod(){
    	System.out.print(iv); // ERR
    }
}

이유 : 메서드간의 호출과 마찬가지로 인스턴스메서드는 인스턴스 변수를 사용할 수 있지만, static메서드는 인스턴스 변수를 사용할 수 없음. (메모리 영역에 static이 먼저 탑재되기 때문)


MemberNumber MN = new MemberNumber();
int num = MN.instanceMethod();

이 코드를 한 줄로 요약하면
int num = new MemberNumber().instanceMethod(); 로 할 수 있습니다.
대신, 참조변수를 선언하지 않았기 때문에 생성된 MemberNumber 인스턴스는 더이상 사용할 수 없게 됩니다. 이점 주의해주세요 !


오버로딩

  • 조건
  1. 메서드 이름이 같아야한다
  2. 매개변수의 개수 또는 타입이 달라야 한다.

즉, 오버로딩된 메서드들은 매개변수에 의해서만 구별될 수 있고,
반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못합니다.

성립되지 않는 오버로딩 예시
// 1 
int add (int a, int b){return a+b;}
int add (int c, int d){return c+d;}

// 2
int add (int a, int b){return a+b;}
int add (int a, int b){return (long)(a+b);}

// 3
long add(int a, long b){return a+b;}
long add(long a, int b){return a+b;}
  1. 매개변수의 이름만 다르고, 매개변수의 타입이 같기 때문에 성립하지 않음

  2. 리턴타입만 다른경우, 어떤 메서드가 호출된 것인지 결정 x (모호하기 때문)

  3. 올바른 경우입니다. 서로 순서가 다른 경우임. 호출 시 매개변수의 값에 의해 호출될 메서드가 구분될 수 있으므로 중복 메서드 정의가 아닌, 오버로딩으로 간주함


오버로딩의 장점

오버로딩을 통해, 하나의 (틀이 있는)이름으로 정의될 수 있습니다.
이런 메서드의 이름만 보고도 '이름이 동일하니까, 같은 기능을 수행하겠구나'라고 예측할 수 있게 됩니다. 즉, 가독성 및 재사용성에 용이합니다.


가변인자

기존에는 메서드의 매개변수 개수가 고정적으로 호출 및 사용되었으나,
가변인자를 통해 동적으로 지정할 수 있게 되었습니다.

  • 형식 : 타입... 변수명과 같은 형식으로 선언

매개 변수가 여러개라면, 매개변수 중에서 제일 마지막에 선언 해야합니다.
또한, 가변인자는 배열도 가능.

즉, 가변인자는 내부적으로 배열을 이용하는 것입니다.
그래서 가변인자가 선언된 메서드를 호출할 때마다 배열이 새로 생성됩니다.
이러한 특성상 비효율적이기 때문에, 꼭 필요한 경우에만 가변인자를 사용해야합니다.

가변인자 오버로딩 코드
// 1
String[] strArr = new String[] {"100", "200", "300"};
System.out.print(concatenate("-", strArr));

// 1번을  합치면
System.out.print(concatenate("-", new String[]{"100", "200", "300"})); // 이렇게 바꿔줘야합니다. 

// 허용되지않는 코드
System.out.print(concatenate("-", {"100","200","300"}));
코드설명
  • concatenate메서드는 매개변수로 입력된 문자열에 구분자를 사이에 포함시켜 결합한 후 반환합니다. 또한, 가변인자로 매개변수를 선언햇기 때문에 문자열을 개수의 제약없이 매개변수로 지정할 수 있게 됩니다.

  • 허용되지 않는 코드를 보면, 두 오버로딩된 메서드가 구분되지 않아서 발생하는 것입니다.
    가변인자를 선언한 메서드를 오버로딩하면, 메서드를 호출했을 때, 구별하지 못합니다. (애매하기 때문). 따라서, 가능하면 가변인자를 사용한 메서드는 오버로딩 하지 않습니다.

profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

0개의 댓글