[앱 스쿨 2기 : Android] 2주차 2023.05.03 (Java)

hxeyexn·2023년 5월 3일
1
post-thumbnail

📅 2023.05.03

📂Java34_Static ~ 📂Java40_Interface

static

객체를 생성하지 않고도 메모리상에 올라감, 클래스 이름을 통해 접근할 수 있음

static variable

  • 프로그램이 시작되어 클래스들이 메모리에 올라갈 때 생성되는 변수
  • 객체 참조 변수를 통해서도 사용이 가능하며 딱 하나의 변수만 생성
  • 프로그램 전체에서 딱 하나만 존재하는 값을 저장할 때 사용

static method

  • static변수나 매개변수를 포함한 지역변수만 사용하는 메서드의 경우 static으로 정하면 편하게 사용할 수 있음
  • 즉, 프로그램 전체에서 1개만 있는 값일 때 사용

📂Java34_Static


final

더 이상 변경할 수 없다는 의미를 가지고 있음

final variable

  • 변수에 다른 값을 저장할 수 없음
  • 선언과 동시에 초기화 필요

final method

  • 자식 클래스에서 overriding이 불가능

final class

  • 상속이 불가능
  • 무조건 객체를 생성해 참조변수를 통해 접근할 수 있도록 원할 경우 사용

📂Java35_Final


InnerClass (중첩 클래스)

클래스 안에 클래스를 만드는 것을 의미

  • 중첩클래스는 개발자의 편의를 위해 쓰는 것, 취향에 맞지 않으면 쓰지 않아도 됨
  • java : 코드 복잡해짐
  • kotlin : 코드가 복잡해지지 않으므로 사용권장

Inner Class (일반 중첩 클래스)

  • 클래스 안에 클래스를 만드는 개념
  • 클래스 내부의 클래스는 외부 클래스의 객체를 통해서 생성할 수 있음
  • 특정 클래스에 정의된 멤버를 자주 사용하는 경우 사용
  • class파일이 외부클래스$내부클래스.class 로 생성
  • 장점 : 내부 클래스에서 외부 클래스의 멤버를 사용하는 것이 자유로움
  • 단점 : 내부 클래스의 객체를 생성하려면 반드지 외부 클래스의 객체를 생성해야 함
public class MainClass {

	public static void main(String[] args) {
    	// 일반 중첩 클래스의 객체를 생성한다.
        // 외부 클래스의 객체를 생성한다.
		OuterClass1 out1 = new OuterClass1();
		// 이를 통해 내부 클래스의 객체를 생성한다.
		OuterClass1.InnerClass1 in1 = out1.new InnerClass1();
		System.out.printf("in1 : %s\n", in1);
    }
}


class OuterClass1 {
	
	int outerMemberA = 100;
	
	public void outerMethodA() {
		System.out.println("outerMethod!");
		// 내부 클래스의 멤버를 사용한다. -> 오류 발생
		// System.out.printf("innerMemberA : %d\n", innerMemberA);
		// innerMethodA();
	}
	
	class InnerClass1 {
		
		int innerMemberA = 200;
		
		public void innerMethodA() {
			System.out.println("innerMethod!");
		}
		
		public void innerMethodB() {
			// 외부 클래스에 정의된 멤버를 사용한다.
			System.out.printf("OuterMemberA : %d\n", outerMemberA);
			outerMethodA();
		}
	}
}

Static Inner Class (정적 중첩 클래스)

  • 장점 : 없다..?
  • 단점 : 내부 클래스가 외부 클래스의 멤버를 자유롭게 사용할 수 있다는 특징이 사라짐. 오로지 외부 클래스에 정의된 static 변수나 메서드만 사용 가능
public class MainClass {

	public static void main(String[] args) {
    	// static 중첩 클래스는 외부클래스의 객체 없이 바로 생성이 가능하다.
		OuterClass2.InnerClass2 in2 = new OuterClass2.InnerClass2();
		System.out.printf("in2 : %s\n", in2);
    }
}


