9 minute read

7-01 상속

  • 자손 클래스는 조상 클래스의 모든 멤버를 상속받는다. (단, 생성자와 초기화 블럭은 상속되지 않는다.)
  • 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
class Parent { }
class Child extends Parent {

}

7-02 상속 예제

class Tv {
	boolean power;
	int channel;

	void power()       {   power = !power; }
	void channelUp()   {   ++channel;      }
	void channelDown() {   --channel;      }
}

class SmartTv extends Tv {  // 스마트TV는 Tv에 캡션(자막)을 보여주는 기능을 추가
	boolean caption;     // 캡션상태 on/off
	void displayCaption(String text) {
		if (caption) {
			System.out.println(text);
		}
	}
}

class Ex7_1 {
	public static void main(String args[]) {
		SmartTv stv = new SmartTv();
		stv.channel = 10;
		stv.channelUp();
		System.out.println(stv.channel);
		stv.displayCaption("Hello, World");
		stv.caption = true; 
		stv.displayCaption("Hello, World");
	}
}

7-03 클래스 간의 관계 - 포함관계

class Circle {
  int x;  // 원점의 x 좌표
  int y;  // 원점의 y 좌표
  int r;
}

class Point {
  int x;
  int y;
}
class Circle {
  Point c = new Point();  // 원점
  int r;
}

7-04 클래스 간의 관계 결정하기

  • 상속관계 : ‘~은 ~이다.(is-a)’
  • 포함관계 : ‘~은 ~을 가지고 있다.(has-a)’
    class Circle extends Point {  // 상속관계 : 원은 점이다.
    int r;
    }
    
    class Circle {
    Point c = new Point();  // 포함관계 : 원은 점을 가지고 있다.
    int r;
    }
    

7-05 단일 상속(single inheritance)

public TvDVD extends Tv, DVD { // 에러. 조상은 하나만 허용된다.

}

7-06 Object클래스 - 모든 클래스의 조상

  • 모든 클래스 상속계층도의 최상위에 있는 조상클래스이다.
  • 모든 클래스들은 자동적으로 Object클래스로부터 상속받는다.
  • 주요 메서드로는 toString(), equals(Object o) 등이 있다.

7-07 오버라이딩(overriding)

class Point {
  int x;
  int y;
  
  String getLocation() {
    return "x:" + x + "y:" + y;
  }
}

class Point3D extends Point {
  int z;
  
  String getLocation() {  // 오버라이딩
    return "x:" + x + "y:" + y + "z:" + z;
  }
}

7-08 오버라이딩의 조건

  • 조상 클래스의 메서드를 자손 클래스에서 오버라이딩할 때
    • 선언부가 조상 클래스의 메서드와 일치해야 한다.
    • 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
    • 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.

7-09 오버로딩 vs. 오버라이딩

  • 오버로딩 : 기존에 없는 새로운 메서드를 정의하는 것(new)
  • 오버라이딩 : 상속받은 메서드의 내용을 변경하는 것(change, modify)
class Parent {
  void parentMethod() { }
}

class Child extends Parent {
  void parentMethod() { } // 오버라이딩
  void parentMethod(int i) { }  // 오버로딩
  
  void childMethod() { }
  void childMethod(int i) { } // 오버로딩
  void childMethod() { } // 에러. 중복정의 되었음.
}

7-10 참조변수 super

  • super : 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다.
class Ex7_2 {
	public static void main(String args[]) {
		Child c = new Child();
		c.method();
	}
}

class Parent { int x=10; }  // super.x

class Child extends Parent {
	int x=20; // this.x

	void method() {
		System.out.println("x=" + x);
		System.out.println("this.x=" + this.x);
		System.out.println("super.x="+ super.x);
	}
}

결과 x = 20, this.x = 20, super.x = 10


7-11 super() - 조상의 생성자

class Point3D extends Point {
  int z;
  
  Point3D(int x, int y, int z) {
    this.x = x; // 조상의 멤버를 초기화
    this.y = y; // 조상의 멤버를 초기화
    this.z = z;
  }
}
Point3D(int x, int y, int z) {
  super(x, y);  // 조상클래스의 생성자 Point(int x, int y)를 호출
  this.z = z;
}


7-12 패키지(package)

  • 클래스의 묶음이다.

7-13 패키지의 선언

package 패키지명;

7-14 클래스 패스(classpath)


7-15 import문

import 패키지명.클래스명;
import 패키지명.*;

7-16 static import문

  • static멤버를 호출할 때 클래스 이름을 생략할 수 있다.
import static java.lang.System.out;
import static java.lang.Math.*;

class Ex7_6 {
	public static void main(String[] args) {	
		// System.out.println(Math.random());
		out.println(random());

		// System.out.println("Math.PI :"+Math.PI);
		out.println("Math.PI :" + PI);
	}
}

