개념 :
클래스에서 생성자와 비슷한 역할의 초기화 작업을 할 수 있는 2가지 블록이 제공된다. 1) 인스턴스 초기화 블록
개념 :
static 초기화 블록
Date함수 임포트 및 호출 - 내부 메소드 사용 위해서는 임포트 및 객체성생 필요
Math.random 객체 생성할 필요 없이 사용가능한 static 메소드? 클래스?
일단 Math클래스는 java.lang에 포함되어있어서 임포트가 필요없다.
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
Math.random();
Date d = new Date();
}
}
개념
상수는 일반적으로 다음 형식으로 표현한다. public static 지정자를 사용하여 외부에서
객체생성 없이 클래스이름으로 쉽게 접근 가능하도록 구현한다
public static final 데이터형 상수 = 값
예)
은행관리 시스템
은행객체 1개 (반드시 1개의 객체만 생성, 사용하도록 작성 )
계좌객체 100개 (new * 100개)
개념 :
1. private) 기본생성자
2. private) 내부 객체 생성 (static객체)(기본생성자 이용)
3. public) 내부에서 만든 static 객체를 외부로 반환해주는 함수를 하나 만든다.
형식 예제
형식 +
메인에서 하나의 객체를 여러 변수에 할당받고 멤버변수 name을 변경시 서로 다른 변수에서 name 값이 다른지 확인하는 코드
Bank.java
package com.banl;
public class Bank {
private String name;
private static Bank b=new Bank(); //2
private Bank() {} //1
public static Bank getBank() {
return b;
//3
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Test1.java
import com.banl.Bank;
public class Test1 {
public static void main(String[] args) {
Bank b1 = Bank.getBank();
System.out.println(b1);
Bank b2= Bank.getBank();
System.out.println(b2);
b1.setName("kb저축");
System.out.println(b2.getName());
}
}
출력화면
싱글톤 개념 4가지와 static 정독필요
< 목차 >
클래스들의 관계
상속
접근 지정자
(중요)메서드 오버라이딩
(중요)다형성
Object 클래스
UML 관계
개념 :
프로젝트명 : 07Day0_Has_Relation
개념 :
하나의 객체를 멤버변수로 갖는 객체
만약 매개변수를 전당하는 생성자를 클래스 내부에 안썼다면
클래스의 get객체 메소드 호출시 발생하는 문제?
public Student(String string, int i, String string2, Parent p1) {
// TODO Auto-generated constructor stub
}
매개변수를 받아서 저장하는 구문이 없는 생성자가 클래스에 정의되어 있고
이 생성자를 통해서 객체를 생성할 경우 전달한 값들이 저장되지 않아서 기본데이터값들로 저장이 될 것이다. 그럼 getter 메소드로 객체의 객체멤버변수를 가져올 때 null을 반환.
만약 이 null에 메소드체인을 걸면 nullPoint 오류가 발생할 것으로 추정된다.
실행결과 예상과 같은 에러가 발생.
메인
public class Test {
public static void main(String[] args) {
Parent p1 = new Parent("AA", 50);
Student stu = new Student("홍길동", 10, "서울", p1);
Parent parent = stu.getParent();
System.out.println(parent.getpName();
}
Student 클래스
public class Student {
private String name;
private int age;
private String addr;
//has a 관계
private Parent parent;
public void setParent(Parent parent) {
this.parent = parent;
}
public Parent getParent() {
return this.parent;
}
// public Student(String name, int age, String addr, Parent parent) {
// super();
// this.name = name;
// this.age = age;
// this.addr = addr;
// this.parent = parent;
// }
// 전달받은 값을 멤버변수에 저장하는 구문이 없는 생성자.
// 이러면 해당 객체의 멤버객체에 접근하려할 때 주소값이 없고 null이 있으니 null이 가르키는 값이 없다는 뜻의 nullPointer Error가 발생한다.
public Student(String string, int i, String string2, Parent p1) {
}
워크샵 4-문제8 : 카페 워크샵. 난이도 상. 상당히 좋은 문제니 여러번 만들어보는 것을 추천
개념:
부모 class b가 이름, 나이가 있고
A class가 부모class b를 상속받고있다면
A는 이름, 부모를 사용할 수 있다.
모든 클래스의 부모 클래스는 Object 클래스
객체 생성시 부모 객체들이 먼저 생성된다
A객체 생성시
Object -> 부모b ->a 순서로 객체가 생성된다.
객체들 간에 is a 관계가 성립되면 자바의 상속기법을 적용시킬 수 있다. 자바 상속의 특징은 다음과 같다.
§ 객체 간에 is a 관계가 성립되어야 한다.
§ 부모클래스의 멤버(인스턴스 변수, 메서드)를 자식클래스가 선언 없이 사용 가능하다. 단
부모 멤버중에서 private로 지정한 멤버와 생성자는 상속이 불가능하다.
§ 자바는 단일 상속 (Single Inheritance) 만 지원한다.
§ 상속을 UML 표기법으로 을 이용한다. (실선을 이용한 삼각형)
§ 상속을 자바코드에서는 extends 키워드로 표현한다.
§ API 및 사용자가 만든 클래스들은 모두 상속 관계인 계층구조로 되어있다. 가장 상위에
있는 클래스는 java.lang.Object 클래스이며 최상위 클래스라고 부른다. 따라서 모든 클
래스는 Object 클래스를 자연스럽게 상속받는다.
모든 메소드 뒤에는 extends Object가 자동으로 추가되어있다.
오버라이딩 : 부모에있는 함수를 자식에서 재정의하여 쓰는 것
오버로딩 : 이름이 같은 함수의 매개변수 차이를 두어 만드는 것
우클릭 -> source -> override에서 오버라이딩 자동생성이 가능하다.
super() : 부모의 기본생성자를 호출한다.
또한 super();는 자식 기본생성자 호출시 첫 줄에 자동으로 생성됨.
super()생략가능.
만약 부모의 기본생성자가 없다면 오류가 발생.
super() 안에 부모에 있는 특정 생성자와 동일한 형태로 매개변수로 기입하면 해당 생성자를 호출한다.
일반적으로 다음 2가지 경우에 사용된다.
2(중요). 자식클래스에서 명시적으로 부모 생성자를 호출하는 경우 super([인자값]) 형식으로 사용하며 인자값은 없거나 여러 개가 가능하다. 주의할 점은 반드시 자식 생성자의 첫 라인에서 호출해야 된다.
참고로 상속받은 멤버변수들은 this.으로도 사용할 수 있음.
개념:
= 재정의
필수 요건 : 상속된 상태. 하위클래스가 상위클래스의 메소드를 재정의
규칙 :
부모
public void test(int a){}
자식
@override
public void test(int a){
함수 내용만 변경
}
개념 :
일반적으로 상속 관계시 부모 클래스의 메서드를 하위 클래스에서는 조건 없이 사용 가능하
다. 하지만 하위 클래스에서 부모 클래스의 메서드를 재정의해서 사용할 수도 있는데 이렇
게 재정의된 메서드를 overriding 이라고 부른다. 주의할 점은 오버로딩(overloading)과
구별할 수 있어야 된다. 메서드 오버라이딩 규칙은 다음과 같다.
§ 상속이 전제되어야 한다.
§ 메서드 이름이 반드시 동일해야 된다.
§ 메서드 리턴타입이 반드시 동일해야 된다. 단, 상속관계인 경우에는 작은 타입으로 재정
의 가능하다.
§ 메서드 인자 리스트가 반드시 동일해야 된다.
§ 접근 지정자는 부모의 레벨보다 같거나 확대만 가능하다.
§ 예외 클래스는 부모의 클래스보다 계층적으로 같거나 하위 클래스만 사용 가능하다.
§ static, final, private 지정자를 가진 메서드는 오버라이딩이 불가능하다.
이 방법들을 프로그램 코드에서 정말 자주 씀.
다형성 - 폴리몰피즘
: 부모 클래스 타입의 변수로 자식 클래스를 저장할 수 있다.
1) 상속관계가 아닌 경우
Emp Manager
Emp m = new Manager() -- 안됨
2)상속관계인 경우
Manager extends Emp
1) Manager m = new Manager();
2) Emp m2 = new Manager(); // 부모타입 변수에 자식 객체 저장 == 다형성
Emp - name, age
Manager - address
m2는 부모클래스 변수인 name, age를 사용할 수 있다,
하지만 address는 접근이 불가능하다.
address 사용을 위해서는 자식 타입으로 형변환을 해주어야함.
((Manager)m2).address = '제주'
이런 식으로 명시적으로 형변환을 해줘야 사용가능하다.
즉, 상속관계의 계층구조에서 상위타입의 변수로 모든 하위타입을
참조할 수 있는 특성을 ‘다형성’이라고 한다.
< 요약 >
1. 자식은 부모에 그냥 저장됨
2. 자식에 있는 것들을 사용하고싶으면 형변환을 하고 사용해라
부모타입에 저장된 자식객체는 자식에 접근을 못한다.
하지만 만약에 부모객체 메소드가 있고 자식객체에서 오버라이딩한 상태라면
해당 메소드를 쓸 때 부모객체의 메소드를 사용하지만 오버라이딩된 실제 객체의 오버라이딩 메소드가 호출된다.
왜 중요한 개념인가? :
예를들면
부모의 자식으로 3개 타입의 객체가 있다. 각각 100개씩
이 여러개의 전체 데이터를 출력하고싶다.
다형성을 이용하면 부모타입의 배열에 이 3개 타입의 객체를 각각 100개씩 다 때려넣어서 저장할 수 있다.
그리고 자식에서 출력할 함수를 부모 함수 오버라이딩 구현해두면
부모 배열 하나에 자식객체를 저장하고 메소드까지 편하게 사용가능.
// 1. 다형성을 이용한 부모 타입 배열에 자식 객체 저장 가능
// 2. 자식에서 출력함수를 부모 함수 오버라이딩 구현 ex) getEmployee
// 따라서 정말 편해짐.
public class Test2 {
public void change(Employee e) {
}
public static void main(String[] args) {
Employee e = new Employee();
Manager m = new Manager();
Engineer en = new Engineer();
Test2 t = new Test2();
t.change(e);
t.change(m);
t.change(en);
}
}
만약 상속관계가 아니라면 아래처럼 만들어줘야한다.
package com.test;
public class Test {
public void change(Employee e) {
}
public void change(Manager e) {
}
public void change(Engineer e) {
}
public static void main(String[] args) {
Employee e = new Employee();
Manager m = new Manager();
Engineer en = new Engineer();
Test t = new Test();
t.change(e);
t.change(m);
t.change(en);
}
}
내일은 다형성 매개변수 연습할 차례