class OuterClass2 {
	
	// 외부 클래스에 정의된 static 변수
	static int outerMemberA = 200;
	// 외부 클래스에 정의된 멤버 변수
    int outerMemberB = 300;
	
	// 내부 클래스의 static 멤버 사용
	public void outerMehod1() {
		System.out.println(InnerClass2.innerMemberA);
		// System.out.println(InnerClass2.innerMemberB);
	}
	
	// static 중첩 클래스
	static class InnerClass2 {
		// 내부 클래스에 정의된 static 변수
		static int innerMemberA = 100;
		
		// 내부 클래스에 정의된 멤버 변수
		// int innerMemberB = 300;
		
		public void innerMethod1() {
			// 외부 클래스에 정의된 static 변수
			// 외부 클래스의 이름을 생략할 수 있다.
			System.out.println(outerMemberA);
			// 외부 클래스에 정의된 멤버 변수 사용 불가
			// System.out.println(outerMemberB);
		}
	}
}

Local Inner Class (지역 중첩 클래스)

  • 메서드 내부에 클래스를 작성하여 사용하는 클래스
  • 메서드의 수행이 끝나면 클래스가 메모리에서 사라지기 때문에 메서드 외부에서는 클래스 사용 불가
    ➡️ OuterClass3$InnerClass3 파일이 존재하지 않는 것을 확인할 수 있음
  • 장점 : 메서드에서 사용하는 클래스를 작성할 때 다른 곳에 작성하지 않고 바로 작성해 사용 가능
  • 단점 : 메서드 내부에서만 사용 가능
class OuterClass3 {
	
	// 지역 중첩클래스 타입의 멤버변수 선언
	// InnerClass3 in30;
	
	public void outerMethod3() {
		// 지역 중첩 클래스
		class InnerClass3 {
			
		}
		// 지역 중첩 클래스 객체 생성
		InnerClass3 in3 = new InnerClass3();
		System.out.println(in3);
	}
	
	// 다른 메서드에서 사용
    // public void outerMethod30(InnerClass3 in34) {
    //     InnerClass3 in33;
    // }
}

Anonymous Inner Class (익명 중첩 클래스)

  • 클래스의 이름이 없음
  • 상속관계의 클래스를 만드는 것임
  • 특정 클래스를 상속받은 클래스를 만듬과 동시에 객체를 생성할 때 사용
  • 메서드 overriding 때문에 사용
  • 특정 클래스를 상속받은 클래스의 객체를 단 하나만 만들어 사용할 때 사용
public class MainClass {

	public static void main(String[] args) {
    	// 익명 중첩 클래스
		// SuperClass100을 상속받은 이름이 없는 클래스를 작성하고
        // 필요한 메서드들을 overriding한다.
        // 그리고 자식클래스의 객체를 생성해준다.
		SuperClass100 s100 = new SuperClass100() {
			
			@Override
			public void superMethod100() {
				System.out.println("overriding된 메서드");
			}
		};
		
		s100.superMethod100();
    }
}


class SuperClass100 {
	
	public void superMethod100() {
		System.out.println("superMethod100");
	}
}

📂Java36_InnerClass


Abstract Class (추상 클래스)

abstract method

  • 코드 부분이 없는 미완성 메서드
  • 구현되지 않은 메서드이므로 메서드를 구현해야지만 사용 가능
  • 메서드 앞에 abstract 키워드를 붙혀줌 ➡️ public abstract void method()

abstract class

  • 미완성 설계도
  • 추상 메서드를 가지고 있는 클래스
  • 클래스 앞에 abstract를 붙혀줌 ➡️ public abstract class ClassName { }
  • 구현되지 않은 메서드를 가지고 있기 때문에 직접 객체 생성이 불가능
  • 따라서, 추상 클래스를 상속받은 자식 클래스를 만들어 추상 메서드를 overriding하여 사용
  • 상속 키워드 : extends