7-17 제어자(modifier)

  • 접근 제어자 : public, protected, (default), private
  • 그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp

7-18 static - 클래스의, 공통적인

  • static이 사용될 수 있는 곳 - 멤버변수, 메서드, 초기화 블럭
class StaticTest {
  static int width = 200; // 클래스 변수(static변수)
  static int height = 120;  // 클래스 변수(static변수)
  
  static {  // 클래스 초기화 블럭
    // static변수의 복잡한 초기화 수행
  }
  
  static int max(int a, int b) {  // 클래스 메서드(static메서드)
    return a > b ? a : b;
  }
}

7-19 final - 마지막의, 변경될 수 없는

  • final이 사용될 수 있는 곳 - 클래스, 메서드, 멤버변수, 지역변수
final class FinalTest { // 조상이 될 수 없는 클래스
  final int MAX_SIZE = 10;  // 값을 변경할 수 없는 멤버변수(상수)
  
  final void getMaxSize() { // 오버라이딩할 수 없는 메서드(변경불가)
    final int LV = MAX_SIZE;  // 값을 변경할 수 없는 지역변수(상수)
    return MAX_SIZE;
  }
}

7-20 abstract - 추상의, 미완성의

  • abstract가 사용될 수 있는 곳 - 클래스, 메서드
abstract class AbstractTest { // 추상 클래스(추상 메서드를 포함한 클래스)
  abstract void move(); // 추상 메서드(구현부가 없는 메서드)
}

7-21 접근 제어자(access modifier)

int add(int x, int y) {
  int result = x + y;
  return result;
}
int add(int x, int y) {
  return x + y;
}

7-22 캡슐화와 접근 제어자

  • 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
  • 메서드가 수행을 마치고 나면 사용했던 메모리를 반환하고 스택에서 제거된다.
  • 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
  • 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.

7-23 다형성(polymorphism)

  • 기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.
  • 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.
class Data { int x; }

class Ex6_6 {
	public static void main(String[] args) {
		Data d = new Data();
		d.x = 10;
		System.out.println("main() : x = " + d.x);

		change(d.x);
		System.out.println("After change(d.x)");
		System.out.println("main() : x = " + d.x);
	}

	static void change(int x) {  // 기본형 매개변수
		x = 1000;
		System.out.println("change() : x = " + x);
	}
}

7-24 참조변수의 형변환

class Data2 { int x; }

class Ex6_7 {
	public static void main(String[] args) {
		Data2 d = new Data2();
		d.x = 10;
		System.out.println("main() : x = " + d.x);

		change(d);
		System.out.println("After change(d)");
		System.out.println("main() : x = " + d.x);
	}

	static void change(Data2 d) { // 참조형 매개변수
		d.x = 1000;
		System.out.println("change() : x = " + d.x);
	}
}

7-25 참조변수의 형변환 예제

class Data3 { int x; }

class Ex6_8 {
	public static void main(String[] args) {
		Data3 d = new Data3();
		d.x = 10;

		Data3 d2 = copy(d); 
		System.out.println("d.x ="+d.x);
		System.out.println("d2.x="+d2.x);
	}

	static Data3 copy(Data3 d) {
		Data3 tmp = new Data3();    // 새로운 객체 tmp를 생성한다.

		tmp.x = d.x;  // d.x의 값을 tmp.x에 복사한다.

		return tmp;   // 복사한 객체의 주소를 반환한다.
	}
}

7-26 instanceof 연산자

메서드 중에서 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 클래스 메서드(static 메서드)로 정의한다.


7-27 매개변수의 다형성

class MyMath2 {
	long a, b;

	// 인스턴스 변수 a, b만을 이용해서 작업하므로 매개변수가 필요없다.
	long add()		{ return a + b; }  // a, b는 인스턴스 변수
	long subtract() { return a - b; }
	long multiply() { return a * b; }
	double divide() { return a / b; }

	// 인스턴스 변수와 관계없이 매개변수만으로 작업이 가능하다.
	static long   add(long a, long b)		 { return a + b; }  // a, b는 지역변수
	static long   subtract(long a, long b)   { return a - b; }
	static long   multiply(long a, long b)   { return a * b; }
	static double divide(long a, long b) { return a / (double)b; }
	
}


class Ex6_9 {
	public static void main(String args[]) {
		// 클래스 메서드 호출. 인스턴스 생성없이 호출가능.
		System.out.println(MyMath2.add(200L, 100L));
		System.out.println(MyMath2.subtract(200L, 100L));
		System.out.println(MyMath2.multiply(200L, 100L));
		System.out.println(MyMath2.divide(200L, 100L));

		MyMath2 mm = new MyMath2(); // 인스턴스를 생성.
		mm.a = 200L;
		mm.b = 100L;
		// 인스턴스 메서드는 객체생성 후에만 호출이 가능함.
		System.out.println(mm.add());
		System.out.println(mm.subtract());
		System.out.println(mm.multiply());
		System.out.println(mm.divide());
   }
}

