[JAVA] 객체지향(생성자/상속/Import)

Updated:

Categories:

Tags: ,

📌 개인적인 공간으로 공부를 기록하고 복습하기 위해 사용하는 블로그입니다.
정확하지 않은 정보가 있을 수 있으니 참고바랍니다 :😸
[틀린 내용은 댓글로 남겨주시면 복받으실거에요]

생성자

  1. 생성자란?
    1. 인스턴스가 생성될 때마다 호출되는 ‘인스턴스 초기화 메서드’
      1. 인스턴스 초기화 - 인스턴스 변수에 적절한 값을 저장하는 것.
    2. 인스턴스 변수의초기화 또는 인스턴스 생성시 수행할 작업에 사용
    3. 몇가지 조건을 제외하고는 메서드와 같다.
    4. 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다.

      1
      2
      3
      4
      5
      6
      7
      
       Card c= new Card();
              
       1. 연산자 new에 의해서 메모리(heap) Card클래스의 인스턴스가 생성된다
       	//연산자 new에 의해서 인스턴스가 생성되는 것이지 생성자가 인스턴스 생성하는것이 아님.
       2. **생성자 Card()** 호출되어 수행된다. 
       3. 연산자 new의 결과로, 생성된 Card 인스턴스 주소가 반환되어 **참조변수 c** 저장된다.
              
      
  2. 생성자의 조건
    1. 생성자의 이름은 클래스의 이름과 같아야 함.
    2. 생성자는 return 값이 없다. but void를 쓰지 않음.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
     클래스 이름 ( 타입변수명, 타입변수명,....){
     //인스턴스 생성시 수행될 코드
     //주로 인스턴스 변수의 초기화 코드를적는다.
        
     ex)
     class Card{
     ...
     	Card(){//매개 변수가 없는 생성자.
     	//인스턴스 초기화 작업
        	
     	Card(String Kind, int number) {//매개변수가 있는 생성자
     	//인스턴스 초기화 작업
        
    
  3. 기본 생성자
    1. 기본생성자란?

      1
      2
      
       클래스이름(){}
       Card(){} //컴파일러에 의해 추가된 Card의 기본 생성자. 내용이 없음.
      
      1. 매개변수가 없는 생성자
      2. 클래스에 생성자가 하나도 없으면 컴파일러가 기본 생성자를 추가한다.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        
         class Data1{
         		int value;                  //생성자 정의 없음.
         }
         class Data2{
         		int value;
         		Data2(int x){                          //생성자 1개 정의되어 있음,
         				value=x;
         		}
         }
                    
         class ConstructorTest{
         	public static void main (String[]agrs){
         			Data1 d1= new Data();
         			Data2 d2 = new Data2();  //compile error 발생!!
                    			
         	}
         }
                    
         왜냐하면 Data1에서는 정의 되어 있는 생성자가 하나도 없어서
         컴파일러가 하기와 같이 자동적으로 기본생성자를 추가해줌
         class Data1 {
         	int value;
         	Data1(){} //기본생성자
         }
                    
         ---
         에러가 발생하지 않도록 하기 위해서는
         Data2의 인스턴스를 생성할  생성자 Data2(int x) 사용
         또는, 클래스 Data2에 생성자 Data2() 추가로 정의해 주어야 한다.
        
      3. 생성자가 하나라도 있으면 추가하지 않음.
      4. == 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다.
    2. 매개변수가 있는 생성자

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
       class Car{
       	String color;    //색상
       	String gearType;  //변속기 종류-auto, manual
       	int door;   //문의 개수
              	
       	Car(){}                //생성자
       	Car(String c, String g, int d){       //생성자
       			color = c;
       			gearType=g;
       			door =d ;
      

      ㄱ. 인스턴스 생성 후 인스턴스 값을 변경

      1
      2
      3
      4
      
       Car c = new Car();
       c.color = "white";
       c.gearType = "auto";
       c.door  = 4;
      

      ㄴ. 매개변수를 갖는 생성자

      1
      
       Car c = new Car("white","auto",4);
      

      ㄱ와 ㄴ은 같은 역할을 하는 코드지만 ㄴ이 더 간결하고 직관적.

  4. this() - 생성자, 같은 클래스에서 다른 생성자 호출 하기
    1. this()생성자 : 같은 클래스의 다른 생성자를 호출할 때 사용, 다른 생성자의 호출은 생성자의 첫 문장에서만 가능.

    b. 기존 코드

    1
    2
    3
    4
    5
    6
    
     Car() {
     	color = "white";
     	gearType = "auto";
     	door  = 4;
     	//지역변수
     }
    

    c. this 사용 >코드의 재사용성을 높인 코드

    1
    2
    3
    4
    
     Car(){
     		this("white","auto",4);
        
     }
    

    d. this는 인스턴스 자신을 가리키는 참조변수, 모든 인스턴스 변수에 숨겨진 채로 존재

    1. this(), this(매개변수)와는 완전히 다름.

변수의 초기화

  1. 변수의 초기화
    1. 변수를 선언하고 처음으로 값을 저장하는 것.
    2. 멤버변수(인스턴스변수, 클래스변수)와 배열은 각 타입의 기본 값으로 자동 초기화되므로 초기화를 생략 할 수 있다.
    3. 지역변수는 사용 전에 꼭!!!!!!! 초기화를 해주어야 한다
  2. 멤버 변수의 초기화
    1. 명시적 초기화-변수 선언과 동시에 초기화

      1
      2
      3
      4
      5
      6
      
       class Car {
       			int door = 4;          //기본형 변수의 초기화
       	Engine e = new Engine();   //참조형 변수의 초기화
              	
       	//....
       }
      
    2. 생성자

      1
      2
      3
      4
      
       Car(String color, String gearType, int door){
       	this.color = color;
       	this.gearType = gearType;
       	this.doo r= door;
      
    3. 초기화 블럭

      인스턴스 초기화 블럭: { } /클래스 초기화 블럭: static{ }

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
        class  InitTest{
       	 static int cv=1; //명시적 초기화
       	 int iv =1;       //명시적 초기화
              	 
       	 static{cv=2;}  //클래스 초기화 블럭
       		{ iv=2; }      // 인스턴스 초기화 블럭
              		
       	 InitTest(){     //생성자
       		 iv=3; 
       		}
       	}       
      
      1. 인스턴스 초기화 블럭
        • 생성자에서 공통적으로 수행되는 작업에 사용되며 인스턴스가 생성될때마다(생성자보다 먼저)실행
        • 생성자를 주로 이용하므로 잘 사용되지 않는다.
      2. 클래스 초기화 블럭
        • 클래스변수의 복잡한 초기화에 사용되며 클래스가 로딩될때 실행됨
        • 단 1번 실행됨
    4. 초기화 시기와 순서

      1. 클래스 변수 초기화 시점 : 클래스가 처음 로딩될때 한번
      2. 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다

상속

  1. 상속의 정의와 장점
    1. 상속이란 ?
      1. 기존의 클래스를 재사용해서 새로운 클래스를 작성
      2. 두 클래스를 조상과 자손으로 관계를 맺어주는 것
      3. 자손은 조상의 모든 멤버를 상속 받음 (생성자, 초기화블럭 제외)
      4. 자손의 멤버개수는 조상보다 적을 수 없다.
      5. class 자손클래스 extends 조상클래스{ }
    2. 상속관계
      1. 공통부분은 조상에서 관리, 개별부분은 자손에서 관리
      2. 조상의 변경은 자손에 영향을 미치지만
      3. 자손의 변경은 조상에 아무런 영향을 미치지 않는다.
  2. 클래스간의 관계
    1. 포함관계
      1. 포함이란? 한 클래스의 멤버변수로 다른 클래스를 선언하는 것
      2. 작은 단위의 클래스를 먼저 만들고 이들을 조합해서 하나의 클래스로 만듬 - 재사용성 증가

        1
        2
        3
        4
        5
        
         class Circle{
         	 int x;
         	 int y;
         	 int z;
         }
        
        • 위 Cricle은 아래 두 클래스와 같이 변경할 수 있음
        1
        2
        3
        4
        5
        6
        7
        8
        
         class Circle{
         	point c = new Point();
         	int r;
         }
         class Point{
         	int x;
         	int y;
         }
        
    2. 클래스간의 관계 결정하기 : 상속 vs 포함
      1. 가능한 한 많은 관계를 맺어주어 재사용성을 높이고 관리하기 쉽게 한다.
      2. 대부분 포함관계
      3. 기존의 클래스에 기능이 추가된 새로운 클래스를 만들 때 상속관계를 맺어줌
      4. 예제1

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        
         import javax.smartcardio.Card;
                    
         public class Deck{
             final int CARD_NUM=52; //카드의 개수
             Card c[] =new Card[CARD_NUM]; //
             Deck(){ //Deck의 카드를 초기화
                 int i =0;
                 for(int k=Card.KIND_MAX;k--){
                     for(int n=1; n<Card.NUM_MAX+1;n++{
                         c[i++]=new Card(k,n);
                     }
                 }
             }
                    
             Card pick(int index){ //지정된 위치에 있는 카드 하나 선택
                 return c[index%CARD_NUM];
             }
             Card pick(){  //Deck에서 카드 하나 선택
                 int index=(int)(Math.random()*CARD_NUM);
                 return pick(index);
             }
                    
             void shuffle(){     //카드의 순서를 섞는다
                 for(int n=0; n<1000; n++){
                     int i = (int)(Math.random()*CARD_NUM);
                     Card temp=c[0];
                     c[0]=c[i];
                     c[i]=temp;
                 }
             }
         }
                    
         public static void main(String[] args) {
                    
                 Deck d = new Deck();
                 Card c = d.pick();
                 d.shuffle();
                 Card c2 = d.pick(55);
             }
        
  3. Java는 단일상속만 허용 - 하나만 상속가능. 나머지는 포함관계

    1
    
     class TVCR extends TV, VCR {...} //불가능
    
  4. Object class - 모든 클래스의 최고 조상
    1. 조상이 없는 클래스는 자동적으로 object class를 상속 받음.
    2. 상속계층도의 최상위는 Object 클래스가 위치
    3. 모든 클래스는 Object 클래스에 정의된 11개의 메서드를 상속받음.
      1. toString(), equals(Object obj), hashCode(),…

오버라이딩

  1. 오버라이딩이란?
    1. 조상클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것을 오버라이딩
  2. 오버라이딩 조건
    1. 선언부가 같아야함(이름, 매개변수, 리턴타입)
    2. 접근제어자를 좁은 범위로 변경할 수 없다.
      1. 조상의 메서드가 protected라면 범위가 같거나 넓은 protected나 public으로만 변경할 수 있다.
    3. 조상클래스의 메서드보다 많은 수의 예외를 선언할 수 있다.
    4. static 메서드를 인스턴스 메서드로 또는 인스턴스 메서드를 static메서드로 변경할 수는 없음.
  3. 오버로딩 vs 오버라이딩

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     class Parent {
     		void paraentMethod(){}
     		}
        		
     	class Child extends Parent{
     		void parentMethod(){}.     //오버라이딩
     		void parentMethod(int i){}  //오버로딩, 매개변수가 다름
        		
     		void childMethod(){}
     		void childMehtod(int i){}  //오버로딩
      		void childMethod(){}.      //에러, 중복 정의
    
    1. 오버로딩 :기존에 없는 새로운 메서드를 정의 (new)
    2. 오버라이딩 : 상속받은 메서드의 내용을 변경하는 것.(change,modify)

super

  1. this
    1. 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어있음
    2. 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재
  2. super
    1. this 와 같음, 조상의 멤버와 자신의 멤버를 구별하는데 사용
    2. 예제 1)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     class Parent{
     	int x =10;
     	}
     	class Child extends Parent{
     	int x=20;
     	void method(){
     	System.out.println("x="+x);
     	System.out.println("this.x="this.x);
     	System.out.println("super.x="super.x);
     	}
     }
        
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     class Parent{
     	int x =10;
     	}
     	class child extends Parent{
     	void method(){
     	System.out.println("x="+x); //x=10
     	System.out.println("this.x="this.x); // 중복변수 없으므로 
     	System.out.println("super.x="super.x);//super.x=10
     	}
     }
    

    중복 변수 없으므로 super 사용 필요 없음, this 사용하는 걸로 충분

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
     class Point{
     int x;
     int y;
     String getLocation(){
     		return"x:"+x+",y:"+y;
     		}
     	}
        	
     	class Point3D extends Point{
     	int z;
     	String getLocation(){      //오버라이딩
     	 return super.getLocation()=",z:"+z; //조상의 메서드 호출
     	 }
     }
    
  3. super()
    1. 조상의 생성자
      1. 자손클래스가 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 합쳐진 하나의 인스턴스가 생성됨 ⇒ 조상의 멤버들도 초기화 되어야 하기 때문에
      2. 조상의 멤버들도 초기화되어야 하기 때문에 자손의 생성자의 첫 문장에서 조상의 생성자를 호출해야한다.
      3. Object클래스를 제외한 모든 클래스의 생성자 첫 줄에는 생성자(같은 클래스의 다른 생성자 또는 조상의 생성자)를 호출해야한다. 그렇지않으면 컴파일러가 자동적으로 ‘super();’를 생성자의 첫줄에 삽입함.

package와 import

패키지

  1. 서로 관련된 클래스와 인터페이스의 묶음
  2. 클래스가 물리적으로 클래스파일(*.class)인 것처럼, 패기지는 물리적으로 폴더에 해당
  3. 패키지는 서브패키지를 가질 수 있으며 ‘.’으로 구분
  4. 클래스의 실제이름 (full name)은 패키지명이 포함된 것이다.
    1. String 클래스의 full name은 java.lang.Stirng
  5. rt.jar는 Java API의 기본 클래스들을 압축한 파일
    1. (JDK설치경로\jre\lib에 위치)
  6. 패키지의 선언
    1. 패키지는 소스파일에 첫번째 문장(주석제외)으로 단 한번 선언한다.
    2. 하나의 소스파일에 둘 이상의 클래스가 포함된 경우 모두 같은 패키지에 속하게 된다.(하나의 소스파일에 단 하나의 public클래스만 허용)
    3. 모든 클래스느 하나의 패키지에 속하며, 패키지가 선언되지 않은 클래스는 자동으로 이름없는 (unnamed)패키지에 속하게 된다.
  7. 클래스패스 설정
    1. 클래스패스는 클래스파일을 찾는 경로. 구분자는 ;
    2. 클래스패스에 패키지가 포함된 폴더나 jar파일을 (*jar)나열한다.
    3. 클래스패스가 없으면 자동적으로 현재폴더가 포함되지만
    4. 클래스패스에 지정할 때는 현재폴더.도 함께 추가해주어야한다.
    5. 클래스패스 자동 포함된 폴더 for 클래스파일(*.class): 수동생성해야함.
      1. JDK설치경로\jre\lib\ext

import문

  1. 사용할 클래스가 속한 패키지를 지정하는데 사용
  2. import문을 사용하면 클래스를 사용할때 패키지를 생략가능
  3. java.lang패키지의 클래스는 import하지 않고도 사용할 수 있음
    1. String,Object,System,Thread… 매우 빈번하게 사용되어 생략할 수 있게 함.
  4. import문의 선언
    1. import문은 패키지문과 클래스 선언의 사이에 선언한다.
    2. 일반적인 소스파일(*java)의 구성은 다음의 순서로 되어있다.
      1. package문
      2. import문
      3. 클래스 선언
    3. import 문 선언 방법 - 여러번 사용 가능
      1. import 패키지명.클래스명;
      2. 또는 import 패키지명.*;
      3. 예제
        1. import문은 컴파일 시에 처리되므로 프로그램 성능에 아무런 영향 미치지 않음.
        2. 이름이 같은 클래스가 속한 두 패키지 import할때는 클래스 앞에 패키지명 붙여줘야한다.




Comment


참고자료 - 자바의 정석




JAVA-Learn 카테고리 내 다른 글 보러가기

Leave a comment