
변수(Variable)란?
메모리에 할당된 공간 (데이터를 담는 공간) ← 이 공간에 데이터가 저장됨
변수를 이용해서 데이터를 읽고 쓰고 조작 가능
- 인스턴스 변수 (Instance Variable) :
① 클래스 내에서 선언, 각 객체(instance)마다 있는 변수
② 객체생성 [new] 될 때마다 새로운 메모리 공간 할당
③ 클래스 내 메서드에서 this로 접근 가능
ex) class Abce {
int a; //instance 변수
}
this.a = 20; //instance 변수에 접근- 전역변수 (Global Variable) :
① 클래스 밖에서 선언, 프로그램 전체에 사용되는 변수
② 프로그램이 시작될 때 메모리에 할당 (객체생성과 관계 X)
③ 클래스 안에서는 static 변수로 선언static 변수(전역변수) :
static이 붙은건 = 클래스 멤버, 해당하는 클래스의 객체를 생성하지 않고도 접근가능
ex) class Abce {
static int b; //전역변수
}
b = 20; //전역변수에 접근- 로컬변수 (Local Variable):
① 메서드 내에서만 사용
② 해당 메서드가 실행될 때마다 메모리 할당 -> 메서드 종료 후 소멸
형변환
- 자식 → 부모 UpCasting
- 부모 → 자식 DownCasting
- ex, ((Test)ob).x : ob를 Test로 형변환하고, Test안에 있는 x값 출력
예외 ) 무조건 메서드는 자식껏만 쓴다 (Test.1 참고)
싱글톤 (Singleton) :
- 객체를 계속해서 생성해내는 것이 아니라 하나의 객체만 생성해서 공유하는 사용법
- ex) Calendar now = new getInstance( );
여기서 new getInstance( ) => static (처음 만들 때 메모리 할당 한번만! 하고 공유해서 사용)- 또 다른 말로는, 클래스가 한번만 메모리 할당하고 (static), 그 메모리에 전역변수를 사용하지 않고 인스턴스 하나를 만들어 객체를 하나만 생성하여 공유하는 법
- 설정값 / 동일한 리소스에 대한 동시접근을 제어하기 위해 사용
- 장점 : 전역변수 많이 쓰는 것과 메모리 낭비를 줄일 수 있음
추상클래스 (Abstract) :
① 메모리 낭비 없이 class 미리 설계 (⑥ → 해당 클래스의 Instance가 메모리에 생성되지 X)
② 메서드를 재정의해서 사용함 (= 다형성)
③ 추상클래스 안에는 반드시 한개 이상의 추상 메서드가 있어야 함 (+ 일반적인 메서드들도 입력할 수 있음)
④ 추상 클래스를 상속받으면 무조건 자식이 Override 해야 함
(단, final 붙은건 안됨)
⑤ 추상 메서드(Abstract Method) :
추상 클래스 내에 있지만, 구현되지 않음
-> 추상 메서드는 반드시 상속받는 자식메서드에서 구현되어있어야 함
⑥ 추상 클래스는 직접 객체 생성 X (상속받는 자식 클래스에서 객체 생성 O)
⑦ ⑥번에 이어 상속받는 자식 클래스에서 객체를 생성하므로 출력은 [ 자식 클래스.공통된 메서드( ); ]가 됨
📌 Note Code
Test1
💻 입력
class Test {
protected int a = 10, b = 20;
public void write() {
System.out.println("Super Class write()...."); // 부모=super
System.out.println("a : " + a + ",b: " + b);
}
}
class Demo extends Test {
protected int b = 30, c = 40;
@Override
public void write() {
System.out.println("Sub Class write()...");
System.out.println("a : " + a + ", b: " + b + ", c: " + c);
//상속으로 인해 부모 a 가져다 씀
// 부모도 있고 자식도 둘 다 b를 가지고있으면 자식 b출력
System.out.println("super.b: " + super.b); // 해당 class안에서만 가능
}
public void print1() {
System.out.println("Sub Class print1()...");
write();// 부모도 있고 자식도 둘 다 write( ) 가지고있으면 자식 wirte 출력
}
public void print2() {
System.out.println("Sub Class print1()...");
super.write(); // super - 부모꺼
}
}
public class Test1 {
public static void main(String[] args) {
Demo ob = new Demo(); // 기본생성자 안에서 super 찾고, 메모리 올리는 일을 반복 후 상속관계 성립
ob.write();
System.out.println("---------------------");
ob.print1();
System.out.println("---------------------");
ob.print2();
System.out.println("---------------------");
System.out.println("ob.b: " + ob.b);
//
System.out.println("((Test)ob).b: " + ((Test) ob).b); //(부모로 형변환)자식.b = 부모의 b
//자식의 write - 부모꺼를 오버라이딩해서 자식이 둘다 가지고있으면 자식의 의도가 들어갔기때문에
//메서드 만큼은 무조건 자식꺼 씀
((Test)ob).write();
}
}
/*
int a; double b;
a = 10;
b = a; --->OK / 큰값 <- 작은값 들어감 / 암시적 형변환
b = (double)a; --->OK : 강제 형변환
a = b; ---> X
a = (int)b --->OK : 강제 형변환
Demo a; 자식
Test b; 부모
* class = 자료형
Test(부모) = Demo(자식) --> OK / 자식 -> 부모 UPCAST
Test(부모) = (Test)Demo(자식) --> OK / 부모 -> 자식 DOWNCAST : 형변환하면 가능
Demo(자식) = Test(부모) ---> X
Demo(자식) = (Demo)Test(부모) ---> OK
*/
Sub Class write()...
a : 10, b: 30, c: 40
super.b: 20
---------------------
Sub Class print1()...
Sub Class write()...
a : 10, b: 30, c: 40
super.b: 20
---------------------
Sub Class print1()...
Super Class write()....
a : 10,b: 20
---------------------
ob.b: 30
((Test)ob).b: 20
Sub Class write()...
a : 10, b: 30, c: 40
super.b: 20
📌 Note Code