final class vs abstract class

  • final class
    : 오버라이딩 막기 위해 사용
    : 객체 O, 상속 X
  • abstract class
    : 상속과 오버라이딩에 대한 강제성을 주기 위해 사용
    : 객체 X, 상속 O
public class MainClass {

	public static void main(String[] args) {
		// 추상 클래스 객체 생성
		// 추상 클래스는 완벽한 클래스가 아니기 때문에
		// 직접 객체를 생성하는 것이 불가능하다.
		// TestClass1 t1 = new TestClass1();

		TestClass2 t2 = new TestClass2();
		t2.testMethod1();
		t2.testMethod2();

		TestClass1 t1 = new TestClass2();
		t1.testMethod2();

		TestClass1 t10 = new TestClass1() {

			@Override
			public void testMethod2() {
				System.out.println("익명 중첩 클래스 사용");
			}
		};
		t10.testMethod2();
	}

}


// 추상클래스
abstract class TestClass1 {
	
	public void testMethod1() {
		System.out.println("일반 메서드");
	}
	
	// 추상메서드
	abstract public void testMethod2();
}

// 추상 클래스를 상속받아 구현한 클래스
class TestClass2 extends TestClass1{

	@Override
	public void testMethod2() {
		System.out.println("TestClass2에서 구현한 testMethod2");
	}
 
}

📂Java38_Abstract


Interface (인터페이스)

Interface

  • 추상 메서드로만 구현되어 있는 요소
  • 자바에서는 단일 상속만 지원하므로 하나의 클래스만 상속 받을 수 있음
  • 여러 타입의 변수에 담을 수 있도록 사용하는 것이 Interface
  • 하나의 클래스는 다수의 Interface를 구현할 수 있음
  • 인터페이스는 클래스가 아니라서 객체를 생성하지 못함
  • 상속 키워드 : implements

variable

  • 인터페이스에 정의한 변수는 static final 변수
  • 변수에 static final을 붙이지 않아도 static final로 간주

method

  • 인터페이스에 정의된 메서드는 모두 추상 메서드
  • 메서드를 선언할 때 abstract 키워드를 붙히지 않아도 추상 메서드로 간주
public class MainClass {

	public static void main(String[] args) {

		// 인터페이스에 정의한 변수 사용
		System.out.printf("TestInterface1.a1 : %d\n", TestInterface1.a1);

		TestClass1 t1 = new TestClass1();
		t1.testMethod1();
		t1.testMethod2();

		// 클래스가 구현한 인터페이스 타입형 변수에 담을 수 있다.
		TestInterface1 t10 = new TestClass1();
		t10.testMethod1();

		TestInterface2 t20 = new TestClass1();
		t20.testMethod2();
	}

}

// 인터페이스는 클래스가 아니라서 객체를 생성하지 못함
interface TestInterface1 {
	// 인터페이스에 정의한 변수는 static final 변수이다.
	int a1 = 100;

	// 메서드
	// 인터페이스에 정의한 메서드는 추상 메서드이다.
	public void testMethod1();

	// 인터페이스에 static 메서드를 정의할 수 있다.
	public static void testMethod100() {
		System.out.println("testMethod100");
	}

}

interface TestInterface2 {

	public void testMethod2();
}

// 인터페이스를 구현한 클래스
// 인터페이스는 다수를 구현할 수 있다.
class TestClass1 implements TestInterface1, TestInterface2 {

	@Override
	public void testMethod1() {
		// TODO Auto-generated method stub
		System.out.println("TestClass1의 testMethod1");
		System.out.printf("a1 : %d\n", a1);
	}

	@Override
	public void testMethod2() {
		// TODO Auto-generated method stub
		System.out.println("TestClass1의 testMethod2");
	}
}

📂Java40_Interface


profile
Android Developer

0개의 댓글