- 클래스의 구조

  • 필드
    • 객체 데이터, 상태 저장하는 변수
    • 멤버 변수 
    • Goods.java
    •  
    • package com.javaex.oop.goods.v1; public class Goods { // 필드 String name; int price; }​
    • GoodsApp.java
    • package com.javaex.oop.goods.v1;
      
      public class GoodsApp{
      	public static void main(String [] args) {
      		Goods camera = new Goods();
      		camera.name = "nikon";
      		camera.price = 400000;
      		
      		Goods smartphone = new Goods();
      		smartphone.name = "iPhone 13";
      		smartphone.price = 1000000;
      		
      		System.out.println("이름 : " + camera.name + "\n가격 : " + camera.price);
      		System.out.println("이름 : " + smartphone.name + "\n가격 : " + smartphone.price);
      	}
      }
      결과 
      이름 : nikon
      가격 : 400000
      이름 : iPhone 13
      가격 : 1000000
  • 생성자
    • 객체 생성시 수행되는
    • 목적 : 객체 초기화 -> heap 객체 생성 -> 조소값 받기
  • 메소드

 

- 접근 제한자

public > protected > default > private

  • public
  • protected
  • default
    • 아무것도 안 적으면 default
  • private
    • 자신의 클래스 안에만 사용 가능

 

- 메서드

  • 매개변수
    • 메소드 호출에서 들어가는 구체적인 값 : 인자(Argument)
  • 반환타입
    • int일 때, return 비워두면 안 된다.
  • 메서드 이름
    • 메서드 명은 기능을 알기 쉽게 작성해야함 (ex. a, b, c, -> 무슨 기능인지 알 수 없음)
    • package com.javaex.oop.methods;
      
      public class MethodsEx {
      	public static void main(String[] args) {
      		//입력 x, 출력 x
      		printMessage();
      		
      		//입력 o, 출력 o
      		double result = getSum(4,5);
      		System.out.println("4 + 5 = "+ result);
      		
      		//입력 x, 출력 o
      		//입력 o, 출력 x
      		
      		printTotal("합계", 1,2,3,4,5,6,7,8,9);
      	}
      	//고정인수, 가변 인수
      	private static void printTotal(String message, double ... values) {
      		System.out.println(message+ " : " + getTotal(values));
      	}
      	
      	//가변 인수를 이용한 다수 인수 전달
      	private static double getTotalVar(double ... values) {
      		return getTotal(values);
      	}
      	
      	private static double getTotal(double[] values) {
      		double total = 0;
      		
      		for(double value: values) {
      			total += value;
      		}
      		return total;
      	}
      }

 

- 가변 인수

  • 매개 변수의 개수를 알 수 없을 때 사용
  • 고정인수, 가변인수 같이 올 때 -> ① 고정인수, ②가변인수 (순서 중요)
    public class MethodsEx {
    	public static void main(String[] args) {		
    		printTotal("합계", 1,2,3,4,5,6,7,8,9);
    	}
    	//고정인수, 가변 인수
    	private static void printTotal(String message, double ... values) {
    		System.out.println(message+ " : " + getTotal(values));
    	}
    	
    	private static double getTotal(double[] values) {
    		double total = 0;
    		
    		for(double value: values) {
    			total += value;
    		}
    		return total;
    	}
    }​

- Getter, Setter

  • 객체 외부에서 직접적으로 접근하는 것을 막음

Goods.java

  • package v2;
    
    public class Goods {
    	//	필드
    	private String name;
    	private int price;
    	
    	//외부 접근 방식 노출
    	//	getter/setter
    	//	getter : 데이터 참조하기 위함
    	public String getName() {
    		return name;
    	}
    	
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	public int getPrice() {
    		return price;
    	}
    	
    	public void showInfo() {
    		System.out.println("상품이름 : " + name);
    		System.out.println("가격 : "+ price);
    	}
    }
     Goods.App.java
    package v2;
    
    public class GoodsApp{
    	public static void main(String [] args) {
    		Goods camera = new Goods();
    		camera.setName("nikon");
    		camera.setPrice(400000);
    		
    		Goods smartphone = new Goods();
    		smartphone.setName("iPhone 13");
    		smartphone.setPrice(1000000);
    		
    //		System.out.println("이름 : " + camera.getName() + "\n가격 : " + camera.getPrice());
    		camera.showInfo();
    //		System.out.println("이름 : " + smartphone.getName() + "\n가격 : " + smartphone.getPrice());
    		smartphone.showInfo();
           	}
    }​

생성자

  • 생성자를 실행시키지 않고 클래스로부터 객체 만들 수 없다.
  • void 안 씀
  • setter가 없으면 readOnly

 

this

  • 현재 사용중인 instance 자신
  • this() : 현재 인스턴스에 있는 다른 생성자 호출
    	public Goods(String name) {
    		this.name = name;
    	}
    	
    	//	생성자 2.
    	public Goods(String name, int price) {
    		this(name);	//	다른 생성자 호출
    		this.price = price;
    	}​

 

메소드 오버로딩

  • 하나의 클래스에 같은 이름의 메소드 존재 가능

 

static, instance, local

  • static :
    • 클래스 영역
    • 해당 클래스로 만들어진 인스턴스
    • new 아니라도 접근 가능
    • static내에서는 static 멤버만 접근 가능 
      • static -> instance 접근 (x)
        public class StaticEx {
        	public static int refCount;	//	 클래스(static) 멤버
        	public static String classVar;	//	클래스 멤버
        	public String instanceVar;	//	인스턴스 멤버
        	
        	// 	static 블록으로 static 영역의 초기화
        	static {
        		refCount = 0;
        		classVar = "static Member";
        		//instanceVar = "Instance Member";	-> 에러
        		// 중요 : sataic 영역에서는 static 만 접근 가능
        	}
        
        }​
  • instance
    • 클래스 영역
    • new 키워드로 인스턴스 사용
    • 인스턴스 내에서 사용
    • instance -> static영역 접근 가능
      public class StaticEx {
      	public static int refCount;	//	 클래스(static) 멤버
      	public static String classVar;	//	클래스 멤버
      	public String instanceVar;	//	인스턴스 멤버
      	
      	// 	static 블록으로 static 영역의 초기화
      	static {
      		refCount = 0;
      		classVar = "static Member";
      		//instanceVar = "Instance Member";	-> 에러
      		// 중요 : sataic 영역에서는 static 만 접근 가능
      	}
      	
      	StaticEx(){
      		//	참조 카운트 증가
      		// 	인스턴스 멤버 -> sataic 멤버 접근 가능
      		refCount++;
      		System.out.println("인스턴스 갯수 : " + refCount);
      	}
      
      }​

    • StaticEx.java
      package com.javaex.oop.staticmember;
      
      public class StaticEx {
      	public static int refCount;	//	 클래스(static) 멤버
      	public static String classVar;	//	클래스 멤버
      	public String instanceVar;	//	인스턴스 멤버
      	
      	// 	static 블록으로 static 영역의 초기화
      	static {
      		refCount = 0;
      		classVar = "static Member";
      		//instanceVar = "Instance Member";	-> 에러
      		// 중요 : sataic 영역에서는 static 만 접근 가능
      		System.out.println("static Block");
      	}
      	
      	StaticEx(){
      		//	참조 카운트 증가
      		// 	인스턴스 멤버 -> sataic 멤버 접근 가능
      		refCount++;
      		System.out.println("인스턴스 갯수 : " + refCount);
      		System.out.println("생성자 호출 : 인스턴스 생성");
      	}
      
      }​
      StaticApp.java
    • package com.javaex.oop.staticmember;
      
      public class StaticApp {
      
      	public static void main(String[] args) {
      		StaticEx s1 = new StaticEx();
      		//static 멤버는 new 없이 접근 가능
      		System.out.println("RefCount"+ StaticEx.refCount);
      		
      		StaticEx s2 = new StaticEx();
      		System.out.println("RefCount"+ StaticEx.refCount);
      	}
      }
      • static영역 먼저 실행
      • StaticApp의 생성자 실행
      • StaticApp mian의 프린트 실행
    • 객체 초기화 : null 로 설정해주면 됨 (heap 메모리에 남아있지만, GTC를 통해 없어짐)
      // 소멸자
      	@Override
      	protected void finalize() throws Throwable{
      		refCount--;
      		System.out.println("소멸자 호출");
      		super.finalize();
      	}​
      	// 	주의 : 가비지 컬렉터를 직접 호출하지 않는다. 
      		System.gc();
      		try {
      			Thread.sleep(3000);//3초간  대기
      		}catch(Exception e) {​
      가비지 수집기 : 사용하지 않은 메모리를 자동적으로 회수하는 서비스GC클래스 : 가비지 수집기 제어
  • local 영역
    • 메서드 영역
    • 메소드 내에서 사용
    • 벗어나면 찾을 수 없음

 

singleton (static의 활용)

  • 단 하나의 인스턴스만 유지
    • 함부러 생성자 호출 불가능하게 -> 생성자를 private로
    • 단 한번만 수행 -> static으로 객체 만들기

Singleton.java

package com.javaex.oop.staticmember;

//	목표 : 어떤 상황에서든 단 한개의 인스턴스만 유지
public class Singleton {
	//	생성자
	private Singleton() {
		
	}
}​

SingletonApp.java

 

package com.javaex.oop.staticmember;

public class SingletonApp {

	public static void main(String[] args) {
		Singleton s1 = new Singleton();	//	생성 불가
	}

}

 

  •  
  •  
  • static 블록에서 생성자 호출
    • Singleton.java
package com.javaex.oop.staticmember;

//	목표 : 어떤 상황에서든 단 한개의 인스턴스만 유지
public class Singleton {

	//	static 블록에서 생성자를 호출
	private static Singleton instance  =  new Singleton();
	
	//	생성자
	private Singleton(){
		
	}

	public static Singleton getInstance() {
		return instance;
	}
}​
  • SingletonApp.java
    package com.javaex.oop.staticmember;
    
    public class SingletonApp {
    
    	public static void main(String[] args) {
    //		private static s1 = new Singleton();	//	생성 불가
    		Singleton s1 = Singleton.getInstance();
    		Singleton s2 = Singleton.getInstance();
    		
    		//객체 주소가 같으면 같은 객체다.
    		System.out.println("s1, s2 같은 객체? " + (s1 == s2));
    	}
    
    }​

 

상속 ( Inheritance )

  • 클래스간 계층적 분리 및 관리 가능
  • 중복 상속을 제거한다. (오직 하나만 상속한다.)
    • ex) 엄마, 아빠 클래스 중 뭐 쓸까 고민,,하는거 안 해도 됨
  • 가급적으로는 상속 배제하도록
    • 상속의 깊이이가 길어지면 유지보수가 어려워진다. 
  • 최상위 클래스 : java.lang.Object
  • 자식 생성자에서 특별한 지시가 없으면 부모 클래스의 기본 생성자가 선택됨
    • 부모의 특정 생성자 사용시에는 명시 해줘야한다. -> super(x,y);
  • 부모의 필드나 메서드에 접근시에는 super 키워드 사용

 

메서드 오버라이딩 (Method Overriding)

  • 물려받은 것을 사용하지 않고, 다른 기능 사용하는 것
    • 같은 이름, 같은 리턴타입, 같은 시그너쳐
    • 부모 메서드 무시
  • @Overriding ( 일종의 지시자 )
    • 매서드 앞에 명시 -> 부모에게 메서드가 있는가?
      • 진짜로 오버라이딩 한 건가?
      • 컴파일러에게 맡김 
      • 시그너쳐 위반 했는지 안 했는지 
  • 객체를 참조하고자 할 때
    • 자식 객체를 부모 타입으로 참조할 수 있다. 
    • 부모 참조
      • person p1 = new Student( );
        • 참조 타입(person) 설계도 내의 메서드만 호출 가능
        • p1.getName( ) (O)
        • p1.getSchoolName( ) (X) -> person에 없음
        • p1.showInfo( ) -> 오브라이딩 된 자식 클래스의 메소드
    • 자기자신 타입으로 참조
      • Studnet s1 = new Student( );
        • s1.getName( ) (O)
        • s1.getSchoolName( )
        • s1.showInfo( ) -> 자기자신의 오버라이딩 된 메소드
    • 다형성의 일부
      • ex) 주소록을 만들 때, 
        • Student[] s = new Studnet[3];
        • s[0] = new Student( );
        • s[1] = new Student( );
        • s[2] = new Person( ); -> 안 됨
      • ex2 ) 주소록
        • Person p[] = new Person[3];
        • p[0] = new Student( );
        • p[1] = new Student( );
        • p[2] = new Person( ); (O)
    • 부모 타입으로 자식객체를 참고할 수 있다.
    • override해도 부모의 메소드 사라지지 않는다.
    • point.v4패키지
      • Point.java
        package point.v4;
        
        //	v4. 상속
        public class Point {
        	protected int x;
        	protected int y;
        	
        	//	기본 생성자 : 매개 변수가 없는
        //	public Point() {
        //		
        //	}
        //	
        	//	전체 필드 초기화 생성자
        	public Point(int x, int y) {
        		this.x = x;
        		this.y = y;
        	}
        	
        	public int getX() {
        		return x;
        	}
        	public void setX(int x) {
        		this.x = x;
        	}
        	public int getY() {
        		return y;
        	}
        	public void setY(int y) {
        		this.y = y;
        	}
        	public void draw() {
        		System.out.printf("점[x=%d, y=%d]을 그렸습니다.\n",x,y);
        	}
        	
        	//메서드 오버로딩
        	//매개변수 타입, 갯수, 순서가 같은 이름의 메서드 
        	public void draw(boolean bDraw) {
        		String message = String.format("점[x=%d, y=%d]을 ", x, y);
        		if(bDraw) {	//	true라면
        			message += "그렸습니다.";
        		}else {
        			message += "지웠습니다.";
        		}
        		System.out.println(message);
        	}
        }​
      • ColorPoint.java
        package point.v4;
        
        //	상속
        public class ColorPoint extends Point{
        	private String color;
        	
        	//	생성자
        	public ColorPoint(int x, int y, String color) {
        		super(x,y);
        		this.color = color;
        	}
        	
        	@Override	//	컴파일러에게 이 메서드가 오버라이딩한 메서드인지 확인
        	public void draw(boolean bDraw) {
        		//부모로부터 물려 받은 메서드를 덮어 쓰기
        		String message = String.format("색깔점[x = %d, y = %d, color = %s]을 ",
        				x, y, color);
        		message += bDraw ? "그렸습니다.":"지웠습니다";
        		
        		System.out.println(message);
        		
        		//부모의 메서드 호추하려면
        		super.draw(bDraw);
        	}
        }​
      • PointApp.java
        package point.v4;
        
        public class PointApp {
        	public static void main(String[] args) {
        		Point p = new Point(4,4);
        		
        		p.setX(10);
        		p.setY(20);
        		p.draw();
        		p.draw(true);
        		p.draw(false);
        		
        
        		Point p2 = new Point(60,40);
        		p2.draw();
        		p2.draw(true);
        		p2.draw(false);
        		
        		ColorPoint cp1 = new ColorPoint(10,20,"RED");
        		cp1.draw(true);
        
        		//	다형성 : 부모타입으로 자식객체 참조
        		Point cp2 = new ColorPoint(30, 40,"RED");
        		cp1.draw(true);
        	}
        }​
    • 위의 같은 경우에서 point.java의 매개변수 없는 생성자와, ColorPoint의 매개변수 없는 생성자를 만들고 실행시키면, point 생성자 먼저 실행되고, ColorPoint 생성자가 실행된다. 
    • 그렇지만, Point의 생성자를 만들지 않고 ColorPoint의 생성자를 만들면 오류생긴다. 

 

