원지의 개발
article thumbnail
728x90

접근제어자: public / protected / default / private
static 클래스 초기화 블럭{} 메서드 멤버변수
final 클래스: 조상이 될 수 없는 제일 마지막 메서드: 오버라이딩x, 재정의x 멤버변수, 지역변수: 상수
abstract 클래스: 추상클래스 선언 메서드: 추상메서드이다  

static (정적 제한자)

  • 변수, 메서드에 적용되는 자바의 키워드 (생성자에는 사용 X)
  • 해당 클래스의 객체 없이도 참조 가능
    static 붙으면 (new를 안 붙여도) 메모리에 알아서 생성해서 만들어줌 → 직접 1개 만들어줌(이건 고정)
  • 인스턴스 변수 = 멤버변수를 안쓸 때 붙음
  • static { } (static 메서드, 정적 초기화자) 안에는 static 변수만 사용, static 메서드만 호출 가능
    즉 static 블록에서 non-static 멤버를 객체 생성 없이 직접 참조할 수 없음
  • static 제한자는 this를 가질 수 없음 (지정된 변수와 메서드를 객체와 무관하게 만들어주기 때문)
  • non-static 메서드로 재정의(Overriding) 될 수 없음
    method override도 static의 개념으로 들어가야함 / 따로 따로 별개다
  • 대표적인 static 메서드는 애플리케이션의 main() 메서드입니다. / 어떤 클래스에 있던지 상관 x

static initializer (정적 초기화자)

  • static에 단순히 블록({ })을 사용한 경우
  • static 변수를 초기화하는 역할, 클래스가 로딩될 때 main() 메서드가 있더라도 그보다 앞서 딱 한 번 실행
  • 일반변수를 사용하지 않고, 범용성있게 사용할 메서드는 static을 붙이면 좋음

 

[암기 필수] static이 갖는 의미

1. static멤버는 객체 생성 없이 클래스명.이름 으로 참조 가능하다

2. static변수는 객체간 값의 공유의 의미

3. static메서드는 같은 static멤버만 참조가능하다. 클래스명.이름 으로 참조


static 변수

  • class에서 값을 공유하는 변수가 됨 ex) 계산기의 pi
    - 객체 1000개를 만들어도 a값은 같음
  • (객체 생성 없이) 클래스 이름만으로 참조가 가능

static 메서드

  • 클래스의 객체 생성 없이도 참조가 가능
  • 주의해야 할 사항
    static 메서드에서는 static 메서드를 바로 사용 가능 (끼리끼리 논다)
    static 메서드 안에서는 non-static(일반) 멤버를 객체 생성 없이 직접 참조할 수 없음
    static 메서드 호출했어도 객체가 생성되었다는 보장이 없으므로 객체 생성없이 일반 멤버 변수 사용 불

static initializer (정적 초기화자) - 쓸일 없음

  • static {
        반드시 한번만 실행되어야 할 로직
    } - 딱 1번 사용

Singleton Design Pattern (싱글톤 패턴) - 수정

자동으로 해 줌

  • 어떤 클래스의 객체는 오직 하나임을 보장, 이 객체에 접근할 수 있는 전역적인 접촉점을 제공하는 패턴
  • 클래스 객체를 유일하게 하나만 생성하여 모든 곳에서 하나의 객체에 접근하게 하여, 전역의 개념으로 객체 사용 가능
  • 객체의 생성을 제한하기 위해 사용 (자바를 이용한 프로그래밍에서 사용됨)


final

  • 클래스, 메서드, 변수에 적용, abstract와 동시에 사용될 수 없음
  • final 클래스: 상속 X = 서브클래스를 가질 수 없음
  • final 메서드: 재정의(overriding) X
  • final 변수: 값을 변경 X
  • 접근제어자 다음에 위치

final 클래스

  • 클래스 선언 시 final을 사용하면 그 클래스는 상속 불가능
  •  자식 클래스를 가질 수 없고, 오직 외부에서 객체 생성을 통해서만 사용 가능
  • 대표 예시 - String 클래스 / 사용자가 임의로 String 클래스를 상속받아 메서드를 재정의하는 것을 방지

final 메서드

  • 자식 클래스에서 부모 클래스의 메서드를 재정의(오버라이딩)하지 못하게 함
  • 클래스에 final 붙지 않는 한 상속은 가능 = 자식 클래스에서 final 메서드의 참조는 가능
  • 자식 클래스에서 반드시 부모의 메서드를 기능의 변경없이 사용하도록 강요할 경우에 final 메서드를 선언

final 변수

  • 값을 할당하면 그 값을 변경할 수 없음
  • 선언시에 초기화 or 생성자를 통하여 초기화해야 함

final class  & final method
final 변수

 

final method


static final (상수) 

  • 상수(constant): 불변의 값을 저장하는 필드
  • 객체마다 저장할 필요가 없는 공용성 有
    여러가지 값으로 초기화될 수 없기 때문에 static과 final 제한자를 동시에 붙여 선언합
  • 상수 이름은 모두 대문자로 작성하는 것이 관례입니다. 연결된 단어라면  (_)로 단어들을 연결
    ex) public static final long VERSION = 1L
 final은 변수의 값이 변하지 않고
 static은 새로운 메모리에 할당하지 않고 한 메모리에 계속 재사용하겠다
