국비지원학원/Java

27일차

초코맛 2018. 11. 27. 22:49
반응형

<ex) Person lee = new Person();으로 생성할때, setter method 로 값을 담는데.

<태어나서 기본적으로가지고있어야될값들이 있을텐데 그게없고,  나중에넣는다는게 이상함.
<이름은 나중에 지어주는거니까 맞는데,
<그래서 setter method와 처음부터 넣어주는 2가지로 나누어 진다.
<미리넣고 싶을때,처음부터 갖고있고 싶을때 생성자사용.
<객체가 생성 되었을때 값을 넣고 나오는게 있을텐데 그때쓰는것
<라면클래스도 마찬가지 처음부터 빈봉지..?이상함



*생성자(Constuctor)

  • 객체가 생성될 때 가지고 있어야할 기본값(객체초기화값)이나 수행될코드를 정의하는 (부분인데 분류상 메소드) 메소드의 일종
  • <생긴건메소드랑같게생김 / 생성자는오버로딩지원
  • 반환형이 없다
  • 오버로드 지원 (객체생성을 다양하게 할수 있다)
  • 클래스명과 동일하게 작성
  • <모든클래스 는 생성자를다 가짐 없는 클래스는 존재할수없음 private라보이지않는것
  • <기본생성자다가짐
  • 개발자가 생성자를 하나도 정의하지않으면컴파일러가<초기값은 실행기가>(인자없는) 매개변수없는 기본생성자(디폴트 컨스터럭트)를 무조건 생성해준다.
  •                                                                                                                                                                    => 기본생성자의 접근지정자는 클래스의 접근지정자를 따라간다.
  • <생성자는메소드쩜 이케안불러지고
  • 생성자는 객체를 생성할 때만 호출된다 (method 호출하듯이 직접 호출할 수 없다)
  • this를 사옹하면 내클래스의 다른 생성자를 호출할 수 있다.
  • <개발자가 생성자를 하나라도 만들면 안해준다. 없을때 까먹었구나 하고 만들어줌
  • 문법)
접근지정자 생성자명(parameter...){
}
  • 접근지정자)
  • public : 클래스 외부에서 객체생성 가능
  • protected : 동일패키지의 다른 클래스에서 객체 생성가능 / 패키지가 다르다면, 자식클래스만 객체 생성 가능
  • private : 클래스 안에서만 객체 생성 가능(싱글턴?패턴 을 적용해서 클래스를 만들고 싶다면 프라이빗 준다.)=>(Singleton pattern적용)
  • default : 아무것도 붙이지 않는것으로 동일 패키지의 다른 클래스에서 객체생성이 가능하지만, 패키지가 다르다면 객체생성 불가능
  • <퍼블릭이나 프라이빗 제일 많이 쓴다.
  • <생성자를 하나도 안만ㄷ르었엇 할땐 클래스의 접근지정자를 따라간다. 라면의 자동생성된 접근지정자는 퍼블릭이 되었을것
  • 기본생성자의 접근지정자는 클래스의 접근지정자를 따라간다.
  • ex)

public class Marker{

        public Marker(){
            color = "검은색";
            cap=1;
            body=1 ;
        }//생성자
        public void setColor(String s){
        }
        public Marker(String color, int cap, int body){
               this color = color;
               this cap= cap;
               this body= body;
        }//생성자의 오버로딩
}
클래스면 객체명 = new 생성자();
Marker m = new Marker();//검은색

m.setColor("빨간색");//검은색을 만들어놓고 빼고 빨간색을 넣는격

Marker ml = new Marker("빨간색" , 1,1);
//생성자의 오버로딩으로 다형성 
//객체가 다르게 만들어진다.






<원래 객체 생성 할때 이렇게 불려지는 것이었다.>

 

<디컴파일러 : 클래스파일을 자바로 (배포될땐 클래스 파일로 배포되는데) 자바소스를 보고싶을때 사용>
<원래 코드로 되돌려 만들어진 프로그램의 취약점 찾기 : 리버싱 / 크랙도 리버싱의 일종 

<클래스파일은 바이트 코드로 사람이 알아볼수 없는데, 그걸 알아보기 위해 소스코드로 바꿈.
<기본생성자 : 소스단계에 없어도 디컴파일러로 보았을때 생성되어있다. 컴파일러가 생성해 줌을 알수 있음

 
<API 에서 사용되는 모습..>
<오버로딩이 잘되어있음을 알수 있다.>

<생성자 없는 클래스가 아니라 프라이빗이라 밖에서 안보이는것 뿐=>없으면 존재할수 없다.>

 
<만든생성자를 모두 주석처리하고 기본생성자가 생긴모습>

