본문 바로가기
정처기 실기 문제풀이

자바 58

by moca7 2024. 4. 18.

ㅁ c언어는 절차적인 언어라 줄줄줄줄 읽다가 함수 만나면 가서 읽고 그러면 됐다. 

- 그런데 자바는 객체지향 언어. 줄줄줄 읽는게 아님. 객체를 생성하고, 객체 안엔 멤버 변수가 있고, 상속도 있고, 오버로딩-오버라이딩 등이 존재한다.

 

ㅁ 클래스의 이름 car와 동일한 이름을 가진 메소드를 생성자라고 함. 

- 그 외에는 멤버 변수메서드다.

- 멤버 변수는 그 클래스가 가진 고유한 값

- 생성자는 기본적으로 세팅이 되는거. 생성할 때. (객체를 생성할 때 호출되는 특별한 메서드)

- 멤버변수는 세미콜론으로 끝나고 메서드나 생성자는 중괄호로 끝남.

 

ㅁ 실제 자바 문제를 풀 때는 main부터 보면 된다.

 

ㅁ 1번 예제 - 1

- this.name = name; 

클래스의 name에 인자로 받은 name 값을 대입하는 게 아니고, 지금 만든 myCar라는 인스턴스의 name에 넣는 거다. 

- 그리고 인자로 받은 name과 speed는 지역변수다. 괄호 안에 있는건 다 지역변수임.

- public car가 끝나면서 인자로 받은 name과 speed는 사라지게 됨.

- 왜 printinfo()에는 this.name이 아니고 그냥 name이냐. this.name이어도 됨. 아니어도 되고.

name과 speed는 대입하려는 거랑 대입받는 변수 이름이 똑같아서 this.으로 표시한거임.  

 

ㅁ 1번 예제 - 2

- Car mycar;

이렇게 끝나면 이름만 있고 사용할 순 없음

그 클래스에 있는 변수들 못 씀. 없음

- setname에는 this.을 붙여줬고 setspeed에는 안붙였음. 변수명이 달라서 ㄱㅊ. this.speed 해도 됨.

 

자바에서 print를 하면 옆에 그대로 이어쓰고, println을 하면 프린트하고 엔터친다.

 

1.

 

- q=p;

p가 100번지일 때, q도 100번지를 참조한다. 

- 두번째 꺼는 this. 안붙였음. 붙여도 되고. 첫번째 거는 이름이 같이니 붙이고. 

- p.print(); 인스턴스 p에서 프린트를 한다.

 

2.

 

- int k1이 아닌 ink k라고 했어도 이 void main에서의 k랑 함수 sum에서의 k는 완전히 다른 거다. 

- a 전역변수.

- 프린트니까 밑으로 쓰면 안 됨. 그대로 옆에다가 이어서 써야 함.

 

ㅁ 2번 예제

 

- public은 어디서든 접근 가능하지만, private은 직접 접근이 안되서 myCar.speed=100; 이렇게 사용 불가.

타 클래스의 private한 요소에 직접 접근해서. 오류 남.

- myCar.speed=100; 이게 없었다면 그 다음 print에서 차량속도: 까지만 출력이 된다. 

- setspeed는 가능. 왜냐면 이건 public 이기 때문.

- 자바에서 기본적으로 생성한 객체를 출력하면 toString이 호출된다.

- 출력 결과는 name은 없으므로 거기는 비어있다.

(보통 string은 null, int는 0이 들어감)

 

4.

 

- 이건 생성자 문제. 아버지는 나를 낳을 수 있지만 나는 아버지를 낳을 수 없다

- 클래스 c라는게 있는거고, 또 그 다음들이 있는거. 각각으로. 

- class CS extends C{}

CS가 C를 상속 받음. CS가 C의 자식이 되는거. 

- 인터페이스는 추상클래스의 극단이다.

- class CI extends C implements I {}

CI가 C를 상속받고, CI가 I를 구현함.

- static은 큰 의미 없음 다. 

- static I i = new CI();

이거 오타인줄 알았는데 그게 아니고 I도 아버지다. I가 CI를 낳는거 가능. 

 

5.

 

