- overloading : 매서드명은 동일하나 매개변수의 타입, 수량, 순서를 달리하여 만들어진 메서드
- override : 기각하다.
- overriding : 최우선시 되는
- 상속은 부모클래스의 맴버를 자식클래스가 사용하게 함. 그러나 상속된 메서드가 자식클래스 입장에서 부족한 부분이 있을 수 있음. 그래서 자식클래스에서 새로 정의함
- 부모클래스의 메서드와 동일(리턴타입, 매서드명, 매개변수의 타입, 수량, 순서 모두 동일)한 메서드를 자식클래스가 재정의 함.
오버라이딩 상태의 메서드를 호출하면 무조건 자식 클래스의 메서드가 실행
package sec03;
public class Calculator {
public double areaCircle(double r) {
System.out.println("Calculator 객체의 areaCircle() 실행");
return 3.14159 * r * r;
}
}
// 다른 클래스
package sec03;
public class Computer extends Calculator{
public double areaCircle(double r) {
System.out.println("Computer 객체의 areaCircle() 실행");
return Math.PI * r * r;
}
}
// 다른 클래스
package sec03;
public class ComputerExample {
public static void main(String[] args) {
int r = 10;
Calculator cal = new Calculator();
System.out.println("원 면적 : " + cal.areaCircle(r));
System.out.println();
Computer com = new Computer();
System.out.println("원 면적 : " + com.areaCircle(r));
}
}
- 상속관계의 클래스간에는 형반환이 가능. 단. 부모타입 변수 = 자식타입 변수
- 부모 타입으로 자동 형변환되면 부모클래스 맴버만 사용 가능하다.
- 자식클래스 부분은 있지만 못 본다.
- 단, 오버라이딩 메서드가 호출된다면 부모클래스의 메서드가 아닌 자식클래스의 메서드가 실행 된다.(다형성)
package sec06;
class A {
}
class B extends A {
}
class C extends A {
}
class D extends B {
}
class E extends C {
}
public class PromotionExample {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
E e = new E();
A a1 = b;
A a2 = c;
A a3 = d;
A a4 = e;
B b1 = d;
C c1 = e;
// B b3 = e; 이 둘은 에러
// C c2 = d;
}
}
- 자식 타입은 부모 타입으로 자동 변환되지만. 반대로 부모 타입은 지식 타입으로 자동 변환되지 않는다. 대신 다음과 같이 캐스팅 연산자로 강제 타입 변환을 할 수 있다.
- 그렇다고 해서 부모 타입 객체를 자식 타입으로 무조건 강제 변환할 있는 것은 아니다. 자식 객체가 부모 타입으로 자동 변환된 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있다.
Parent parent = new Child(); // 자동 타입 변환 Child child = (Child) parent; // 강제 타입 변환 (캐스팅)
package sec07;
public class Parent {
public String field1;
public void method1() {
System.out.println("Parent-method1()");
}
public void method2() {
System.out.println("Parent-method2()");
}
}
// 다른 클래스
package sec07;
public class Child extends Parent{
public String field2;
public void method3() {
System.out.println("Child-method3()");
}
}
// 다른 클래스
package sec07;
public class ChildExample {
public static void main(String[] args) {
Parent parent = new Child();
parent.field1 = "data1";
parent.method1();
parent.method2();
/*
parent.field2 = "data2"; err
parent.method3();
*/
Child child = (Child) parent; // 캐스팅
child.field2 = "data2";
child.method3();
}
}
- 매개변수가 아니더라도 변수가 참조하는 객체의 타입을 확인하고자 할 때. instanceof 연산자를 사용할 수 있다. instanceof 연산자의 좌항에는 객체가 오고 우항에는 타입이 오는데. 좌항의 객체가 우항의 타입이 true를 산출하고 그렇지 않으면 false 산출한다.
boolean result = 객체 instanceof 타입
- Java 12부터는 instanceof 연산의 결과가 true 경우. 우측 타입 변수를 사용할 있기 때문에 강제 타입 변환이 필요 없다.
package sec10;
public class Person {
public String name;
public Person(String name) {
this.name = name;
}
public void walk() {
System.out.println("걷습니다.");
}
}
// 다른 클래스
package sec10;
public class Student extends Person {
public int studentNo;
public Student(String name, int studentNo) {
super(name);
this.studentNo = studentNo;
}
public void study() {
System.out.println("공부를 합니다.");
}
}
// 다른 클래스
package sec10;
public class InstanceofExample {
public static void personInfo(Person person) {
System.out.println("name : " + person.name);
person.walk();
if(person instanceof Student student) {
System.out.println("studentNo : " + student.studentNo);
student.study();
}
}
public static void main(String[] args) {
Person p1 = new Person("홍길동");
personInfo(p1);
System.out.println();
Person p2 = new Student("김길동", 10);
personInfo(p2);
}
}
1. 자바의 상속에 대한 설명 중 틀린 것은 무엇입니까?
1. 자바는 다중 상속을 허용한다.
2. 부모의 메소드를 자식 클래스에서 재정의(오버라이딩)할 수 있다.
3. 부모의 private 접근 제한을 갖는 필드와 메소드는 상속의 대상이 아니다.
4. final 클래스는 상속할 수 없고, final 메소드는 오버라이딩할 수 없다.
☞ 1번 : 자바는 다른 언어와 달리 다중 상속을 허용하지 않는다. -> 하나만 상속 가능
2. 클래스 타입 변환에 대한 설명 중 틀린 것은 무엇입니까?
1. 자식 객체는 부모 타입으로 자동 타입 변환된다.
2. 부모 객체는 항상 자식 타입으로 강제 타입 변환된다.
3. 자동 타입 변환을 이용해서 필드와 매개 변수의 다형성을 구현한다.
4. 강제 타입 변환 전에 instanceof 연산자로 변환 가능한지 검사하는 것이 좋다.
☞ 2번 : 강제 타입 변환은 부모 클래스 타입으로 변환된 자식 객체만 가능하다.
3. final 키워드에 대한 설명으로 틀린 것은?
1. final 클래스는 부모 클래스로 사용할 수 있다.
2. final 필드는 값이 저장된 후에는 변경할 수 없다.
3. final 메소드는 재정의(오버라이딩)할 수 없다.
4. static final 필드는 상수를 말한다.
☞ 1번 : final 클래스는 부모 클래스로 사용할 수 있다. 클래스를 선언할 때 final 키워드를
class 앞에 붙이게 되면 이 클래스는 최종적인 클래스이므로 상속할 수 없는 클래스가 된다.
대표적인 예 ) 자바 표준 API에서 제공하는 String클래스
4. 오버라이딩(Overriding)에 대한 설명으로 틀린 것은?
1. 부모 메소드의 시그니처(리턴 타입, 메소드명, 매개 변수)와 동일해야 한다.
2. 부모 메소드보다 좁은 접근 제한자를 붙일 수 없다. (ex: public(부모) -> private(자식))
3. @Override 어노테이션을 사용하면 재정의가 확실한지 컴파일러가 검증한다.
4. protected 접근 제한을 갖는 메소드는 다른 패키지의 자식 클래스에서 재정의할 수 없다.
☞ 4번 : protected 접근 제한을 갖는 메소드는 다른 패키지의 자식 클래스에서 재정의할 수 없다.
protected : 같은 패키지 또는 다른 패키지내의 상속받은 자식 클래스에서 사용 가능
6. Parent 클래스를 상속해서 Child 클래스를 다음과 같이 작성했는데, Child 클래스의 생성자에서 컴파일 에러가 발생했습니다. 그 이유를 설명해보세요.
public class Parent{
public String name;
//생성자
public Parent(String name){
this.name = name;
}
}
public class Child extends Parent{
private int studentNo;
public Child(String name, int studentNo){
//this.name = name; (X)
super(name); // 부모 생성자 호출
this.studentNo = studentNo;
}
}
7. Parent 클래스를 상속받아 Child 클래스를 다음과 같이 작성했습니다. ChildExample 클래스를 실행했을 때 호출되는 각 클래스의 생성자의 순서를 생각하면서 출력 결과를 작성해보세요.
public class Parent{
public String nation;
// 부모 생성자1
public Parent(){
this("대한민국"); // 자신의 생성자 호출 (부모 생성자 2 호출)
System.out.println("Parent() call");
}
// 부모 생성자2
public Parent(String nation){
this.nation = nation;
System.out.println("Parent(String nation) call");
}
}
public class Shild extends Parent{
private String name;
//자식 생성자 1
public Child(){
// super(); // 컴파일 시 자동 생성 (부모 생성자 1 호출)
this("홍길동"); // 자신의 생성자 호출 (자식 생성자 2)
System.out.println("Child() call");
}
//자식 생성자 2
public Child(String name){
this.name = name;
System.out.println("Child(String name) call");
}
}
public class ChildExample{
public static void main(String[] args){
Child child = new Child();
}
}
☞ 실행 순서 : 부모생성자2 > 부모생성자1 > 자식생성자2 > 자식생성자1
접근 순서 : 자식생성자1 > 부모생성자1 > 부모생성자2 > 자식생성자2
8. Tire 클래스를 상속받아 SnowTire 클래스를 다음과 같이 작성했습니다. SnowTireExample 클래스를 실행했을 때 출력 결과는 무엇일까요?
public class Tire{
public void run(){
System.out.println("일반 타이어가 굴러갑니다.");
}
}
public class SnowTire extends Tire{
@Override
public void run(){
System.out.println("스노우 타이어가 굴러갑니다.");
}
}
public class SnowTireExample {
public static void main(String[] args){
SnowTire snowTire = new SnowTire();
Tire tire = snowTire; // 자동 타입 변환 (= Tire tire = new SnowTire();)
snowTire.run();
tire.run();
}
}
☞ snowTire.run() > 스노우 타이어가 굴러갑니다 출력
tire.run() > 스노우 타이어가 굴럽갑니다 출력
tire : 부모 클래스에 정의된 필드, 메소드 , 자식클래스에서 오버라이딩된 메소드 사용가능
9. A, B, C, D, E, F 클래스가 다음과 같이 상속 관계에 있을 때 다음 빈칸에 들어올 수 없는 코드는 ?
B b = □
메소드 선언 : void method(B b) {......} 상속 관계 : D, E -> B -> A
메소드 호출 : method(□) F -> C -> A
1. new B( )
2. (B) new A( ) // 강제 타입 변환
3. new D( ) // 자동 타입 변환
4. new E( ) // 자동 타입 변환
☞ 2번 : 강제 타입 변환은 자식 타입이 부모 타입으로 자동 변환 되어 있을 경우만 가능
ex) **부모클래스 변수명1 = new 자식클래스();
자식클래스 변수명2 = (자식클래스) 변수명1;**