업캐스팅, 다운 캐스팅

특정 객체 다운 캐스팅 할 때, instanceof로 확인해라.

 

casting 패키지

Animal.java

package com.javaes.oop.casting;

public class Animal {
	protected String name;
	
	//	생성자
	public Animal(String name) {
		this.name = name;
	}
	
	public void eat() {
		System.out.println(name + " is eating");
	}
	
	public void walk() {
		System.out.println(name + " is walking");
	}
}

Dog.java

package com.javaes.oop.casting;

public class Dog extends Animal{
	//생성자 Animal 없어서 오류났음 -> 생성자 ㅏ만들어줘야 함
	public Dog(String name) {
		//부모생성자의 일부 호출해줘야한다. 
		super(name);
	}
	
	public void bark() {
		System.out.println(name + ": 멍멍!");
	}
}

Cat.java

package com.javaes.oop.casting;

public class Cat extends Animal{
	public Cat(String name) {
		super(name);
	}
	
	public void meow() {
		System.out.println(name + ": 야옹!");
	}
}

AnimalApp.java

package com.javaes.oop.casting;

public class AnimalApp {
	public static void main(String[] argv) {
		//	업 캐스팅, 다운 캐스팅
		Dog dog1 = new Dog("스누피");
		dog1.eat();
		dog1.walk();
		dog1.bark();
		
		//	업 캐스팅 : 참조 자료형에 있는 설계된 멤버에만 접근 가능
		Animal dog2 = new Dog("아지");
		dog2.eat();
		dog2.walk();
//		dog.bark();	//오류남
		
		//	다운 캐스팅
		//	animal -> dog로
		((Dog)dog2).bark();	//	일시적으로 변환
		
		
		//	업 캐스팅
		Animal cat1 = new Cat("야옹이");
		cat1.eat();
		cat1.walk();
//		((Dog)cat1).bark();//	오류남,,-> cat과 Dog 서로 캐스팅 안 됨
		
		if(cat1 instanceof Dog) {	//cat1이 Dog의 인스턴스인가?
			((Dog)cat1).bark();
		}else if(cat1 instanceof Cat){	// 	cat1이 Cat의 인스턴스?
			((Cat)cat1).meow();
		}
		
//		Dog[] pets = new Dog[3];
		Animal[] pets = new Animal[3];
		pets[0] = dog1;
		pets[1] = (Dog)dog2;
		pets[2] = new Dog("멍멍이");
//		pets[3] = new Cat("아즈라엘");// 오류남
		
		for(Animal pet : pets) {
			pet.eat();
			pet.walk();
			
			if(pet instanceof Dog) {
				((Dog)pet).bark();
			}else if(pet instanceof Cat)
				((Cat)pet).meow();
			
		}
		
	}
}
  • 다운 캐스팅 : 자료형에 있는 설계된 멤버만 접근 가능 
    • Animal dog2 = new Dog()
    • 이면, Dog에만 있는 dark()는 오류가 난다.
  • 같은 부모를 상속하는 자녀 사이에 캐스팅이 안 된다.
    • Cat과 Dog는 서로 캐스팅이 안 됨
  • Dog[] pets = new Dog[3];을 한 뒤,
  • pets[3] = new Cat() -> 오류난다. 
    • Dog객체에 Cat을 넣었기 때문.

 

 

 

'study > JAVA 전문가' 카테고리의 다른 글

인터페이스  (0) 2021.12.07
예외  (0) 2021.12.07
추상 클래스  (0) 2021.12.07
[모의 필기테스트] 오답노트 & 정리  (0) 2021.12.07
[DAY+2]Java Programming  (0) 2021.12.03

+ Recent posts