- 다 쓸 수 있는줄 알았는데 아니었음.

- a3는 a2만 상속받았지만, a2가 a1을 상속받은 상태라, 최종적으로 a3는 a2, a1 다 가능

- protected는 상속받으면 그냥 접근 가능

private은 그 클래스 내에서만 가능. 상속받아도 상관없이 안 됨

- private이어도 상속받으면 자식클래스에서 그 변수 값은 있는데 사용이 불가능할 뿐.

 

6.

 

- 상속받으면 그 멤버변수, 메서드, 생성자?가 다 그 클래스에 있는 판정인 듯.

- subject1 클래스에서 a가 protected가 아닌 private이어도, sub.fun1()은 1000 출력함. 

subject1 클래스의 fun1()이라는 함수를 이용했으니까. (같은 클래스)

sub.fun2()는 오류 발생. a 못 쓰니까. (다른 클래스에서)

- 오류 안나려면, subject1에 public getA() {return a;}하고, subject2의 fun2() {return getA()/b}면 가능.

 

ㅁ 3번 예제

- 생성자 인자값이 없어도, 클래스명이랑 이름이 같으면 호출되니까 인자값 없이 객체 생성해도, 생성자 있으면 그 메서드 실행해야함. 

- 하나의 클래스에 car라는 이름의 두 개의 생성자가 존재 가능(인자 없는 생성자, 인자 있는 거)

- 인자 2개의 생성자를 2개 만들 수는 없고.

- 객체 생성을 car()와 car("~", ~) 가능.

- 그냥 system.out.println();은 뭐냐. 그냥 엔터치란 거임. 

 

- 생성자는 한번만 호출 가능.

- 근데 강제적으로 호출도 가능. 어떻게? 

생성자 car("~", ~)메서드 중괄호 안에, this();하고 mycar2하면, this();는 나의 인자값없는 생성자를 말함.

그럼 car()수행하고 내것들 함. 

- 생성자 car() 메서드 중괄호 안에 this("a", 50)하고 mycar1하면, 위와 똑같이 나의 인자값있는 생성자 호출함.

여기서 a랑 50을 mycar1에 넣음.

 

ㅁ 4번 예제(상속 - 생성자)

- 상속 - 생성자는, 부모부터 수행하는건 맞는데 자식을 먼저 봐야 해요. 

- Dog bDog = new Dog()

그냥 dog a! 출력하는게 아님.

생성된 객체의, 생성자가, 상속을 받은 경우, 묵시적으로 부모의 인자없는 생성자를 호출함 먼저.

[출력결과]

Animal A!

Dog A!

- Dog aDog = new Dog("말티즈")

이건 묵시적으로 부모의 인자없는 생성자를 먼저 호출하지 않음.

super가 있어서? 암튼 super는 부모 클래스 말하는 듯. 
(super로 명시적으로 부모를 호출하고 있으면 그걸로 하고 아니면 인자없는 부모 호출

[출력결과]

Animal A!

Dog A!

Animal B!

Dog B!

 

8.

 

- A b = new C(1000);

가능함. c가 c를 낳는거 가능, b가 c를 낳는거 가능, a가 c를 낳는 거 가능. 부모가 자식을 낳는거 가능. 반대는 불가.

그냥 C를 생성한다고 보면 되는듯.

= A는 나중에 하이딩, 변수의 유효범위할 때 신겨쓰는거. 

-

1) 객체 생성.

2) 인자값 있이 생성하면 생성자가 있다는 뜻. 

3) 그 생성자를 바로 수행하는게 아니고, 상속여부를 확인

4) 상속받고 있는게 있으면, 자식클래스에서 super()로 부모를 명시적으로 호출하는지 확인.

5) 그렇지 않다면 부모의 인자없는 생성자 호출

6) 부모의 인자없는 생성자도 바로 수행하지 않고, 상속여부 확인 후 똑같이 반복

7) 부모 먼저 다 하고 태초의 자식 클래스 생성자 실행. 

- super는 조부모 말고 부모만 말함.

= 그런데, super보다도 this있으면 this 먼저함. this의 중괄호 안에 super 있으면 그거 먼저 하고, 

