[정보처리기사 실기]_JAVA언어 특강(6)
49번
class A{
String str;
public A(String str) {
this.str = str;
}
public String toString() {
return "aa" + str + "aa";
}
}
class Test {
public static void main(String[] args) {
A a = new A("bbb");
A b = new A("ccc");
System.out.println(a);
System.out.println(b);
System.out.println(a.str);
System.out.println(b.str);
}
}
1) class A
① String str : 문자열을 저장하기 위한 인스턴스 변수 str 생성.
② 생성자 A(String str) : 이 생성자는 인수로 받은 문자열을 인스턴스 변수 str에 저장.
String str의 str과 this.str의 str과 같고,
생성자 A(String str)의 str이랑 =str의 str과 같음.
public A는 생성자이고, public String toString()은 toString() 메서드를 재정의 한 것.
③ toString() 메서드 : 이 메서드는 객체가 출력될 때 호출되고, str 값을 포함한 형식의 문자열을 반환.
2) class Test
① A a = new A("bbb"); → "bbb"라는 문자열을 인수로 받아 A객체 a를 생성.
② A b = new A("ccc"); → "ccc"라는 문자열을 인수로 받아 A객체 b를 생성.
3) 출력
① System.out.println(a); → a 객체의 toString() 메서드가 호출되어 "aabbbaa"가 출력.
② System.out.println(b); → b 객체의 toString() 메서드가 호출되어 "aacccaa"가 출력.
③ System.out.println(a.str); → a 객체의 str 멤버 변수 값을 직접 출력하므로 "bbb" 출력.
④ System.out.println(b.str); → b 객체의 str 멤버 변수 값을 직접 출력하므로 "ccc" 출력.
[출력]
aabbbaa
aacccaa
bbb
ccc
a.str과 같이 멤버 변수에 직접 접근하는 경우에는 a객체의 str 멤버 변수 값을 반환함.
이 때는 toString 메서드가 직접 호출되지 않음. 그러나 System.out.println(a);와 같이 레퍼런스 변수만을 사용하여 객체를 출력할 때는 Java는 해당 객체를 문자열로 변환하기 위해 toString 메서드를 자동으로 호출함.
50번
public class Feline {
public static void main(String[] args) {
Long x = 42L;
Long y = 44L;
System.out.println(" " + 7 + 2 + " ");
System.out.println(foo() + x + 5 + " ");
System.out.println(x + y + foo());
}
static String foo() {
return "foo";
}
}
1) Long x = 42L; Long y = 44L;
: Long 타입 변수 x, y 선언하면서 각각 42L, 44L로 초기화.
2) System.out.println(" " + 7 + 2 + " ");
: 문자열 " "과 7, 2들 더하면 _72_. 앞에 문자열로 시작하여 출력하면 뒤에 숫자가 있더라도 문자열로 변한 되어 출력함.
3) System.out.println(foo() + x + 5 + " ");
: foo() 메서드가 호출되어 "foo"를 반환함. x = 42L이므로 foo() + x + 5 = "foo" + 42 + 5 = foo425로 출력.
4) System.out.println(x + y + foo());
: x + y = 42L + 44L = 86, foo() 메서드 호출되어 "foo"를 반환하므로 86 + "foo" = 86foo를 출력.
5) 정적 메서드 foo : 호출 시 'foo"라는 문자열을 반환하는 메서드.
[출력]
72
foo425
86foo
51번
class Test {
public static void main(String[] args) {
int a = 245;
String str = "245";
String value = String.valueOf(a);
if (str.equals(value))
a = 100;
else
a = 200;
System.out.println(a);
}
}
1) itn a = 245;
: 정수형 변수 a 선언하면서 245로 초기화.
2) String str = "245";
: 문자열형 변수 str 선언하면서 "245"로 초기화.
3) String value = String.valueOf(a);
: 정수 a를 문자열로 변환하며 value에 저장.
4) str.equals(value)
; str과 value의 내용을 비교하여 같은 값이면 참(true). 현재 str에는 "245", value에는 "245"로 두 문자열이 같기 때문에 참(true)을 반환.
5) 출력
: 결과는 참이어서 a = 100;을 반환함. 따라서 a의 값을 출력하면 100을 출력.
[출력]
100
52번
class Division {
public static void main(String[] args) {
int a, b, result;
a = 3;
b = 0;
try {
result = a / b;
System.out.print("A");
}
catch (ArithmeticException e) {
System.out.print("B");
}
finally {
System.out.print("C");
}
System.out.print("D");
}
}
1) int a, b, result;
: 정수형 변수 a, b, result 선언.
2) a = 3; b = 0;
: a는 3으로 b는 0으로 초기화.
3) try - catch - finally
try는 예외가 발생할지 발생하지 않을 지 모르는 코드 블록 정의
catch는 try 블록 내부에서 예외가 발생할 경우 호출되는 문장 블록
finally는 try 블록에서 일어난 일에 관계없이 항상 실행이 보장되어야 할 뒷정리용 코드
따라서 finally가 있으면 무조건 실행이 되어야 하고, catch나 finally 블록은 생략 가능.
try는 catch나 finally 중 적어도 하나 이상의 블록과 함께 사용되어야 함.
그리고 try가 실행되면 catch는 실행이 되지 않고, try가 실행되지 않으면 catch가 실행됨.
① result = a / b;
: a = 3, b = 0으로 3 / 0에서 0으로 나눌 수 없으므로 예외가 발생하여 catch 블록이 실행됨.
② catch 블록에서 실행된 B를 출력.
③ finally 블록은 예외 발생 여부 상관 없이 항상 실행되므로 C를 출력.
④ try - catch - finally 블록이 끝난 후 마지막 출력문에서 D를 출력
[출력]
BCD
// 예외가 발생하지 않았다면 ACD가 출력됨.
53번
public class A {
public static String s = "";
public static void f(int a) {
try {
s += "1";
if (a == 1) throw new Exception();
s += "2";
}
catch (Exception e) {
s += "3";
return;
}
finally {
s += "4";
}
s += "5";
}
public static void main(String[] args) {
f(2);
f(1);
System.out.println(s);
}
}
1) public static String s = "";
: 정적 문자열 변수 s 선언하면서 초기화. 이 변수는 모든 호출에서 동일한 인스턴스를 공유.
2) main 메서드 : 첫 번째 호출 f(2) : 메서드 f로 가면 a는 2.
3) 메서드 f(int a) : 매개변수 a에 따라 예외처리 수행하므로 현재 a = 2.
4) try - catch - finally (a = 2)
① try
ⅰ. s += "1"; → 항상 실행됨. 따라서 s = "1".
ⅱ. if문 : a == 1 이면 예외발생. 현재 a는 2이므로 예외가 발생하지 않고 다음 문장 실행.
ⅲ. s += "2"; → s는 현재 1이 저장되어 있고 다음에 2를 저장하므로 s = "12".
② finally : try 블록이 실행되었으므로 catch 블록은 실행되지 않고 finally 블록으로 실행. 따라서 s += "4" 계산하면 s = "124".
③ try - catch - finally 블록이 모두 끝나고 마지막 s += "5"도 실행되어야 하므로 s = "1245"
5) main 메서드 : 두 번째 호출 f(1) : 메서드 f로 가면 a는 1.
6) 메서드 f(int a) : 매개변수 a에 따라서 예외처리 수행하므로 현재 a = 1.
6) try - catch - finally (a = 1)
① try
ⅰ : s += "1"; → 항상 실행되므로 s += "1" 계산하면 s = "12451"
ⅱ. if문 : a == 1 이면 예외 발생하여 catch 블록 실행하는데 현재 a = 1이므로 예외 발생하여 catch 블록 실행
② catch
ⅰ. s += "3" 실행하면 s = "124513"
ⅱ. return 문으로 인해 메서드 종료.
③ finally
ⅰ. finally 블록이 있으면 항상 실행되므로 s += "4"를 실행하면 s = "1245134".
ⅱ. 메서드가 예외로 인해 중단되고, 반환됨.
[출력]
1245134
54번
public class B extends A {
int a = 20;
public B() {
System.out.print("다");
}
public B(int x) {
System.out.print("라");
}
}
public class A {
int a = 10;
public A() {
System.out.print("가");
}
public A(int x) {
System.out.print("나");
}
public static void main(String[] args) {
B b1 = new B();
A b2 = new B(1);
System.out.println(b1.a + b2.a);
}
}
1) class A
① int a = 10; → 인스턴스 변수 a 선언하면서 10으로 초기화.
② public A() : 기본 생성자로, 호출 시 "가"를 출력.
③ public A(int x) : 매개변수 받는 생성자로, 호출 시 "나"를 출력.
2) class B
① int a = 20; → 인스턴스 변수 a 선언하면서 20으로 초기화.
② public B() : 기본 생성자로, 호출 시 "다"를 출력.
③ public B(int x) : 매개변수 받는 생성자로, 호출 시 "라"를 출력.
3) main 메서드
① B b1 = new B();
ⅰ. B의 기본 생성자 호출.
ⅱ B의 기본 생성자 실행 되기 전에 A의 기본 생성자가 호출.
→ 그 이유는 B는 A를 상속받기 때문에 상위 클래스의 기본 생성자를 먼저 호출하고 하위 클래스의 생성자를 호출함.
ⅲ. 따라서 상위클래스 A의 기본생성자인 "가"를 출력하고, 하위클래스 B의 기본생성자인 "다"를 호출. (출력 : 가다)
② A b2 = new B();
ⅰ. B의 매개변수 받는 생성자 호출.
ⅱ. 생성자 실행 전에 A의 기본 생성자가 호출.
→ 매개변수가 있어서 A 클래스의 매개변수 있는 생성자로 갈 수 있지만 this나 super가 없으면 기본생성자로 가서 출력해야 함.
ⅲ. 따라서 상위클래스 A의 기본 생성자인 "가"를 출력하고, 하위클래스의 B의 매개변수 받는 생성자를 실행하므로 "라"를 출력. (출력: 가라)
4) System.out.println(b1.a + b2.a);
① b1.a는 B의 인스턴스 변수로 class B에 있는 인스턴스 변수의 값을 출력하므로 20.
② b2.a는 A의 인스턴스 변수로 class A에 있는 인스턴스 변수의 값을 출력하므로 10.
③ 따라서 b1.a + b2.a = 20 + 10 = 30
[출력]
가다가라30
55번
class Super {
Super() {
System.out.print('A');
}
Super(char x) {
System.out.print(x);
}
}
class Sub extends Super {
Sub() {
super();
System.out.print('B');
}
Sub(char x) {
this();
System.out.print(x);
}
}
public class Test {
public static void main(String[] args) {
Super s1 = new Super('C');
Super s2 = new Sub('D');
}
}
1) class Super
① 생성자 Super() : 기본 생성자로, 호출 시 문자 'A'를 출력.
② 생성자 Super(char x) : 매개변수 받는 생성자로, 호출 시 전달된 문자를 출력
2) class Sub : Sub 클래스는 Super 클래스를 상속받음.
① 생성자 Sub() :
ⅰ. 기본 생성자로, 먼저 super()를 호출하는데 super()는 부모 클래스의 기본 생성자를 실행.
ⅱ. 부모의 기본 생성자 실행 후 문자 'B'를 출력.
② 생성자 Sub(char x) :
ⅰ. 매개변수 받는 생성자로, this()를 호출하여 Sub()의 기본생성자를 호출하여 기본 생성자를 실행 후, 전달 된 문자를 출력.
3) class Test
① Super s1 = new Super('C');
ⅰ. Super(char x) 생성자가 호출.
ⅱ. 전달된 문자 'C'가 출력되므로 'C'를 출력.
② Super s2 = new Super('D');
ⅰ. Sub(char x) 생성자가 호출.
ⅱ. 이 생성자는 먼저 this()를 호출하므로, 자신의 기본생성자 즉 Sub()의 기본생성자를 호출.
ⅲ. Sub() 생성자에서 super()가 호출되므로 상위클래스인 Super()의 기본생성자를 호출하여 실행. 따라서 'A'를 출력.
ⅳ. 다시 내려와 Sub() 기본 생성자에서 'B'를 출력.
ⅴ. Sub(char x)의 매개변수 값인 'D'를 출력.
[출력]
CABD
! 강의 보며 혼자 공부한 것으로,
틀린 거 있을 시 댓글로 가르쳐 주시면 감사하겠습니다!