Test2
💻 입력
class Sing {
//1개의 클래스 - Instance 변수 1개 [private로 외부 접근 막음]
private static Sing ob;
//getInstance 메서드를 통해서만 접근 가능
public static Sing getInstance() {
//Instance가 없을 땐 객체 생성
if (ob == null) {
ob = new Sing();
}
//Instance가 있으면 ob값 반환
return ob;
}
}
public class Test2 {
public static void main(String[] args) {
//하나의 객체 생성 후 여러곳에서 getInstance 메서드를 통해 접근 가능 & 같은 주소 공유
//static
Sing ob1 = Sing.getInstance(); //Sing ob1 = Sing.ob(); : 10번지
Sing ob2 = Sing.getInstance();
if (ob1 == ob2) {
System.out.println("동일한 객체!!");
} else {
System.out.println("동일하지 않은 객체!!");
}
}
}
동일한 객체!!
📌 Note Code
Test3
💻 입력
class TestB{
public static final double PI; //double PI = 인스턴스변수 (한번 초기화한 후, 절대 바꿀 수 없음)
//public static final double PI = 3.14;
static { // 얘만 static 주게 되면 위에껀 메모리에 안올라가서 같이 static써줘야함
PI = 3.14;
}
public double area; // instance변수
public final void write(String title) {
System.out.println(title + " : " + area);
}
}
public class Test3 extends TestB {
/*
@Override
public void write(String title) { //2. Method에 final을 붙이면 Override 불가능
System.out.println("야호~~~");
}
*/
public void circleArea(int r) {
area = (double)(r*r*PI); //(double)r*r*PI = (double)r만 치환됨 , int * double = 암시적형변환 큰값으로 출력
}
public static void main(String[] args) {
Test3 ob = new Test3();
ob.circleArea(10);
ob.write("원");
}
}
원 : 314.0
📌 Note Code

Test4
💻 입력
abstract class ShapeClass{
abstract void draw(); //추상메서드 - ;으로 끝남 , 오버라이드 할때 고정
}
class Circ extends ShapeClass{
@Override //추상클래스 상속받으면 무조건 Override해야함
public void draw() { //오버라이드 할때 고정
System.out.println("원을 그린다");
}
}
class Rect extends ShapeClass{
@Override
public void draw() {
System.out.println("사각형을 그린다");
}
}
class Tri extends ShapeClass{
@Override
public void draw() {
System.out.println("삼각형을 그린다");
}
}
public class Test4 {
public static void main(String[] args) {
Circ c = new Circ();
Rect r = new Rect();
Tri t = new Tri();
c.draw();
r.draw();
t.draw();
}
}
원을 그린다
사각형을 그린다
삼각형을 그린다
📌 Note Code
Test5
💻 입력
abstract class SortInt{
private int[] value;
protected abstract void sorting(); //추상클래스 상속받으면 무조건 Override해야함
// 우회도로
public void sort(int[] value) { // 배열은 배열로 넘겨줘야함
this.value = value;// 초기화 됨
sorting();// 부모,자식 둘 다 가지고 있어도 메서드는 무조건 자식꺼
}
// 배열의 개수 확인
public int length() {
if (value == null) {
return 0; //0이면 false , 1이면 true반환
}
return value.length; // 배열에 쓰이는 length는 ()없음
}
protected final int compare(int i, int j) {
if (value[i] == value[j]) { //if쓰는 이유 확인용
return 0;
} else if (value[i] > value[j]) {
return 1; //원하는 값
} else {
return -1;
}
}
protected final void swap(int i, int j) { // 자리바꿈
int temp;
temp = value[i];
value[i] = value[j];
value[j] = temp;
}
public void print() {
if (value == null) {
return;
}
for (int su : value) { // (확장 for문) 알아서 배열의 개수만큼 실행해줌
System.out.printf("%4d", su);
}
}
}
class SortTest extends SortInt { //자식이 부모꺼 상속받았으므로, final을 제외하곤 메서드로 만들 수 있음
@Override
protected void sorting() {
// Selection Sort
for (int i = 0; i < length() - 1; i++) {
for (int j = i+1; j < length(); j++) {
if (compare(i, j) > 0) { // 반환값 1이어야 함
swap(i, j);
}
}
}
}
}
public class Test5 {
public static void main(String[] args) {
int[] data = {50,30,60,20,10};
SortTest ob = new SortTest();
ob.sort(data);
ob.print();
}
}
10 20 30 50 60