super 없으면 부모의 인자값없는 생성자 먼저 실행하고, this 중괄호 안 실행하고, 내 생성자로 돌아옴.

 

10. 

 

- B가 A를 상속받으면, B에는 B이 멤버변수들과 A의 멤버변수들이 다 있다. private이면 못 쓸뿐

 

11.

 

- 부모를 명시적으로 호출하지 않는데도, 부모의 인자없는 생성자를 호출하지 않음.

this()있으면 이것먼저 함.

- 부모 호출은 클래스당 1번만 함. 여러번 생성자가 호출되도 한번했으면 부모 생성자 호출 안하는 듯. 

= 자식 클래스에서 부모 클래스의 생성자는 한번만 호출할 ㅅ ㅜ있다.

 

12.

 

- main은 어디있든 상관없음. 그거부터 시작하면 됨. 

- 변수의 유효범위. 

b1엔 A의 a 10, B의 a 20이 있음. b2에도 A의 a 10, B의 a 20이 있음. 

이렇게 중복일 땐 맨 왼쪽걸 찾아가는거.

- B b1 = new B(); 이거는 B의 변수

A b2 = new B(); 이거는 A의 변수 

 

13.

 

- 일단 this가 나왔으면 거기에 부모 생성자 호출이 있든 없든 일단 this 먼저

this에 갔는데 부모 생성자 호출이 없으면 부모의 인자가 없는 디폴트 생성자로 감.

그러고 나서 this.x = x; 함. 무조건 부모 생성자 호출이 먼저네.

- this는 그 해당하는 클래스라고 보시면 되는 거에요.

전에는 인스턴스가 this라면서요. 그때는 클래스 하나만 썼으니까요. 

= this로 다른 생성자에게 super를 호출하는걸 위임하게 됨.

- 이 문제에서 자식클래스에도 getX();가 있다면 메서드 오버라이딩임.

메서드 오버라이딩 형태면 어떤 형태든 오버라이딩 된 메서드를 호출함. 

이런 문제 풀어봤는데 오버라이딩이란거 못깨달음 ㅋㅋ. 

인스턴스화하고, 인스턴스화 한거의 메서드를 실행하는데, 그게 부모에도 있고 나에도 있으면 그게 오버라이딩. 

 

ㅁ 5번 예제(오버로딩)

- 오버로딩은 추상화와 관련 있음. 추상화는 오버로딩, 오버라이딩과 연관됨.

- 오버로딩: a(), a(x), a(x, y)

- 오버라이딩: 상속을 받았는데 자식에서 상속받은 메서드를 재정의하는 거. 

= 오버로딩: 같은 이름의 메소드를 매개변수의 개수 또는 타입(자료형)에 따라 여러번 정의하는 것

 

15.

 

- float cal(float a, float b)과 double cal(double a, double b) 이렇게 있으면 둘 중 뭐를 실행하냐.

c도 자바도 기본적으로 형태를 지정하지 않으면 실수는 double이다. 

- a.cal(24.8, 5.1)말고 a.cal((float)24.8, (float)5.1)이렇게 형변환하면 float으로 감.

 

16.

 

- 틀린 이유. 3.4+5.6 한걸 return하는데 그냥 9라고 생각함. 9.0이다!! 실수 더하기 실수는 실수다. 

- 이문제는 왜 객체화안하고 그냥 바로 실행이 가능하냐.

static 메서드여서. static 변수, static 메서드는 그냥 프로그램 실행하자마자 메모리 상에 올라감. 

 

ㅁ 6번 예제(오버라이딩)

- 오버로딩과 오버라이딩 전부 메서드에 대한 걸 얘기하는 거지, 멤버변수랑은 상관없다.

- 멤버변수는 클래스 안에서 선언된 변수

매개 변수는 지역변수의 일종으로, 메서드를 호출할 때 값을 넣는 거. 메서드 안에서만 유효. 끝나면 사라짐. 

 