7-28 매개변수의 다형성 예제

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  2. 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
  4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.

7-29 여러 종류의 객체를 배열로 다루기

  • 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다.
  • 단, 클래스멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.

7-30 여러 종류의 객체를 배열로 다루기 예제

  • 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것
    1. 메서드 이름이 같아야 한다.
    2. 매개변수의 개수 또는 타입이 달라야 한다.
    3. 반환 타입은 관계없다.

7-31 추상 클래스(abstract class)

class Ex6_10 {
	public static void main(String args[]) {
		MyMath3 mm = new MyMath3();
		System.out.println("mm.add(3, 3) 결과:"    + mm.add(3,3));
		System.out.println("mm.add(3L, 3) 결과: "  + mm.add(3L,3));
		System.out.println("mm.add(3, 3L) 결과: "  + mm.add(3,3L));
		System.out.println("mm.add(3L, 3L) 결과: " + mm.add(3L,3L));

		int[] a = {100, 200, 300};
		System.out.println("mm.add(a) 결과: " + mm.add(a));
   }
}

class MyMath3 {
	int add(int a, int b) {
		System.out.print("int add(int a, int b) - ");
		return a+b;
	}
	
	long add(int a, long b) {
		System.out.print("long add(int a, long b) - ");
		return a+b;
	}
	
	long add(long a, int b) {
		System.out.print("long add(long a, int b) - ");
		return a+b;
	}

	long add(long a, long b) {
		System.out.print("long add(long a, long b) - ");
		return a+b;
	}

	int add(int[] a) {		// 배열의 모든 요소의 합을 결과로 돌려준다.
		System.out.print("int add(int[] a) - ");
		int result = 0;
		for(int i=0; i < a.length;i++) 
			result += a[i];
		
		return result;
	}
}

7-32 추상 메서드(abstract method)

  • 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’이다.
    1. 생성자의 이름은 클래스의 이름과 같아야 한다.
    2. 생성자는 리턴 값이 없다.
class Point {
  Point() { // 매개변수가 없는 생성자.
  
  }
  
  Point(int x, int y) { // 매개변수가 있는 생성자.
  
  }
}

7-33 추상클래스의 작성

  • 기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때 뿐이다.

7-34 추상클래스의 작성 예제

class Car {
  String color;
  String gearType;
  int door;
  
  Car() {} // 기본 생성자
  Car(String c, String g, int d) { // 생성자
    color = c;
    gearType = g;
    door = d;
  }
}
// 생성자 Car() 사용한다면
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;
// 생성자 Car(String color, String gearType, int door) 사용한다면
Car c = new Car("white", "auto", 4);

7-35 인터페이스(interface)

  • 인스턴스를 생성할 때는 다음의 2가지 사항을 결정해야 한다.
    1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
    2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
class Car {
	String color;
	String gearType;
	int door;

	Car() {}

	Car(String c, String g, int d) {
		color = c;
		gearType = g;
		door = d;
	}
}

class Ex6_12 {
	public static void main(String[] args) {
		Car c1 = new Car();
		c1.color    = "white";
		c1.gearType = "auto";
		c1.door = 4;

		Car c2 = new Car("white", "auto", 4);

		System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
		System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
	}
}

7-36 인터페이스의 상속

  • 생성자의 이름으로 클래스이름 대신 this를 사용한다.
  • 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
class Car2 {
	String color;
	String gearType;
	int door;

	Car2() {
		this("white", "auto", 4);
	}

	Car2(String color) {
		this(color, "auto", 4);
	}

	Car2(String color, String gearType, int door) {
		this.color = color;
		this.gearType = gearType;
		this.door = door;
	}
}
class Ex6_13 {
	public static void main(String[] args) {
		Car2 c1 = new Car2();	
		Car2 c2 = new Car2("blue");

		System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
		System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
	}
}

7-37 인터페이스의 구현

  • this : 인스턴스 자신을 가리키는 참조변수
  • this(), this(매개변수) : 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
  • this는 ‘참조변수’이고, this()는 ‘생성자’이다.

7-38 인터페이스를 이용한 다형성

  • 멤버변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택이지만, 지역변수의 초기화는 필수이다.
class Test {
  int x;  // 인스턴스 변수
  int y = x;  // 인스턴스 변수
  
  void method1() {
    int i;  // 지역변수
    int j = i;  // 에러. 지역변수를 초기화하지 않고 사용
    }
}

7-39 인터페이스의 장점

  • 명시적 초기화
  • 초기화

7-40 디폴트 메서드와 static

Tags:

Categories:

Updated:

Leave a comment