(public/private) static final TYPE NAME = VALUE;
TYPE: 변수의 타입
NAME: 보통 대문자와 _로 구성
VALUE: 상수 값

참고로 변수는 final로 선언되면 값을 바꿀수없지만, 객체의 경우 다른 객체를 가리킬수 없는거지 값은 바뀔수 있음

예를 들어

public static final Point ORIGIN = new Point(0,0);

public static void main(String[] args){

    ORIGIN.x = 3;

}

이경우 ORIGIN.x=3은 정상적으로 동작해서 point의 값을 (3,0)이 됨 - 출처: #ashcode


final field


 

abstract (추상)

      ↔ final

abstract 클래스 

  • 메서드들의 이름을 통일한 목적
  • new 키워드 사용 불가 = 객체 못 만듦
  • 상속을 통해서만 자식 클래스로 구체화 = 다형성 사용
  • 일반클래스와 마찬가지로 멤버변수, 생성자, 메서드를 선언
  • new를 사용하여 직접 생성자를 호출할 수는 없지만,
    자식 객체가 생성될 때 super()를 호출하여 추상 클래스 객체를 생성하므로 추상 클래스도 생성자가 반드시 필요

abstract 메서드 = { }가 없는 메서드

  • 반드시 추상 클래스가 있어야 함, 반드시 그 안에서만 선언
  • 자식클래스가 반드시 실행 내용을 채우도록 강요 (= 오버라이딩을 하도록 하는 경우)하고 싶은 메서드가 있을 때 선언
  • 자식클래스에서 반드시 추상메서드를 재정의하여 실행 내용을 작성해야 함

 

abstract가 갖는 의미

1. 굳이 abstract클래스로 설계할 필요는 없다 → 많이 보이지 않는다

2. 많은 클래스는 abstract클래스로 정의 되어있음을 알아둬야 한다 → 인식할 수 있으면 ok

3. 자식 클래스로 생성해서 부모클래스(추상클래스)에 저장하는 점에 익숙해지자

 

예제

day09.abs.good

추상화된 메서드 확인 후 자식클래스에서 완성하기

      main

package day09.abs.good;

public class MainClass {

	public static void main(String[] args) {
		
//		1. 추상클래스는 객체 생성이 안됩니다.
//		   반드시 자식으로 구체화합니다.
		
//		Store s = new SeoulStore(); // 자식으로 생성해서 추상클래스 타입에 저장해도 결과는 똑같음
		Store s = new BusanStore(); // new SeoulStore();
		s.apple();
		s.melon();
		s.orange();
		
		System.out.println(s.getName()); // 상속받은
	}
}

-----------------결과------------------
추상클래스 생성자 호출
부산사과 500원
부산멜론 600원
부산오렌지 700원
호식이네

Quiz13

Shape에 연결된 Circle, Rect 이용하여 추상메서드 완성하고 넓이 구하기

              Shape / 부모클래스 / 추상클래스 + 추상메서드

package quiz13;
public abstract class Shape { // 부모클래스

	private String name;
	
	public Shape(String name) { // 생성자 필수
		this.name = name;
	}
	
	//오버라이딩을 강제화 한다면 추상메서드로 선언
	public abstract double getArea();
	
	//오버라이딩을 강제화 하지않는다면 일반메서드로 선언
	public String getName() {
		return "도형이름:" + name;
	}
}

              Circle / 자식클래스 / 추상메서드 완성하기

package quiz13;
public class Circle extends Shape {
	private static final int PI = 0;
	//원은 생성될 때 이름과, 반지름의 길이를 받도록 처리하고,
	//getArea()는 원의 넓이를 계산하도록 오버라이딩 처리
	//main에서 확인
	private int radius;
	
	public Circle(String name, int radius) {
		super(name);
		this.radius = radius;
	}
	
	public double getArea() {
		return radius * radius * Math.PI; // Math.PI - 파이값
	}
	
}

              Rect / 자식클래스 / 추상메서드 완성하기

package quiz13;
public class Rect extends Shape{
	//사각형은 생성될 때 이름과, 변의 길이를 받도록 처리하고,
	//getArea()는 사각형의 넓이를 계산하도록 오버라이딩 처리
	//main에서 확인
	private int side;
	
	public Rect(String name, int side) {
		super(name);
		this.side = side;
	}
	
	public double getArea() {
		return side * side;
	}
	
}

      main

package quiz13;
public class MainClass {

	public static void main(String[] args) {
		
		Shape s = new Circle("동그라미", 10);
		System.out.println(s.getName()); // 상속
		System.out.println(s.getArea()); // 오버라이딩
		
		Shape s1 = new Rect("네모", 10);
		System.out.println(s1.getName());
		System.out.println(s1.getArea());
	}
}

Quiz14

부모클래스 Unit을 만들고 추상메서드를 선언해라

