어서와 Java 는처음이지! 제 7 장상속 Super 키워드 상속과생성자 상속과다형성
서브클래스의객체가생성될때, 서브클래스의생성자만호출될까? 아니면수퍼클래스의생성자도호출되는가?
class Base{ public Base(String msg) { System.out.println("Base() 생성자 "); ; class Derived extends Base { public Derived() { System.out.println("Derived() 생성자 "); ; public class Test { public static void main(string[] args) { Derived r = new Derived(); ;
생성자의호출순서는 ( 부모클래스의생성자 ) -> ( 자식클래스의생성자 ) 순으로된다.
super 를이용하여서명시적으로수퍼클래스의생성자호출 class Shape { ; public class Rectangle extends Shape { ; public Shape(String msg) { public Rectangle(){ System.out.println("Shape 생성자 () " + msg); super("from Rectangle"); // 명시적인호출 System.out.println("Rectangle 생성자 ()");
class Shape { public Shape(String msg) { System.out.println("Shape 생성자 ()"); ; class Rectangle extends Shape { public Rectangle() { ; System.out.println("Rectangle 생성자 ()"); 1 부터 10 까지의정수의합 = 55 Shape 생성자 Rectangle 생성자
다형성 (polymorphism) 이란객체들의타입이다르면똑같은메시지가전달되더라도서로다른동작을하는것
클래스 A 의참조변수로클래스 B 의객체를참조할수는없다. class A { A() { class B { B() { public class TypeTest1 { public static void main(string args[]) { A a = new B(); // NO!
부모클래스의참조변수는자식클래스의객체를참조할수있다! class A { A() { class B extends A { B() { public class TypeTest1 { public static void main(string args[]) { A a = new B(); // OK!
하나의예로 Rectangle, Triangle, Circle 등의도형클래스가부모클래스인 Shape 클래스로부터상속되었다고가정하자.
class Shape { protected int x, y; class Rectangle extends Shape { private int width, height; class Triangle extends Shape { private int base, height; class Circle extends Shape { private int radius;
public class ShapeTest { public static void main(string arg[]) { Shape s1, s2; s1 = new Shape(); // 1 당연하다. s2 = new Rectangle(); // 2 Rectangle 객체를 // Shape 변수로가리킬수있을까?
서브클래스객체는수퍼클래스객체를포함하고있기때문이다.
public class ShapeTest { public static void main(string arg[]) { Shape s= new Rectangle(); Rectangle r = new Rectangle(); s.x = 0; s.y = 0; s.width = 100; s.height = 100; 1 부터 10 까지의정수의합 = 55 width cannot be resolved or is not a field height cannot be resolved or is not a field 컴파일오류가발생한다. s 를통해서는 Rectangle 클래스의필드와메소드에접근할수없다.
Shape s = new Rectangle(); s 를통하여 Rectangle 클래스의필드와메소드를사용하고자할때는어떻게하여야하는가? ((Rectangle) s).setwidth(100);
서브클래스참조변수로수퍼클래스객체를참조하는것으로일반적인상황에서는컴파일오류이다. Rectangle r; r = new Shape(); // NOT OK!
만약서브클래스객체인데형변환에의하여일시적으로수퍼클래스참조변수에의하여참조되고있는경우는가능 Rectangle r; Shape s; s = new Rectangle(); r = (Rectangle)s; r->width = 100; r->height = 100;
다형성은객체들이동일한메시지를받더라도각객체의타입에따라서서로다른동작을하는것
class Shape { protected int x, y; public void draw() { System.out.println("Shape Draw"); class Rectangle extends Shape { private int width, height; public void draw() { System.out.println("Rectangle Draw");
class Triangle extends Shape { private int base, height; public void draw() { System.out.println("Triangle Draw"); class Circle extends Shape { private int radius; public void draw() { System.out.println("Circle Draw");
public class ShapeTest { public static void main(string arg[]) { Shape s1, s2, s3, s4; s1 = new Shape(); s2 = new Rectangle(); s3 = new Triangle(); s4 = new Circle(); s1.draw(); s2.draw(); s3.draw(); s4.draw();
Shape Draw Rectangle Draw Triangle Draw Circle Draw
메소드호출을실제메소드의몸체와연결하는것을바인딩 (binding) 이라고한다. 자바가상머신 (JVM) 은실행단계에서객체의타입을보고적절한메소드를호출하게된다. 이것을동적바인딩 (dynamic binding) 또는가상메소드호출 (virtual method invocation) 이라고한다.
public class ShapeTest { private static Shape arrayofshapes[]; public static void main(string arg[]) { init(); drawall(); public static void init() { arrayofshapes = new Shape[3]; arrayofshapes[0] = new Rectangle(); arrayofshapes[1] = new Triangle(); arrayofshapes[2] = new Circle(); public static void drawall() { for (int i = 0; i < arrayofshapes.length; i++) { arrayofshapes[i].draw();
Rectangle Draw Triangle Draw Circle Draw
class Cylinder extends Shape { private int radius, height; public void draw(){ System.out.println("Cylinder Draw"); 위와같은새로운클래스가추가되더라도다른코드는변경할필요가없다.
메소드의매개변수로부모클래스참조변수를이용한다. -> 다형성을이용하는전형적인방법
public class ShapeTest { public static void printlocation(shape s) { System.out.println("x=" + s.x + " y=" + s.y); public static void main(string arg[]) { Rectangle s1 = new Rectangle(); Triangle s2 = new Triangle(); Circle s3 = new Circle(); printlocation(s1); printlocation(s2); printlocation(s3);
강아지와고양이를나타내는클래스를작성하자. 이들클래스의부모클래스로 Animal 클래스를정의한다. 강아지와고양이클래스의 sound() 메소드를호출하면각동물들의소리가출력되도록프로그램을작성해보자. Animal 클래스의 sound() 멍멍야옹
class Animal { void sound() { System.out.println("Animal 클래스의 sound()"); class Dog extends Animal { void sound() { System.out.println(" 멍멍 "); class Cat extends Animal { void sound() { System.out.println(" 야옹 ");
public class DynamicCallTest { public static void main(string args[]) { Animal animal = new Animal(); Dog dog = new Dog(); Cat cat = new Cat(); Animal obj; obj = animal; obj.sound(); obj = dog; obj.sound(); obj = cat; obj.sound();
is-a 관계 : ~ 은 ~ 이다 와같은관계 상속은 is-a 관계이다. 자동차는탈것이다 (Car is a Vehicle). 강아지는동물이다 (Dog is a animal).