<생성자를 만들고 기본생성자가 없어진 모습=>하나정의하고 나니 기본생성자가 사라짐.

<먼저한 코드들 호출부분의 setter method부분을 생성자로 고쳐봄>

<닥만들어서 잘 만들어졌는지 봄>
<생성자란~? 객체 생성시 기본값들을 넣어주는 부분~~
<생성자는 직접호출이 되지 않고 this 사용시 호출할수 있다고,,



*this
  •  생성자를 호출하거나, heap의 주소(생성된 객체의 주소)를 가지는 keyword  <용법2가지
  • method 형식과 keyword 형식으로 사용할 수 있다.
  • method 형식)
    • 생성자를 호출할 때
  • keyword 형식)
    • 생성된 객체의 주소를 사용할 때.
  • this method 형식)
    • 내 클래스의 오버로딩(Overloding)된 생성자를 호출할 때 사용.
    • <규칙을 반드시 지켜서 작성해야한다.
    • <생성자의 첫번째 줄에서 꼬옥(슈퍼자리에)
    • <생성자를 부른다.
    • 규칙 : 생성자의 첫번째 줄에서만 사용가능.
    • 문법)
this();   //기본생성자를 호출할때 사용.
this(인수값,,,);   //인자있는 생성자를 호출할 때 사용.
<재귀호출이 되면 Error  <생성자의 재귀호출 불가.
ex)
public class Test{
    public Test(){
    }
    public Test(int i){
    }
}
Test t = new Test();
이때 기본생성자에서 인자있는 생성자를 부르고 싶으면

public class Test{
    public Test(){
        this(11);
    }
    public Test(int i){
    }
}
Test t = new Test();
<기본생성자를 불리고 인자있는생성자를 바로 부른뒤 일을 하고 닫힘괄호로 다시 기본생성자로 돌아가 
<나머지 돌고 닫힘괄호만나 호출한 곳으로 돌아간다.

 
public class Test{
    public Test(){
        
    }
    public Test(int i){
        this();
    }
}//요렇게도 해보고~
<만약 둘다 서로를 부르고 있다면 재귀호출이되어 프로그램이 끝나지 않는다. 그래서 아예 프로그램에서 막아 놓았는데 그래서 Error
<재귀호출의 가능성이 있거나 그안에서 나를다시 부른다면 바로 이클립스에서 Error 쓰고싶어도 쓸수 없다.
<자바는 재귀호출 Error

<서로계속 불러 Error>

 
<이 순으로 돌게 되고 this로 다른생성자를 호출가능>

 
<this 의 사용으로 이렇게도 줄일수 있다. >

 

<생성자를 알았더니 사용하는쪽의 코드가 간단해졌고
<this를 알았더니 생성하는곳의 코드가 간단해짐





  • this method 형식)
  • <하기전에 콜바이벨유와 콜바이레퍼런스   알아야한다.<C에대한 이야기지로 자바도 그런 성격이지만 자바는 확인할 길이 없다
*Call by value
  • method의 매개변수를 기본형데이터형으로 정의하면 값이 복사되어 넘어간다. (전달된다.)
  • <복사된 값으로 계속 돌고 원본값이 바뀌지 않는것?
  • <클래스 스트링 배열로 저장하면 주소가 그대로 저장(주소는 딱 하나인데 하나가지고 쓰는것)
ex)
class Test{

    public void swap(int i, int j){
        int temp=0;
        temp = i;
        i=j;
        j=temp
    System.out.println("i="+i",j="+j);//300 100
    }
    public static void main(String[] args){
        int i=100,j=300;
        S.o.p(i+" "+j);//100 300
        Test t = new Test();
        t.swap(i,j);
        sop(i+""+j);
    }
}
//복사된 값이라 원본에 영향을 끼치지 않는다.
//복사된종이에 낙서된다고 원본에 낙서되지 않음=>Call by value



int i=100, j=300

temp][0]
i][100
temp][100
j][300
i][300
temp][100
j][100
//매개변수로만 놀고 사라짐

ex)
class Test{

    public void swap(int i, int j){
        int temp=0;
        temp = i;
        i=j;
        j=temp
    System.out.println("i="+i",j="+j);//300 100
    }
    public static void main(String[] args){
        int i=100,j=300;
        S.o.p(i+" "+j);//100 300
        Test t = new Test();
        t.swap(i,j);
        sop(i+""+j);
    }
}
//복사된 값이라 원본에 영향을 끼치지 않는다.
//복사된종이에 낙서된다고 원본에 낙서되지 않음=>Call by value
 public static void main(String[] args){
        int i=100,j=300;
        S.o.p(i+" "+j);//100 300
        Test t = new Test();
        t.swap(i,j);
        sop(i+""+j);
    }
 int i=100,j=300;