- public void speek() {

super.speak();

system.out.println("멍멍!");

오버라이딩 했는데 자식에서 이런 경우, super.speak()를 실행하고나서 돌아와서 자식에 있는 멍멍도 출력함. 

 

ㅁ 7번 예제(하이딩)

- 상위 클래스의 static 메서드를 하위 클래스에서 같은 유형으로 다시 선언하는 것.

하이딩된 메서드는 메서드 호출이 클래스 타입에 따라 결정된다. 

- 생긴건 오버라이딩처럼 생겼어, 근데 앞에 static 붙으면 그건 오버라이딩이 아니라 하이딩임.

오버라이딩처럼 움직이진 않아요.

- 클래스 타입이란건 앞에 있는거를 말함. 

 

- 오버라이딩은 자식에 있는 메서드를 호출 했음. 

하이딩은 객체생성할 때 왼쪽에 뭐가 왔냐. 누가 낳았냐가 결정함. 변수의 유효범위와 같이. 중복일 때.

 

20.

 

- 매개변수가 x, y인지 i, j인지 이런게 중요한건 아님. 메서드명이 같고, 자료형과 인자 개수가 같으면 오버라이딩.

 

22.

 

- 제대로 안보고 또 조부모-부모-자식인줄 알았는데 부모-자식, 부모-자식이었다. 

- void 보고 하이딩인줄 알았음. void가 아니라 static이 하이딩이다!!!!!!!!

 

ㅁ 8번 예제(변수의 유효범위)

- 변수는 오버로딩, 오버라이딩 아님. 메서드고 그건. 

- 1번 문제. Child in = new Child()일 때, in.printNames()하면 변수의 유효범위&하이딩처럼 왼쪽 클래스 보고 결정하는줄 알았는데, 아니었음. (중복된 변수면 유효범위를 따지는데, 메서드는 오버라이딩 or 하이딩)

이건 변수가 아님. 메서드임. 메서드는 그냥 그 클래스 내에서 실행되고, 그 클래스의 변수를 쓰고 없으면 부모 클래스의 변수를 씀. 

 

23.

 

- 조부모-부모-자식인 경우에서, 자식에 멤버변수가 없는데 부모와 조부모에 중복으로 있을 경우, 자식 기준에서 가까운 부모걸 가져온다. 

 

24.

 

- 틀린이유. 단순 실수. return num인데 return 1이라고 나혼자 생각해버림.

 

ㅁ 9번, 10번 예제(추상클래스, 인터페이스)

- 그냥 추상클래스와 인터페이스는 객체를 생성하지 못한다. 라고만 알아두심 돼요.

이거 가지고 문제가 막 출제되는건 아님. 

- 추상클래스 : 부분적으로 구현된 클래스. 하나 이상의 추상 메서드(구현되지 않은 메서드)를 포함한다.

상속을 통해 자식 클래스에서 완전히 구현한다. (ex. 리모콘)

(미완성된걸로 객체 구현 불가)

 

- abstract class Animal{

abstract void makesSound();

...}

이런 식. abstract가 클래스앞에 있으면 추상클래스. 

추상 메서드에도 앞에 abstract가 붙어 있다. 추상 메서드는 메서드의 원형만 있게 됨.

- 멤버변수랑 헷갈리지만 아님. abstract 붙어있고, 뒤에 ()도 있고.

- Animal a = new Animal(); 이게 안됨. <- 자식클래스에서 구현해도 안 됨. 얘 자체로는.

Animal a = new 자식클래스(); 이거는 됨. 

 

- 인터페이스 : 모든 메서드가 기본적으로 추상 메서드인 형태. 

interface Vehicle{

 void start();

 void stop(); }

이런식. class도 없네. 

= 구현은 {}가 들어간게 구현이다. 중괄호 안이 비어도 {} 있으면 구현된걸로 보는거라 있으면 에러남.(인터페이스는 모든 추상클래스가 구현 안되어있어야 해서)

- 인터페이스는 추상클래스와 달리 extends 못씀. implements 써야 함. 

- 얘도 당연히 Vehicle v = new Vehicle(); 안됨.

 

29.

 

- 추상 클래스 구현하고 사용하려면 객체.구현한메서드.추상메서드();

그냥 추상메서드만 있으면 사용 못하니까. 앞에 구현한 메서드가 있어야하고, 또 객체 있어야지. 

- 추상클래스는 원래는 extends 써서 예제처럼 해야하는데 문제라 이렇게 나옴.

추상클래스 구현 하고 그 뒤에 {} 써서 그 안에서 추상메서드를 구현.

 

30.

 

- 추상 클래스 Shape

Shape s;

이건 가능함. new를 이용해 객체생성하는게 아니면 가능.

 

31.

 

- intreface인데 메서드 없이 멤버변수만 있는것 가능. 

- a=3;은 main에서만 있는 지역함수다. 

이걸 헷갈리라고 넣어논 거임. 인스턴스 생성하면 나랑 부모, 조부모의 멤버변수들과 메서드를 받는데, 이거 받는거 지역변수는 안받음. 

 

32.

 

- AB ab = new AB();

InterfaceA ia = ab;

인터페이스 ia가 만들어지는데, ab라는 객체를 참조함. 

부모여서 자식을 담는게 가능. 

- 이러면 똑같은 주소를 참조하는거. 그래서 여기서 수정하면 저기서도 수정됨. 

 

ㅁ 예제 11번(예외처리)

- 예외는 오류는 아님. 

- catch()는 여러개일수 있음. 

- finally는 try에서 오류가 있든 없든 실행되어야 하는 것들. 

- throws는 클래스 단에서 표현하는거고, catch단에서 표현하는 건 throw

 

- try{} 에서 예외가 발생할 수도 있고 발생하지 않을 수도 있음. 

예외가 발생하지 않으면 그냥 finally로 빠지는 거고,

예외가 발생하면 catch 블록으로 빠짐. 만약 예외가 발생하면 더이상 밑의 구문은 실행하지 않음. 

- 예외가 발생된 구문에서 예외를 확인한 후 그 뒤의 구문들은 수행하지 않고 바로 catch블록으로. 

- 그리고 finally는 무조건 수행.

- try에 예외가 없으면, 그냥 try에 출력문도 하고, finally 코드도 수행. (catch는 스킵)

 

- throw new exception("");

이거 하면 강제로 예외 발생시킴. catch블록으로 가면 됨 그 클래스의. 

- catch 블록의 throw e;

throw는 예외를 던지는거. 나를 호출한 공간으로 예외를 던진다.

그렇다고 나를 호출한 공간의 다음 문장을 수행하는건 아니고, finally 수행먼저.

- 그럼 main에선 예외가 온거니까 자기의 그 아래 코드는 수행 안하고, 자기도 catch있으니 거기로 빠짐. 

 

- catch 블록의 throw가 없으면 main으로 와서 그 다음 블록이랑, finally 수행. catch ㄴㄴ.

 

33.

 

- 객체 생성만 함 main에서. 생성자 실행한거다.

- try catch finally와 전혀 관계없이 출력문이 있다. 두 블록인거. 

- void method(){} 이거는 오류 아니다. 정상수행이다. 

 

35.

 

- finally 없을 수도 있다. 없으면 안하면 됨. 

- 영분모. 영은 분모가 될 수 없다. 

- 만약 <= ar.length였으면 ar[5]없어서 오류발생.

= 만약 try문에서 오류가 발생했는데, catch가 여러개인 경우엔?

catch는 하나만 수행한다. 여러개 중에서 하나만. 

- exception이 최상위. 그 외에 수학적 예외나 배열 예외 등이 있는 거.

 

- 자바에서 float a = 12/4;

출력 a 하면 3.0이 나옴. 자바에서 실수는 .0인가 봄. 

연산이 먼저고 대입은 나중이다. 

 

ㅁ 예제 12번(객체비교, static 변수, static 메서드 + 유틸 패키지에 있는 클래스들 몇가지)

 

(1) 객체비교

- 객체 두 개를 만들었을 때, 두가지 방법을 사용하여 객체를 비교할 수 있다. 

- equals() 메서드 : 객체의 내용이 같은지 비교

- == ; 두 객체가 같은 주소값을 참조하느냐. 두 객체의 참조가 같은 객체를 가리키고 있는지 확인.

- person1 == person2

내용이 같은걸 두 개 만들어도 주소값이 다르다. 주소값이 같으려면 참조를 해야함. false 출력함. 자바는.

- true, ture.

 

(2) static 변수

= 자바도 그렇고 c언어도 그렇고, static 변수와 static 메소드는 프로그램 시작과 동시에 메모리에 올라간다.

객체 생성안해도 무조건 메모리에 올라간다.

 

= c언어에서의 static 변수와 다르다. 

- static 변수는 클래스의 모든 인스턴스에 걸쳐 공유되는 변수.

- 하나의 인스턴스에서 static 변수의 값을 변경하면, 변경사항이 모든 인스턴스에 반영.

 

- main이 실행되기 전에 이미 static 변수는 만들어져 있음. 그 후에 여러번 초기화해도 무시.

- static 변수는 그냥 클래스명.count해도 사용 가능함. 메모리상에 있어서 객체 안해도.

 

(3) static 메서드

- static 메서드는 인스턴스 변수에 접근할 수 없다.

public int sum;

public static int add(int a, int b){

sum = a+b; return sum; }

오류 남. static 변수와 메소드는 프로그램 시작하자마자 메모리에 올라가기 때문에.

(int a, int b는 인스턴스 변수가 아닌 지역변수라 ㄱㅊ)

 

- static 데이터 멤버나 다른 static 메서드만 호출할 수 있다. (static 메서드 안에서 객체 변수나 객체 메서드를 활용 못 함)

public static sum;

이면 얘도 같이 메모리에 올라가니까 얘는 가능.

 

- static 메서드는 객체를 생성하지 않고 클래스 이름을 통해 직접 호출할 수 있다.

= static 메서드는 별거없고, static 변수는 모든 인스턴스가 공유한다는거 꼭 기억.

 

38. 

 

- new하지 않으면 주소가 같다.

- new하면 객체를 새로 만든거라 주소가 다르다.

 

41.

 

- addLast와 removeFirst가 기본. 

 

44.

 

= ~.clone

~를 복사해서 왼쪽에 집어넣어라.

 

47.

 

- 자바 print는 문자를 만나면 그뒤부터 모든것들을 문자로 인식함. 

- 3+4+"3+2="+3+2

343+2=32

 

49.

 

- 배열은 c언어도 그렇고 자바도 그렇고 call by reference. 주소값이 넘어간거라 값이 바뀐게 다 공유.

 

 

50.

 

int a[][] = {{45,50,74}, {89}}

45 50 74

89 0 아니고 null이네 c언어가 그렇대.

 

= 대부분의 언어가 명령의 대소문자를 구분함. 대소문자를 구분않는건 sql만. 

 

51.

 

- 자바에서 메서드 쓸 때 인스턴스 안만들고 c언어에서 함수호출하는 것처럼 사용하기 위해선 check라는 메서드라 메모리상에 먼저 올라가야함. static 앞에 붙여놔야.

 

52.

 

- if 괄호 안에 &&가 두 개 들어간 논리연산자를 다뤘는데 이번엔 &하나인 비트연산자가 나옴. 그럴 수도 있지.

비트연산자는 논리연산자와 달리 왼쪽만 보고 참거짓을 판단불가.

- 근데 자바 true false

 

55.

 

- 23242 숫자처럼 보이지만 문자임.

- substring(4, 6)이면 배열[4]부터 배열[6]까지 출력.

 

56.

 

- void change와 void display의 인자는 지역변수지만, 값이 아닌 주소값을 받으면 그건 메모리 상의 값이 바뀌는 거라 다 공유된다.

 

58. 

 

- push는 넣는거고 pop은 뽑는거다. 

- stack은 아래가 막혀있다. a, b, c를 넣으면 c를 빼야 b와 a를 뺄 수 있다. 

- 넣을 때는 스택 포인터가 -1부터 보통 시작인데 +1하고 뺀다, 뺄때는 빼고 -1한다.

- push: buf[ ++top ] = x;

pop: return buf[top--];

- 메서드 앞에 int니까 반환하는거죠.

메서드 앞에 void가 아니면 리턴을 해줘야 합니다. 

 

'정처기 실기 문제풀이' 카테고리의 다른 글

C언어 143 58 37  (0) 2024.04.17