Unit / 부모클래스 / 추상메서드

  • 멤버변수 정해줄 때 int x = 0; 이렇게 하지 말고, int x만 쓰면 기본값인 0이 저장됨
  • int hp는 자식클래스에 모두 있으나 값이 다르니까 여기에서 매개변수를 넣게 생성하고, this.hp = hp로 저장
    자식클래스에서 꺼낼때는 super() 부모생성자 빌려오는 키워드 사용해서 매개변수 넣어주면 됨
package quiz14;

public abstract class Unit { // 부모클래스

	public int x; // 기본값 = 0
	public int y;
	public int hp;
	
	public Unit() {}
	public Unit(int hp) { // 생성자(각각 다름)
		this.hp = hp;
	}
	
	public abstract void location(); // 추상메서드
	public abstract void move(int x, int y);
	public abstract void stop();
	
}

Marine / 자식클래스 / 추상메서드 완성하기 / 본인의 static변수 가지고 있음

  • attack, armor의 경우 객체마다 같은 값을 갖도록 하려면 static으로 선언해줌
    static area에 위치하게 되며 같은 값을 공유하게 됨
    메인에서 호출시 sysout하고, 클래스명.이름(Marine.attak / Marine.armor)으로 호출하면 됨
package quiz14;

public class Marine extends Unit {
	
	public static int attack = 6; // 객체마다 같은 값을 갖도록 static
	public static int armor =0; // static멤버 가져올 때 클래스명.이름
	
	public Marine() { // hp 생성자 부모한테 상속받아서 super()로 빌려쓰기
		super(40);
	}
	
		public void location() {
			System.out.println("현재 위치: " + x + ", " + y);
		}
		public void move(int x, int y) {
			this.x = x;
			this.y = y;
			System.out.println("움직인 위치: " + x + ", " + y);
		}
		public void stop() {
			System.out.println("정지");
		}
		
}

tank / 자식클래스 / 추상메서드 완성하기 / 본인의 changeMode 메서드 있음

  • 특별한 기능으로 mode 변경을 해줌
    단순히 끄고, 켜는 기능이라 boolean타입으로 진행
    if(mode) { mdoe = false} else { mode = true};
    조건 = mode가 true이면 false 넣어주고, false이면 true 넣어줌
package quiz14;

public class tank extends Unit{
	
	private boolean mode;
	
	public tank() {
		super(100);
	}
	
		public void location() {
			System.out.println("현재 위치: " + x + ", " + y);
		}
		public void move(int x, int y) {
			this.x = x;
			this.y = y;
			System.out.println("움직인 위치: " + x + ", " + y);
		}
		public void stop() {
			System.out.println("정지");
		}
//		특별한 기능 - mode 변경 (true → false, false → true)
		public void changeMode() {
			if(mode) {
				mode = false;
			} else {
				mode = true;
			}
			System.out.println("공격모드 변경");
		}
}

DropShip / 자식클래스 / 추상메서드 완성하기

package quiz14;

public class DropShip extends Unit {
	
	
	public DropShip() { // 안에 int hp 생략가능
		super(150);
	}
	
	public void location() {
		System.out.println("현재 위치: " + x + ", " + y);
	}
	public void move(int x, int y) {
		this.x = x;
		this.y = y;
		System.out.println("움직인 위치: " + x + ", " + y);
	}
	public void stop() {
		System.out.println("정지");
	}
}

mian

package quiz14;

public class MainClass {

	public static void main(String[] args) {
		
//		Marine m = new Marine();
//		m.move(10,20);
//		m.location(); 아래와 같음
//		System.out.println( Marine.armor); static 변수 불러올 때
//		System.out.println( Marine.attack); 
		
		Unit u = new Marine();
		u.location();
		u.move(10, 20);
		u.stop();
		
		Unit u1 = new tank();
		tank t = new tank();
		u1.location();
		u1.move(10, 30);
		u1.stop();
		t.changeMode();

		Unit u2 = new DropShip();
		u2.location();
		u2.move(10, 40);
		u2.stop();
		
	}
}

오늘 하루

더보기

기억에 남는 부분

- static 정적 제한자는 인스턴스 변수 = 멤버변수를 안 쓸 때 붙인다는 점

- static은 객체 없이도 참조 가능하고, 이걸 붙이면 메모리가 알아서 1개 생성해줌! class 밖에 어딘가에 생성

 

어려운 부분

- final이 한번만 저장되는 것은 알겠는데 어디에 써야 좋을지 모르겠고, static final도 완벽하게 이해는 못함

- static을 어디에 붙여야 할지 대략적으로만 알고, 아직 익숙하지 않음

- singletone design pattern : 그냥 잘 모르겠어요^^..

- 정적초기화 (잘 안 쓴다고는 하는데 실행할 때 딱 한번 호출된다고 하면 되나?) 기억에 잘 안남을 듯

 

문제 해결 부분

- quiz13: abstract 사용하는 이유와 사용방법을 알고 문제를 품, but 거기에 집중한 결과 기본 메서드는 사용할 생각을 안했음

 

728x90
profile

원지의 개발

@원지다

250x250