[i][100]
[j][300]
[t][i=100,j=300]

method(static변수
stack(local변수
heap(instance변수
JVM



*Call By Reference
  • method의 매개변수를 참조형 데이터형으로 정의하면 하나의 주소가 그대로 넘어간다.(주소는 유일)
  • <건드리면 바뀐다. 원래의 값이~!
ex)
class Test{
int i;//만약 int가 private였으면 밖에서 접근이 안되야 하는데 
//배열 일때에는 getter로 써서 내보내면 public이 되어 콜바이레퍼런스때문에 변경됨...배열시 다시
int j;//인스턴스 변수라 쓰려면 객체화

public void swap(Test t){
//이 클래스로 i와 j에 접근
int temp = 0;
temp = t.i;
t.i=t.j;
t.j=temp;
s.o.p("swap 안에서"+i+" "+j);//200 100
}
public static void main(String[] args){
Test t = new Test();
t.i=100;
t.j=200;
s.o.p(t.i+" "+t.j);/100 200
t.swap(t);//그 주소를 그대로 갖고 가서 건드렸기 때문에 변경된다.
s.o.p(t.i+" "+t.j);//200 100
}
}  //<복사와 주소의 차이 참조형데이터형일떄에는 값의 변경을 주의해야한다. =>배열 주의...


*Keyword 형식
  • 생성된 객체의 (heap에 올라감) 주소를 저장한 keyword
  • <특징)어디에서나 쓸수 있지만 객체가 생성되기전 호출되는 영역에서는 쓸수 없다.   <(static 영역ㄴㄴ)
  • static 역역 안에서는 사용할 수 없다    <(인스턴스안에서만 사용가능)<편함..
  • 문법)
this.변수명
this.method명();
<변수나 메소드를 쓸때 쓰게 됨.

ex)
class Test{
 int i ;
 public void temp(int i){
    system.out.println(i);//1000
}
public static void main(String[] args){   
    Test t = new Test();
    t.temp=1000;
    s.o.p(t.i);//0
//i에 값을 넣어 준 적이 없음.
}
//1000이 나오게 고치려면 노란부분을 고쳐야 하는데,

                        //이렇게 고친다.
class Test{
 int i ;
 public void temp(int i,Test t){
    system.out.println(i);//1000
    t.i=i;
}
public static void main(String[] args){   
    Test t = new Test();
    t.temp(1000, t);
    s.o.p(t.i);//0->1000
}
}
  • <이걸 편하게 쓰기 위해 this가 나온것.
  • <클래스를 매개변수로 준다음에 t에 값을 넣으면 t.i에 1000이 들어가 값이 들어있는 heap부분에 저장하게 됨으로 1000이 유지된다.
  • <<<Test t라는 주소를 넣어주어야 주소를 받고 그주소의 변수에 값을 넣어주어 살아있게 된다.
<JVM에서 벌어지는 일>


println frame
println
[x][t.i]=>1000

class Test{
 int i ;
 public void temp(int i,Test t){
    system.out.println(i);//1000
    t.i=i;
}
public static void main(String[] args){   
    Test t = new Test();
    t.temp(1000, t);
    s.o.p(t.i);//0->1000
}}
//주소를 불러다 꽂아준다.

class Test{
int i ;
public void temp(int i){
    System.out.println(i);//1000
    this.i=i;//인스턴스 변수를 부르는 t로 대치가 된다
}
public static void main(String[] args){   
    Test2 t = new Test2();
    t.temp(1000);
    System.out.println(t.i);//0
}}
//this를 keyword로 사용한 버전
//두개가 같다.

println frame
x][i참조


t][10번지 주소]
i][1000
(temp frame)

클래스(static변수 잡고)->메인(Test t=new Test();)
->temp->int i, test T >temp는 멈추고 println 프레임
int x는 x는 실행되기 바로 직전인 i를 넣어주게 된다.
그리고 사라짐
->temp로 다시 돌아와 마저 실행)
t.i=i;
i=10번지 가 됨
heap i=stack i // i][1000
->temp사라지고
main으로 ->println
->사라지고 닫는중괄호 만나서 다지워지고 끝
//지역변수는 만들어 지고 지워지고 반복

