[ review 복습 ]
- OOP(Object Oriented Program) or OOAD (Analysis and Design 분석설계)
: 객체를 시스템의 기본단위로 상정하고,
객체와 객체의 관계를 중심으로 분석설계하는 기법 - Object : 시스템의 기본 단위, 속성과 기능으로 구성
* 속성 : attribute, variable, field
* 기능 : operation, method, function - Class와 Object의 관계
: Class는 붕어빵 틀(설계도), Object(instance)는 붕어빵
객체지향의 주요개념
- Encapsulation
: "public interface, private implementation"
: 인터페이스는 공개하고, 구현부는 감춘다 - Inheritance (상속)
: 부모 클래스(객체)의 멤버(속성, 기능)을 물려받아 사용
: 장점) 1. 재사용성 증대 → 생산성 향상
2. 계층구조 형성을 통한 다형성(polymorphism) 적용 환경 제공
[ Inheritance 상속 ]
- 부모의 멤버(속성, 기능)를 자식이 물려받아 사용
→ 재사용성 증대(생산성 향상) - 계층구조 형성을 통한 다형성(polymorphism) 적용환경을 제공
부모 클래스 → super class
자식 클래스 → sub class
UML(통합 모델링 언어) 중 Class Diaram 상에서
상속관계는 일반화 generalization (is a relationship)로 표현한다.
참고)
- association 연관 (use a)
- aggregation 집합 (has a)
- composition 구성 (consist of)
- generalization 상속 (is a)
부모 클래스 (super class) : Employee
자식 클래스 (sub class) : Secretary / Manager / Engineer
* 부모클래스의 attribute 변수 : empNo, name, salary
- 접근제어자 : # (protected) / 같은 클래스 내 접근만 가능하나, 상속인 경우에는 접근가능하다.
* private의 경우 상속은 가능하나, 접근이 불가하기에 settet/getter가 필요하다.
* 각 자식 클래스의 attribute 변수 : nameOfBoss , department, skill
- 접근제어자 : - (private) /보안을 위해 private으로 지정하였다.
접근 제어자(Access Modifier)
public > protected > default > private
public : 어디서나 접근 가능
protected : 동일한 패키지 내에서 접근 가능하나, 상속 관계시에는 어디서나 접근 가능
default : 동일한 패키지 내에서만 접근 가능
private: : 동일한 클래스 내에서만 접근 가능 (다른 클래스에서 접근하려면, getter/setter를 이용하여 접근하여야 한다)
extends
: 부모 Class or Object를 확장하여 자식 Class or Object에 정의한다.
: 확장을 위한 java keyword이기 때문에 extends class는 특정 기능을 추가하고 싶을때에만 사용한다.
class Dog extends Animal {} Dog : 자식 class (sub class) extends : 부모 class를 자식 class에 상속해주는 java keyword Animal : 부모 class (super class) |
extends 사용 예시
class Animal{
int age = 100;
public void eat() {
System.out.println("먹다");
}
}
//Animal을 상속받아보자
class Person extends Animal{
// 부모 Animal에 없는 기능을 자식 class에 구현할 수 있다
public void study() {
System.out.println(("사람이 공부하다"));
}
}
public class TestInheritance1 {
public static void main(String[] args) {
// 자식 Person 객체를 생성
Person p = new Person();
p.eat(); //상속받았으므로 사용가능
System.out.println(p.age); //상속받았으므로 사용가능
p.study(); //자신의 메서드 당연히 사용가능
}
}
super ()
: 자식 클래스(sub class)의 생성자 안에 들어가게 된다. (java keyword 중 하나이다.)
- 생성자의 첫라인에 명시되는 코드
- 별도로 super(); 키워드를 명시하지 않으면, 자동삽입이 default이다.
: 부모 생성자(super class)를 호출해서, 부모객체를 실행하는 역할을 한다.
* this : 현재 객체를 호출하는 키워드
* super : 부모 객체를 호출하는 키워드
* super() : 부모 생성자를 호출하여 부모 객체를 생성
class A { A() { super();} } |
다른 main이 있는 실행 클래스에서 new B()를 실행하면,
B 객체에 앞서 A 객체 생성 후 B 객체 생성된다.
** 별도로 super(); 키워드를 명시하지 않으면, 자동삽입이 default이다.
** 만약 부모 생성자(super class의 constructor)에 매개변수가 있다면,
super() 키워드 내에 부모 생성자의 매개변수를 입력해주어야 한다.
super 사용 예시 1
//super class
class Animal {
Animal(){
System.out.println("Animal 객체 생성");
}
public void eat() {
System.out.println("먹다");
}
}
//sub class
class Person extends Animal {
// 생성자(constuctor) 명시
Person() {
super(); //없으면 컴파일시에 자동 삽임
//super()는 부모 생성자를 실행해서 부모객체를 실행하는 역할
System.out.println("Person class의 객체 생성");
}
}
// 실행 class
public class TestSuper {
public static void main(String[] args) {
// 객체 생성 (-> 생성자실행)
new Person();
/* 출력값
* Animal 객체 생성
* Person class의 객체 생성
*/
}
}
super 사용 예시 2
// GrandParent class : super class
class GrandParent{
public GrandParent() {
//super(); //여기에도 숨어있다.
System.out.println("조부모 객체 생성");
}
}
// Parent class : GrandParent의 sub class / Child의 super class
// GrandParent -> Parent 상속
class Parent extends GrandParent{
public Parent() {
super(); // 자동생성됨(생략가능)
System.out.println("부모 객체 생성");
}
}
// Child class : Parent의 sub class
// Parent -> child 상속
class Child extends Parent{
public Child() {
//super();
System.out.println("자식 객체 생성");
}
}
// 실행 class
public class TestSuper2 {
public static void main(String[] args) {
new Child();
/* 출력값
* 조부모 객체 생성
* 부모 객체 생성
* 자식 객체 생성
*/
}
}
super 사용 예시 3
// super class
class Animal{
int age;
Animal(int age){
this.age = age;
}
}
// sub class
class Person extends Animal{
String name;
Person(String name, int age){
//super();
/* error
* : super는 즉 Animal의 생성자이기 때문에,
* (sub class내의 super()는 super class의 생성자이다)
* 생성자 생성 시 필수 요소인
* 매개변수 int age를 넣어야한다.
*/
super(age);
/*
* 이 경우에는 super();로 자동생성 되기때문에,
* 부모 클래스 생성자의 매개변수를 넣은
* super(매개변수); 를 반드시 넣어줘야 한다.
*/
this.name = name;
}
}
// 실행 class
public class TestSuper3 {
public static void main(String[] args) {
Person p = new Person("아이유", 28);
System.out.println(p.name+" "+p.age);
}
}
Method Overriding(메서드 오버라이딩)
: 부모 메서드를 자식에 맞게 구현부를 재정의하는 기법
*사용하는 이유?
: User Interface 사용자의 편의성을 증대하기 위해 사용한다. *사용자(client code까지 포함)
: 동일한 메서드명(=사용법이 동일하다/호출방법이 같으므로)
* 오버로딩 overloading과의 차이점
: method overloading 이란 ? 동일한 이름의 메서드를 매개변수를 다양하게 하여 여러 개 정의하는 기법
* 매개변수의 다양성 => 다양한 정보를 처리 가능
: method overriding은? 상속받은 부모 메서드를 자신에 맞게 재정의
* 부모 메서드의 구현부 재정의
* 메서드명, 리턴타입은 부모, 자식 동일 / 접근제어자는 좁아지면 안됨(부모 public, 자식 private 불가)
method overriding 사용 예제
// super class
class Animal{
public void eat() {
System.out.println("먹다");
}
}
// sub class 1
class Person extends Animal{
Person() {super();} // 생성자는 생략 가능하다.
// 메서드 오버라이딩 : 부모 메서드를 자신에 맞게 재정의
public void eat() {
System.out.println("수저를 이용");
super.eat(); // 부모 메서드를 이용
}
}
// sub class 2
class Dog extends Animal{
}
// 실행 class
public class TestOverriding {
public static void main(String[] args) {
System.out.println("**Person 실행**");
Person p = new Person();
p.eat();
System.out.println("\n**Dog 실행**");
Dog d = new Dog();
d.eat();
/* 출력 :
* **Person 실행**
* 수저를 이용
* 먹다
* **Dog 실행**
* 먹다
*/
}
}
java.lang 라이브러리
java.lang.Object
: java 클래스의 최상위 클래스 (java 계층구조의 root)
> 특정한 클래스를 상속받지 않으면, 자동으로 extends Object를 통해 Object 클래스를 상속받게 된다.
즉, 모든 자바 클래스(객체)는 Object의 자식이 된다.
* 모든 자바 클래스(객체)는 Object의 기능을 가지게 된다.
**
java.lang 라이브러리(패키지)는 자동으로 실행이 되기 때문에,
java.lang.Object는 Object만 적어도 진행이 된다. (String 또한 java.lang안에 포함된 것이다.)
[ java.lang.Object의 메서드들 ]
- getclass()
> 어느 class로부터 가져온 객체인지 확인 - toString()
> 기본 기능 : 객체의 주소값을 반환해줌
> 주기능 : 자식 class에서 toString() 메서드를 오버라이딩해서 사용
* 실제값(객체의 속성정보)을 반환하도록 재정의해서 사용한다.
java.lang 사용 예제 1 ( getclass() )
// super class
class Parent { // extends Object
Parent() {
super(); // 생략가능=자동생성 (생성자 매개변수가 없으면)
System.out.println("Parent 객체 생성");
}
}
// sub class
class Child extends Parent {
Child() { // 생략가능=자동생성
super(); // 생략가능=자동생성 (생성자 매개변수가 없으면)
System.out.println("Child 객체 생성");
}
}
class Car {
}
// 실행 class
public class TestObjectClass {
public static void main(String[] args) {
Child c = new Child();
/* 출력값 :
* Parent 객체 생성
* Child 객체 생성
*/
// getClass(): 어느 class로부터 가져온 객체인지 확인
System.out.println(c.getClass());
/* 출력값 :
* class step1.Child
*/
Car car = new Car();
System.out.println(car.getClass());
/* 출력값 :
* class step1.Car
*/
}
}
java.lang 사용 예제 2 ( toString() )
class Employee{
public String empId;
public String name;
public Employee(String empId, String name) {
super(); //Object class의 기능 호출
this.empId = empId;
this.name = name;
}
// toString()의 기능을 실제값(객체의 속성정보)을 반환하도록 재정의해준다.
@Override
public String toString() {
return "Employee [empId=" + empId + ", name=" + name + "]";
}
}
// 실행 class
public class TestToString2 {
public static void main(String[] args) {
Employee e = new Employee("200", "마우스");
// Employee 에서 toStrng()을 오버라이딩 했으므로,
// 오버라이딩한 자신의 메서드가 호출된다.
System.out.println(e); //println()메서드가 내부적으로 toString()을 호출
System.out.println(e.toString());
// 위 두 라인은 동일한 결과를 출력
/* 출력값:
* Employee [empId=200, name=마우스]
* Employee [empId=200, name=마우스]
*/
}
}
* 참고 링크 )
https://docs.oracle.com/javase/8/docs/api/
▶ super 사용 예시 3의 실행 순서
- 처음에 실행 class의 main method로 가게 됨
- person p = new Person() 명령을 통해,
> Heap 메모리 영역에 Person과 Animal이 저장된다.
*사실은 Object → Animal → Person순으로 저장된다. (Heap영역에 제일 먼저 생성되는 것은 Object이다)
> person p 객체에 new Person의 Heap 메모리에 저장된 것의 주소를 Stack 메모리에 저장하게 됨. - Person class로 가게 됨.
- super()를 통해 부모 클래스(Parent)의 생성자에 가서, 부모 객체를 호출하게됨
- Parent의 super를 통해 Animal class의 부모 생성자를 찾게 됨. 그러나 별도의 상속관계 표현이 없기 때문에 자동으로 상속관계를 준다.
- Animal class는 Object class를 상속한 것이다. (class Animal = class Parent extends Object)
* 모든 java의 class는 Object class를 상속받은 것이다.
* Object class는 최상위 클래스이다.