ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TECHIT 앱 스쿨 2기: Android 8일차 (23.05.03)
    [THEC!T] 앱 스쿨2기 : Android 2023. 5. 4. 00:33
    728x90

    자료 출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 내용

     

    시간이 참 빠른 것 같습니다. 벌써 8일차......

     

    오늘은 static에 대한 설명을 해주시는 것으로 시작하였습니다.

    변수나 메서드에 static 을 붙혀주면 객체를 생성하지 않더라도 클래스 이름을 통해 접근 할 수 있습니다.

    package com.studty.lst;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    		// 객체 생성 없이 static 변수 사용하기
    		System.out.println(Test1.num1);
    		// 객체 생성 없이 static 메서드 사용하기
    		Test1.m1();
    		
    	}
    
    }
    
    class Test1 {
    	
    	static int num1 = 100;
        
    	public static void m1(){
    		System.out.println("Test1의 static으로 선언된 메소드");
    	}
    	
    }
    출력 결과
    100
    Test1의 static으로 선언된 메소드

    static 으로 선언하면 객체를 생성할 필요 없이 해당 변수 혹은 메서드를 사용할 수 있는 점을 확인하였습니다.

    static 변수는 static 메서드에서 사용하는 변수이거나, 프로그램 전체에서 1개만 있는 값들로 구성해야 합니다.

     

    그리고 주의 할 점은 static 메서드에서 객체의 멤버 변수를 사용하면 안됩니다.

    왜냐하면 해당 객체가 생성되었는지 안되었는지 확실하게 알 수 없기에 에러가 발생합니다.

    package com.studty.lst;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    		// 객체 생성 없이 static 변수 사용하기
    		System.out.println(Test1.num1);
    		// 객체 생성 없이 static 메서드 사용하기
    		Test1.m1();
    		
    		// 객체 생성 없이 멤버 변수 사용하기
    //		System.out.println(Test1.num2); // 에러
    		// 객체 생성 없이 멤버 메서드 사용하기
    //		Test1.m2(); // 에러
    	}
    
    }
    
    class Test1 {
    	// static 변수 생성
    	static int num1 = 100;
    	
    	// 멤버 변수 생성
    	int num2 = 200;
    	
    	// static 메서드 생성
    	public static void m1(){
    		System.out.println("Test1의 static으로 선언된 메소드");
    		// 멤버 변수 사용해보기
    //		System.out.printf("num2 : %d\n",num2); // 에러 발생
    		// 멤버 메서드 사용해보기
    //		m2(); // 에러발생
    	}
    	
    	// 멤버 메서드 생성
    	public void m2(){
    		System.out.println("Test1의 맴버 메소드");
    	}
    	
    }

     

    Final

    final 은 더 이상 변경할 수 없다는 의미를 가지고 있습니다.

    변수에 final을 사용 할 경우 변수를 선언 할 때 값을 저장해줘야 합니다.

    그리고 final을 사용한 변수는 상수역할을 할 변수를 정의 할 때 사용합니다.

    자바에서는 상수의 이름은 대문자로 짓습니다.

     

    변수에 사용 시

    해당 변수에 다른 값을 저장 할 수 없습니다.

    package com.studty.lst;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    		
    		// final을 이용하여 변수 생성
    		final int NUM1 = 100;
    		// final을 이용하여 생성한 변수 변경 시도
    		NUM1 = 200; // 에러 발생
    		//The final local variable num1 cannot be assigned. 
    		//It must be blank and not using a compound assignment
    	}
    
    }

    메서드에 사용 시

    추후 자식 클래스에서 오버라이딩(overriding)을 할 수 없습니다. 

    class Test1 {
    	
    	// final을 이용하여 메서드 생성
    	final public void m1() {
    		System.out.println("m1 메소드");
    	}
    	
    }
    
    class Test2 extends Test1 {
    	
    	// final을 이용하여 생성한 변수 변경 시도
    	final public void m1() { // 에러 발생
    		System.out.println("m1 메소드");
    	}
    	// Cannot override the final method from Test1
    }

    클래스에 사용 시

    해당 클래스는 상속이 불가능 합니다.

    //final을 이용하여 클래스 생성
    final class Test1 {
    	
    	// final을 이용하여 메서드 생성
    	final public void m1() {
    		System.out.println("m1 메소드");
    	}
    	
    }
    
    class Test2 extends Test1 { // 에러 발생
    	
    }
    // The type Test2 cannot subclass the final class Test1

     

    중첩 클래스

     

    클래스 내부에 만든 클래스를 Inner Class 라고 부르며,  Inner Class를 감싸고 있는 클래스를 Outer Class 라고 합니다.

     

    일반 중첩 클래스

    클래스 안에 클래스를 만든 개념이며, 클래스 내부의 클래스는 외부 클래스의 객체를 통해서 생성 할 수 있습니다.

    특정 클래스에 정의된 멤버를 자주 사용하는 경우 사용합니다.

    장점으로는 내부 클래스에서 외부 클래스의 멤버를 사용하는 것이 자유롭습니다.

    단점으로는 내부 클래스의 객체를 생성하려면 반드시 외부 클래스의 객체를 생성해야 합니다.

     

    package com.studty.lst;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    
    		// 외부 클래스의 객체 생성
    		OuterClass out = new OuterClass();
    		// 이를 통해 내부 클래스의 객체 생성
    		OuterClass.InnerClass in1 = out.new InnerClass();
    		
    	}
    
    }
    
    class OuterClass{
    	// 외부 클래스의 멤버 변수 생성
    	int outterMember = 100;
    	
    	// 외부 클래스의 멤버 메서드 생성
    	public void outerM1() {
    		System.out.println("outerM1!");
    	}
    	
    	
    	// 내부 클래스
    	class InnerClass{
    		int innerMember = 200;
    		
    		public void innerM1() {
    			// 외부 클래스에 정의된 멤버 사용
    			System.out.printf("outterMember : %d \n",outterMember);
    		}
    		
    		public void innerM2() {
    			// 외부 클래스에 정의된 메서드 사용
    			outerM1();
    		}
    		
    	}
    	
    }

     

    지역 중첩 클래스

    메서드 내부에 클래스를 작성하여 사용하는 클래스입니다.

    메서드의 수행이 끝나게 되면 클래스가 메모리에서 사라지기 때문에 메서드 외부에서는 사용을 할 수 없습니다

     

    장점으로는 메서드에서 사용하는 클래스를 작성할 때 다른 곳에 작성하지 않고 바로 작성하여 사용할 수 있습니다.

    단점으로는 메서드 내부에서만 사용이 가능하다는 점 입니다.

     

    class OuterClass2{
    	
    	public void outerM1() {
    		// 지역 중첩 클래스 
    		// outerM1 내 에서만 사용이 가능하며 메서드가 종료되면 소멸한다.
    		class InnerClass2{
    			
    		}
    		// 지역 중첨 클래스 객체 생성
    		InnerClass2 in2 = new InnerClass2();
    		System.out.println(in2);
    	}
    	
    	// 지역 중첩클래스 타입의 멤버 변수 선언 -> 오류 발생.
    	InnerClass2 in3 = new InnerClass2();
    	
    	// 지역 중첩클래스 타입의 멤버 메서드 선언 -> 오류 발생.
    	public void outerMethod30(InnerClass2 in34) { 
    		InnerClass2 in33;
    	}
    	
    }

     

    익명 중첩 클래스

    클래스의 이름이 없다는 뜻 입니다. 익명 중첩 클래스는 상관관계의 클래스를 만드는 것입니다.

    특정 클래스를 상속받은 클래스를 만듬과 동시에 객체를 생성할 때 사용합니다.

    그렇기에 재사용을 할 수 없습니다. 따라서 생성하려는 객체가 1개일 경우에는 유용합니다.

    일반적으로는 메서드 오버라이딩(overrinding) 때문에 사용합니다.

    특정 클래스를 상속 받은 클래스의 객체를 단 하나만 만들어 사용할 때 사용합니다.

    package com.studty.lst;
    
    import com.test.main.InnerClass3;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
            
    		// 익명 중첩 클래스
    		// SuperClass을 상속받은 이름이 없는 클래스를 작성하고
    		// 필요한 메서드들을 overriding한다.
    		// 그리고 자식클래스의 객체를 생성해준다.
    		SuperClass s1 = new SuperClass() {
    			public void superM1() {
    				System.out.println("overrinding 실행하였음.");
    			}
    		};
    		
    		s1.superM1();
    		
    	}
    
    }
    
    class SuperClass{
    	public void superM1() {
    		System.out.println("superM1");
    	}
    }

    출력 결과

    overrinding 실행하였음.

     

     

    추상 메서드 와 추상 클래스 

    추상 메서드는 코드 부분이 없는 미완성 메서드를 말하며 추상 클래스는 추상 메서드를 가지고 있는 클래스를 말합니다.

    추상 클래스는 구현이 되지 않은 메서드를 가지고 있기 때문에 객체 생성이 불가능 합니다. 따라서, 추상 클래스를 상속 받은 자식클래스를 만들어 추상 메서드를 오버라이딩(overrinding) 한 뒤 자식 클래스를 이용하여 객체를 생성합니다.

    추상 클래스와 추상 메서드 앞에는 abstract 라는 키워드를 붙혀 줍니다.

     

    package com.studty.lst;
    
    import com.test.main.InnerClass3;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    
    		// 추상 클래스를 이용한 객체 생성
    		//TestClass1 t1 = new TestClass1();
    		// 에러 발생
    		// Cannot instantiate the type TestClass1
    		// 추상 클래스를 상속 받아 추상 메서드를 오버라이딩 한 자식 클래스를
    		// 이용한 객체 생성
    		TestClass2 t2 = new TestClass2();
    		// 자식 클래스를 이용한 추상 클래스 멤버 메서드 호출
    		t2.testM1();
    		// 자식 클래스에서 오버라이딩 된 메서드 호출
    		t2.testM2();
    		
    	}
    
    }
    
    // 추상 클래스
    abstract class TestClass1{
    	
    	// 멤버 메서드
    	public void testM1() {
    		System.out.println("일반 메서드");
    	}
    	
    	// 추상메서드
    	// 코드를 작성하는 몸체 부분이 없는 메서드
    	// 메서드 앞에 abstract 키워드를 붙혀준다.
    	abstract public void testM2();
    }
    
    // 추상 클래스를 상속 받는 자식 클래스 생성
    class TestClass2 extends TestClass1{
    	// 만약 부모 클래스에 추상메서드를 오버라이딩 하지 않을 경우
    	// 자식 클래스도 추상 클래스가 된다.
    	
    	// 부모 클래스의 testM2 오버라이딩
    	 public void testM2() {
    		 System.out.println("testM2 오버라이딩 완료");
    	 }
    }

     

    출력 결과

    일반 메서드
    testM2 오버라이딩 완료

     

    이후 강사님이 지금까지 배운 내용을 사용해 볼 수 있도록 문제를 내주셨습니다.

    어제 만들었던 Zoo 문제를 작성한 코드를 기반으로 수정 및 작성하는 하기 와 같은 문제를 내주셨습니다.

     

    문제

    자동차 공장
    어떤 자동차를 생산할까요?
    1. SUV, 2. 세단, 3. 슈퍼카, 0. 종류 : 1

    자동차의 이름은 무엇인가요? 붕붕카

    반복해서 입력을 받는다.


    출력예시
    자동차 종류 : SUV
    이름 : 붕붕카
    가격 : 싸다
    색상 : 빨간색
    시동방법 : 버튼을 눌러 시동을 겁니다.
    --------------------------------------------
    자동차 정보
    SUV
    가격 : 싸다
    색상 : 빨간색
    시동 방법 : 버튼을 눌러 시동을 겁니다.


    세단
    가격 : 보통이다
    색상 : 검은색
    시동 방법 : 카드를 올려둡니다.

    슈퍼카
    가격 : 비싸다
    색상 : 노란색
    시동 방법 : 지문 인식


    ---------------------------

    조건)
    시동 방법은 메서드로 구현한다.
    자동차는 Car 라는 클래스를 상속 받게 한다.
    시동 방법 메서드는 추상 메서드로 정의한다.
    Car를 상속받는 클래스 따로 만들지 않고 익명 중첩 클래스를 사용한다.

     

     

    일단 먼저 결론을 먼저 말하자면 다시 생각해보니 아쉬웠던 점이 조금 있지만, 오늘 조원들과 이야기를 하며 결과물은 완성 하였습니다.

     

    조원들과 작성한 코드는 하기와 같습니다.

    패키지 구성 사진

    MainClass 입니다.

    package study;
    import study.car.CarClass;
    
    public class MainClass {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    		// Car 클래스를 이용하여 만든 객체를 생성한다.
    		CarClass carClass = new CarClass();
    		
    		// 입력받은 Car의 타입
            int typeNumber = 0;
            
            // 입력 받는 차 번호가 0이 아닌 동안 반복한다.
            do {
            	typeNumber = carClass.inputCarType();
            	
            	// 차 타입 번호가 0이 아니라면...
                if(typeNumber != 0) {
                	carClass.addAnimal(typeNumber);
                }
            	
            } while(typeNumber != 0);
            
            // 입력한 자동차들의 정보를 출력한다.
            carClass.printAnimalInfo();
    	}
    
    }

    CarClass 입니다.

    package study.car;
    
    import java.util.Scanner;
    
    public class CarClass {
    
    	private Scanner scanner;
    
    	// 자동차 객체들을 담을 배열
    	private CarInfoClass[] carArray;
    	// 자동차의 수
    	private int carCount;
    
    	public CarClass() {
    		this.scanner = new Scanner(System.in);
    		carArray = new CarInfoClass[1000];
    		carCount = 0;
    	}
    
    	// 자동차을 추가하는 메서드
    	public void addAnimal(int typeNumber) {
    
    		// 자동차의 이름을 입력받는다.
    		System.out.print("자동차의 이름은 무엇인가요? : ");
    		String name = scanner.next();
    
    		// 자동차 객체를 생성한다.
    		CarInfoClass car = null;
    
    		// typeNumber 에 따른 자동차 종류 클래스 입력 switch문
    		switch (typeNumber) {
    		case 1:
    			// animal = new ElephantClass(name);
    			car = new CarInfoClass() {
    				@Override
    				void startup() { // 시동 방법에 대한 메서드 오버라이딩
    					// TODO Auto-generated method stub
    					System.out.println("버튼을 눌러 시동을 겁니다.");
    				}
    			};
    			car.carKind = "SUV";
    			car.carPrice = "싸다";
    			car.carColor = "빨간색";
    			car.carName = name;
    			break;
    		case 2:
    			car = new CarInfoClass() {
    				@Override
    				void startup() { // 시동 방법에 대한 메서드 오버라이딩
    					// TODO Auto-generated method stub
    					System.out.println("카드를 올려둡니다.");
    				}
    			};
    			car.carKind = "세단";
    			car.carPrice = "보통이다";
    			car.carColor = "검은색";
    			car.carName = name;
    			break;
    		case 3:
    			car = new CarInfoClass() {
    				@Override
    				void startup() { // 시동 방법에 대한 메서드 오버라이딩
    					// TODO Auto-generated method stub
    					System.out.println("지문 인식");
    				}
    			};
    			car.carKind = "슈퍼카";
    			car.carPrice = "비싸다";
    			car.carColor = "노란색";
    			car.carName = name;
    			break;
    		}
    
    		carArray[carCount] = car;
    		carCount++;
    	}
    
    	// 입력한 자동차들의 정보를 출력하는 메서드
    	public void printAnimalInfo() {
    		// 자동차의 수 만큼 반복한다.
    		for (int i = 0; i < carCount; i++) {
    			CarInfoClass car = carArray[i];
    			car.printInfo();
    			car.startup();
    			System.out.println();
    		}
    	}
    
    	// 자동차의 타입을 입력받아 반환한다.
    	public int inputCarType() {
    		// 차 타입 번호를 입력받는다.
    		System.out.println("어떤 자동차를 생산할까요?");
    		System.out.print("1. SUV, 2. 세단, 3. 슈퍼카, 0. 종류 : ");
    		int typeNumber = scanner.nextInt();
    		return typeNumber;
    	}
    
    }
    
    abstract class CarInfoClass {
    	// 자동차 종류
    	String carKind;
    	// 자동차 가격
    	String carPrice;
    	// 자동차 색상
    	String carColor;
    	// 자동차 이름
    	String carName;
    
    	// 시동방법에 대한 추상 메서드
    	abstract void startup();
    
    
    	// 출력
    	public void printInfo() {
    		System.out.printf("자동차 종류 : %s\n", carKind);
    		System.out.printf("이름 : %s\n", carName);
    		System.out.printf("가격 : %s\n", carPrice);
    		System.out.printf("색상  : %s\n", carColor);
    	}
    }

     

    음... 코드를 다시 보니 제대로 변경하지 못한 점이 몇개 보이지만 그래도 처음으로 원하는 결과물이 나오도록 코드를 작성하였기에 수정은 하지 않도록 하겠습니다.

    수정을 한다면 ->

    // 입력한 자동차들의 정보를 출력하는 메서드

    public void printAnimalInfo()

    이 부분과 관련하여 일단 메서드 명을 변경 할 것입니다.

     

    일단은 어제 맘먹은 대로 진짜 말을 엄청 했던 것 같습니다. 화면 공유도 그냥 먼저 한다고 한 뒤에 조원 분들에게 계속 말을 걸었습니다. 만약 제가 코드를 잘못 짜거나, 코드를 작성하는데 있어 저와 다른 방식으로 작성하는 의견이 있는지, 코드 작성하다가 이거 어떻게 작성하더라? 라던지 코드를 수정해 가면서 보게 된 메서드가 어떤 기능을 하는지, 이름은 어떻게 수정을 할지... 등등 진짜 열심히 말을 했었던 것 같습니다. 그래서 확실히 이야기를 하면서 어제보다 소통이 잘 되었다고 생각을 합니다. 중간에 한번 잘못 작성하여 오류가 났었는데.... 아이스 브레이킹하는 느낌으로 왜 말안해줬어요... 라는 농담을 던질 수 있었을 만큼 나름 원활했던 것 같았습니다. 그리고 이후에 강사님께서 해당 문제에 대해서 알려주시기 전까지 나름 이런 저런 이야기를 하면서 어제보다는 조금 더 가까워진듯한 느낌을 받았습니다. 강의가 끝나면 뭐하는지.. 차 사고 싶다라던가.. 블로그 이야기 라던가 등등

     

    이후 시간이 지난 뒤 강사님께서 해당 문제에 대해서 설명을 해주셨습니다.

    강사님은 문제를 내주실 때는 만들었던 코드를 참고하여 작성하라고 하셨었던 이유가 오늘 배운 내용들을 써보도록 만들게 하시려는 의도 였다고 말씀을 해주셨고, 새로 코드를 작성하여 알려 주셨습니다.

    사실 이때 문제에 있던 조건만 생각해 어제 배운 내용들은 적용을 별로 못시켰었습니다. 

    -> 접근제한자 쓸 생각을 솔직히 1도 못했었습니다..... 그냥 이야기 하며 수정..수정...수정...

     

    하기와 같이 클래스를 만드셨습니다.

     

    이렇게 만드실 것을 보고 문제에 자동차 공장이 있었다는 사실을 깜빡 했었다는 사실을 알게 되었었습니다 . 그러면 이름을 선택 할 수 있는 폭이 많아졌을텐데 라는 생각도 들었었습니다.

     

    강사님은 일단 내주신 문제에 조건에 맞게 익명 중첩클래스를 사용하여 작성하는 방법과 상속을 이용하여 작성하는 방법 두 가지 코드를 알려주셨습니다.

     

    MainClass 입니다.

    package com.test.main;
    
    public class MainClass {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            
    		// Factory 객체 생성한다.
    		Factory factory = new Factory();
    		
    		// 자동차 종류
    		int carType = 0;
    		
    		do {
    			// 자동차 종류를 입력받는다. 
    			carType = factory.inputCarType();
    			
    			if(carType != 0) {
    				// 자동차 정보를 입력 받는다.
    				factory.inputCarInfo(carType);			}
    			
    		} while(carType != 0);
    		
    		factory.printCarInfo();
    	}
    
    }

     

    Factory 클래스 입니다.

    주석이 된 부분은 익명 중첩 클래스 및 추상 클래스를 사용한 부분 입니다.

    package com.test.main;
    
    import java.util.Scanner;
    
    public class Factory {
    	// 자동차 최대 대수
    	private final int CAR_MAX_COUNT = 100;
    	// 입력한 자동차 대수
    	private int carCount = 0;
    	// 스캐너
    	private Scanner scanner;
    	// 자동차들을 담을 배열
    	private Car [] carList;
    	
    	public Factory() {
    		this.scanner = new Scanner(System.in);
    		carList = new Car[CAR_MAX_COUNT];
    	}
    	
    	// 자동차 타입 입력 메서드
    	public int inputCarType() {
    		System.out.println("자동차 종류를 입력해주세요");
    		System.out.println("1. SUV, 2. 세단, 3. 슈퍼카, 0. 종류 : ");
    		int carType = scanner.nextInt();
    		return carType;
    	}
    	
    	// 자동차 이름을 받아 자동차 객체를 생성하는 메서드
    	public void inputCarInfo(int carType) {
    		System.out.println("자동차 이름을 입력해주세요 : ");
    		String name = scanner.next();
    		
    		// 자동차 종류에 따라 객체를 생성한다.
    		Car car = null;
    		
    		switch(carType) {
    		case 1 :
    //			car = new Car() {
    //
    //				@Override
    //				public void startEngine() {
    //					// TODO Auto-generated method stub
    //					System.out.println("버튼을 눌러 시동을 겁니다.");
    //				};
    //				
    //			};
    //			car.setCarType("SUV");
    //			car.setCarName(name);
    //			car.setCarPrice("싸다");
    //			car.setCarColor("빨간색");
    			car = new SUVClass("SUV", name, "싸다", "빨간색");
    			break;
    			
    		case 2 :
    //			car = new Car() {
    //
    //				@Override
    //				public void startEngine() {
    //					// TODO Auto-generated method stub
    //					System.out.println("카드를 올려둡니다.");
    //				};
    //				
    //			};
    //				car.setCarType("세단");
    //				car.setCarName(name);
    //				car.setCarPrice("보통이다");
    //				car.setCarColor("검정색");
    			car = new SedanClass("세단", name, "보통이다", "검정색");
    				break;
    				
    		case 3 :
    //			car = new Car() {
    //
    //				@Override
    //				public void startEngine() {
    //					// TODO Auto-generated method stub
    //					System.out.println("지문 인식으로 시동을 겁니다.");
    //				};
    //			};
    //				
    //				car.setCarType("슈퍼카");
    //				car.setCarName(name);
    //				car.setCarPrice("비싸다");
    //				car.setCarColor("노란색");
    			car = new SuperCarClass("슈퍼카", name, "비싸다", "노란색");
    				break;
    		}
    		
    		carList[carCount] = car;
    		carCount++;
    	
    	}
    	
    	// 자동차 정보들을 출력하는 메서드
    	public void printCarInfo() {
    		for(int i = 0 ; i < carCount; i++) {
    			carList[i].printCarInfo();
    		}
    	}
    	
    }
    
    
    //abstract class Car{
    //	// 자동차 종류
    //	private String carType;
    //	// 자동차 이름
    //	private String carName;
    //	// 자동차 가격
    //	private String carPrice;
    //	// 자동차 색상
    //	private String carColor;
    //	
    //	public abstract void startEngine();
    //
    //	public void setCarType(String carType) {
    //		this.carType = carType;
    //	}
    //
    //	public void setCarName(String carName) {
    //		this.carName = carName;
    //	}
    //
    //	public void setCarPrice(String carPrice) {
    //		this.carPrice = carPrice;
    //	}
    //
    //	public void setCarColor(String carColor) {
    //		this.carColor = carColor;
    //	}
    //	
    //	public void printCarInfo() {
    //		System.out.printf("자동차 종류 : %s\n", carType);
    //		System.out.printf("자동차 이름 : %s\n", carName);
    //		System.out.printf("자동차 가격 : %s\n", carPrice);
    //		System.out.printf("자동차 색깔 : %s\n", carColor);
    //		startEngine();
    //	}
    //	
    //}
    
    abstract class Car{
    	// 자동차 종류
    	private String carType;
    	// 자동차 이름
    	private String carName;
    	// 자동차 가격
    	private String carPrice;
    	// 자동차 색상
    	private String carColor;
    	
    	public Car(String carType, String carName, String carPrice, String carColor) {
    		this.carType = carType;
    		this.carName = carName;
    		this.carPrice = carPrice;
    		this.carColor = carColor;
    	}
    	
    	public abstract void startEngine();
    	
    	public void printCarInfo() {
    		System.out.printf("자동차 종류 : %s\n", carType);
    		System.out.printf("자동차 이름 : %s\n", carName);
    		System.out.printf("자동차 가격 : %s\n", carPrice);
    		System.out.printf("자동차 색깔 : %s\n", carColor);
    		startEngine();
    	}
    	
    }
    
    // SUV
    class SUVClass extends Car {
    
    	public SUVClass(String carType, String carName, String carPrice, String carColor) {
    		super(carType, carName, carPrice, carColor);
    		// TODO Auto-generated constructor stub
    	}
    
    	@Override
    	public void startEngine() {
    		// TODO Auto-generated method stub
    		System.out.println("버튼을 눌러 시동을 겁니다.");
    	}
    	
    }
    
    // 세단
    class SedanClass extends Car {
    
    	public SedanClass(String carType, String carName, String carPrice, String carColor) {
    		super(carType, carName, carPrice, carColor);
    		// TODO Auto-generated constructor stub
    	}
    
    	@Override
    	public void startEngine() {
    		// TODO Auto-generated method stub
    		System.out.println("카드를 올려둡니다.");
    	}
    	
    }
    
    // 슈퍼카
    class SuperCarClass extends Car {
    
    	public SuperCarClass(String carType, String carName, String carPrice, String carColor) {
    		super(carType, carName, carPrice, carColor);
    		// TODO Auto-generated constructor stub
    	}
    
    	@Override
    	public void startEngine() {
    		// TODO Auto-generated method stub
    		System.out.println("지문 인식으로 시동을 겁니다.");
    	}
    	
    }

     

     

    마지막으로는 intetface 에 대해서 설명해 주셨습니다.

     

    Interface

    추상 메서드만 가지고 있는 요소입니다.

    기본적으로 자바에서 클래스는 하나의 클래스만 상속 받을 수 있습니다.

    하지만 여러 타입의 변수에 담을 수 있도록 사용하는 것이 Interface 입니다.

    Interface 는 다중 상속을 지원하기 위해 제공되는 것이 절대 아닙니다.

    하나의 클래스는 다수의 Interface를 구성 할 수 있습니다.

     

    Interface 내 메서드는 static를 명시하지 않는 이상  추상 메서드 입니다.

    이때   abstract 키워드는 적지 않아도 됩니다.

     

    Interface 내 정의한 변수는 static final 변수입니다.

     

    Interface를 구현한 클래스 만들 때

    클래스 명  뒤에 implements 구현하려는 인터페이스명 을 적어줍니다 

    이때 구현하려는 인터페이스가 여러개 일 경우 ',' 을 사용하여 구현하는 인터페이스를 모두 적어 줍니다.

    혹시 많을 경우에는 하나의 인터페이스에 여러개의 인터페이스를 상속받은 다음 상속 받은 인터페이스를

    적어주면 됩니다.

     

    인터페이스를 구성한 클래스를 생성할 경우 클래스 안에서는 구현한 인터페이스들의 추상 메소드를 모두 오버라이딩 해야 합니다.

     

    예제는 하기 코드에 기재 하였습니다.

     

    package com.studty.lst;
    
    import com.test.main.TestClass1;
    import com.test.main.TestInterface1;
    import com.test.main.TestInterface2;
    
    public class Study3 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub		
    		
    		// 인터페이스에 정의한 변수 사용
    		System.out.printf("TestInterface1.a : %d\n", TestInterface1.a);
    		// 인터페이스에 정의한 메서드 사용
    		TestInterface1.interfaceM2();
    		// 인터페이스를 구현한 클래스를 사용하여 객체 생성
    		TestClass1 t1 = new TestClass1();
    		TestClass2 t2 = new TestClass2();
    		// 인터페이스를 구현한 클래스를 사용하여 생성한 객체를 이용하여
    		// 오버라이딩 한 메서드 사용
    		t1.interfaceM1();
    		
    		t2.interfaceM1();
    		t2.interfaceM3();
    		
    		// 클래스가 구현한 인터페이스 타입형 변수에 담을 수 있다.
    		TestInterface1 t10 = new TestClass1();
    		t10.interfaceM1();
    		
    		TestInterface2 t20 = new TestClass2();
    		t20.interfaceM3();
    
    	}
    
    }
    
    interface TestInterface1{
    	// 인터페이스에 정의한 변수는 static final 변수이다.
    	int a = 100;
    	
    	// 인터페이스에 정의한 메서드는 기본적으로 추상 메서드 이다.
    	public void interfaceM1();
    	
    	// 인터페이스에 메서드를 정의할 대 static 메서드를 사용할 수 있다.
    	public static void interfaceM2() {
    		System.out.println("TestInterface1 내 static를 이용하여 생성한 메서드");
    	}
    	
    }
    
    interface TestInterface2{
    	// 인터페이스에 정의한 변수는 static final 변수이다.
    	int b = 100;
    	
    	// 인터페이스에 정의한 메서드는 기본적으로 추상 메서드 이다.
    	public void interfaceM3();
    	
    	// 인터페이스에 메서드를 정의할 대 static 메서드를 사용할 수 있다.
    	public static void interfaceM4() {
    		System.out.println("TestInterface2 내 static를 이용하여 생성한 메서드");
    	}
    	
    }
    
    // 인터페이스를 구현한 클래스
    // 클래스 내 오버라이딩을 하지 않으면 에러가 발생한다.
    class TestClass1 implements TestInterface1{
    	
    	@Override
    	public void interfaceM1() {
    		// TODO Auto-generated method stub
    		System.out.println("TestInterface1를 구현한 클래스1");
    	}
    	
    }
    
    //인터페이스를 다수 구현한 클래스
    class TestClass2 implements TestInterface1, TestInterface2{
    	
    	@Override
    	public void interfaceM1() {
    		// TODO Auto-generated method stub
    		System.out.println("TestInterface1를 구현한 클래스2");
    	}
    
    	@Override
    	public void interfaceM3() {
    		// TODO Auto-generated method stub
    		System.out.println("TestInterface2를 구현한 클래스2");
    	}
    	
    }
    
    
    // 인터페이스의 인터페이스 상속
    // 자주 구현해야하는 인터페이스들이 많을 경우
    // 하나의 인터페이스에 모두 상속 시키고
    // 상속 받은 인터페이스 하나만 클래스에 구현하면 편하게 사용 할 수 있다.
    
    interface Inter1{
    	public void method1();
    }
    
    interface Inter2{
    	public void method2();
    }
    
    interface Inter3{
    	public void method3();
    }
    
    // 인터페이스 Inter1~3 까지 상속 받은 인터페이스
    interface Inter4 extends Inter1, Inter2, Inter3{
    	public void method4();
    }
    
    // 여러 인터페이스를 상속 받은 인터페이스를 구현하는 클래스 생성
    // 여러 인터페이스에 있는 추상 메서드를 오버라이딩 해야함.
    class TestClass3 implements Inter4{
    
    	@Override
    	public void method1() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void method2() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void method3() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void method4() {
    		// TODO Auto-generated method stub
    		
    	}
    	
    }
    출력 결과
    TestInterface1.a : 100
    TestInterface1 내 static를 이용하여 생성한 메서드
    TestInterface1를 구현한 클래스1
    TestInterface1를 구현한 클래스2
    TestInterface2를 구현한 클래스2
    TestInterface1를 구현한 클래스1
    TestInterface2를 구현한 클래스2

     

    마무리

     

    확실히 시간이 점점 갈수록 내용이 어려워 지지만 기초를 제대로 모르는 상태로 추후 안드로이드 개발을 하고 싶지 않기에 어렵더라도 기초를 튼튼하게 다지고 넘어 갈 수 있도록 하겠습니다.

     

    일단 오늘 가장 만족스러운 점은 아직 개선할 점도 많고, 기존 코드를 편집하며 사용하였지만 원하는 형태의 출력이 나올 수 있도록 소통하며 코드를 작성했다는 점 입니다. 즉, 아직 성장 가능성이 많이 있다라고 긍정적으로 생각합니다.

     

    요즘 강의를 들으면서 점점 더 열심히 해야겠다라는 생각이 많이 드는게 내가 선택해놓고 열심히 하지 않으면 나중에 무엇을 열심히 할 수 있을까? 라는 생각이 들어 스스로 뭔가 더 열심히 하게 되는 것 같습니다.

    그래서 아마 과거의 저라면 이렇게 당일 배운 내용을 그냥 휘발성 메모리 마냥 잊어 버렸을 것 같은데 지금은 비휘발성 메모리에  저장 할 수 있도록 노력하고 있는 것 같습니다.  그리고 내용은 어렵지만 재밌다라는 생각이 들기도 합니다ㅋㅋㅋ

     

     

Designed by Tistory.