[t][10번지 주소]
(main메소드 에있으니까 main frame)
[i][0]->
[i][1000]
method(static변수
stack(local변수
heap
(instance변수
JVM

 

class Test{
 int i ;
 public void temp(int i){
    system.out.println(i);//1000
    this.i=i;//인스턴스 변수를 부르는? t로 대치가 된다
}
public static void main(String[] args){   
    Test t = new Test();
    t.temp(1000);
    s.o.p(t.i);//0
}

  • this는 method를 호출하는 객체의 주소로 변경되는 keyword
  • <static에서는 쓸수 없다.



*String
  • 기본형 데이터형과 참조형 데이터형을 가지고 있는데,변수에 값/변수에 주소 (값을 저장하기위해 예약해둔 공간의 이름)
  • 기본형 데이터형 : 값자체 저장, 정수 : byte,short,int,long/문자 : char / 실수 : float,double / 불린 : boolean
    • stack영역에 [i][10]
  • 참조형 데이터형 : 주소 저장 / class, 문자열, 배열 / (class: 참조형 데이터형이며, 사용자정의 데이터형) 보통 heap의 주소를 저장하는데 new가 생성해줌.
    • 상수는 리터널에 저장하고 i에 저장되었다면
    • test t= new Test(); 로 heap의 주소가 담김 =>new 를 사용하여야 함 <<객체화>>
    • 클래스는 안에 변수와 메소드를 갖는데, 변수는 인스턴스 변수 스테틱변수와 메소드는 생성자, 인스턴스 메소드와, 스테틱 메소드를 갖는다. method= 일 <method도 잘 보아야 , 생성자도 잘 보고~~


*문자열
  • "로 묶여 있는 여러 글자들
  • 문자열은 문자열 저장소라는 literal에 생성 <<절대 같은 문자열이 생성 되지 않는다.
  • 같은 문자열은 하나만 생성되고, 그 시작 주소를 사용하게 된다.
  • 문자열로 저장하고 사용하기위한 class로 java.lang package에 String 제공한다.
  • String class에서 제공하는 모든 method를 사용할수 있다.
  • <문자열과 String는 다르다. String는 class 별명을 붙여 쓰기 편하게 만든것/
  • <가독성 향상하기 위함..
    • ex)
    • String address = "서울시 강남구"
    • class               !=   String
    • int와 정수상수10이 다른것처럼.
*String class
  • 참조형 데이터형
  • 문자열 저장소에 주소를 저장할 수 있는 데이터 형
  • 기본형 형식과 참조형 형식 2가지로 사용 가능.
  • 기본형 형식 사용) (new 쓰지 않는다.)
    • String str = "ABC";
    • //<String은 제일 속도가 느린 클래스
  • 참조형 형식 사용) (new 사용)
    • String str = new String("ABC");
  • <C에서는 연산자 오버로딩으로 가능하나 java는 안됨.
  • <공통으로는 문자열 저장소의 주소를 저장했다는게 공통점.
  • <String에서 제공하는 method는 다쓸수 있다.
  • == vs equals)
  • 객체 ==)
    • <값이 같은지 
    • <주소, 번지가 같은지 물어본다. (주소는 유일~!~!)
    • ==을 사용하면 주소가 같은지 비교~!~!
    • String s= "ABC";//기본 형식
    • if (s=="ABC"){
      }else{
    • }//s=="ABC" 주소가 같다.

    • String s=new String("ABC");

    • if (s=="ABC"){
      }else{
    • }//다르다.
    • //같은 문자열일지라도 ==비교 불가
    • stack      heap     문자열 저장소로 나누어 저장.
  • <기본형으로 만들어 졌는데,,문자열이 어디서 시작했는지 보기 어렵. 100프로 
  • 기본형 형식으로 만들면 같은 문자열 비교가 가능하지만 참조형 형식으로 만들면 heap과 stack의 주소를 비교하게 되므로 비교를 할 수 없음
  • String str = new String();
  • 면 str은 지역변수로 Stack에 만들어지고 new 니까 heap에 만들어짐. heap은 주소인 10을 갖고 stack의 str은 heap의 주소인100을 가짐.
  • =>기본형 형식으로 만들면 같은 문자열인지 비교 가능하지만 참조형 혁식으로 만들면 같은 문자열인지 비교할 수 없다.
  • equals method(overloading의 대표적메소드)를 사용하면 객체내의 주소를 비교하는 기능을 수행함으로 기본형이나 참조형 형식모두 같은지에 대한 비교를 수행 할 수 있다.
 
반응형

'국비지원학원 > Java' 카테고리의 다른 글

29일차  (0) 2018.11.30
28일차  (0) 2018.11.28
26일차  (0) 2018.11.25
25일차  (0) 2018.11.23
24일차  (0) 2018.11.23