메인 클래스 동작 방식
static
*Call Static Fame Area
package fc.java.part3;
public class StaticTest {
public static void main(String[] args) {
int a=10;
int b=20;
int sum = StaticTest.hap(a,b);
System.out.println("sum = " + sum);
}
//매개변수로 2개 정수 입력 받아 총합 구해 리턴
public static int hap(int a, int b){
int v=a+b;
return v;
}
}
static 메서드 접근 방법 = 클래스이름.호출메서드
static 멤버는 클래스를 사용하는 시점에서 자동으로 static - zone에 로딩 됨.
new를 이용해 객체 생성할 필요 없음
none-static 메서드 접근 방법
*Method Area
*Heap Area
객체 생성을 막는 방법 : 생성자를 private으로
package fc.java.part3;
public class NoneStaticTest {
public static void main(String[] args) {
int a=10;
int b=20;
NoneStaticTest st = new NoneStaticTest();
int sum=st.hap(a,b);
System.out.println("sum = " + sum);
}
public int hap(int a, int b){
int v=a+b;
return v;
}
}
package fc.java.model;
public class MyUtil {
public static int hap (int a, int b) {
int v = a+b;
return v;
}
}
package fc.java.part3;
import fc.java.model.MyUtil;
public class StaticAccess {
public static void main(String[] args) {
int a = 10;
int b = 20;
int sum = MyUtil.hap(a,b);
System.out.println(sum);
}
}
package fc.java.model;
public class MyUtil1 {
public int hap(int a, int b){
int v = a+b;
return v;
}
}
package fc.java.part3;
import fc.java.model.MyUtil1;
public class NoneStaticAccess {
public static void main(String[] args) {
int a = 10;
int b = 20;
MyUtil1 my1 = new MyUtil1();
int sum = my1.hap(a,b);
System.out.println("sum = " + sum);
}
}
JVM의 Memery model (Runtime Data Area)
Method Area
Heap Area Generation
Stack Area (Call Stack Frame Area)
Runtime Constant Pool (Literal Pool)
package fc.java.model;
public class AllStatic {
public static int hap(int a, int b) {
int v = a + b;
return v;
}
public static int max(int a, int b) {
return a > b ? a : b;
}
public static int min(int a, int b) {
return a < b ? a : b;
}
}
package fc.java.part3;
import fc.java.model.AllStatic;
public class AllStaticTest {
public static void main(String[] args) {
AllStaticTest st = new AllStaticTest();
System.out.println(AllStatic.hap(10, 20));
System.out.println(AllStatic.hap(10, 20));
System.out.println(AllStatic.hap(10, 20));
System.out.println(Math.max(30, 60));
System.out.println(Math.max(40, 10));
}
}
클래스: 객체를 모델링 하는 도구(설계도)
Object(객체)
→ 객체 변수: 변수가 구체적인 실체(대상)을 가리키지 않는 상태, 객체가 서로 구분 안되는 시점
Instance(인스턴스, 실체): 객체 생성에 의해 메모리(Heap Memory)에 만들어진 객체
→ 인스턴스 변수: 객체가 구체적인 실체를 가리키는 상태, 객체가 서로 구분이 되는 시점
package fc.java.part3;
import fc.java.model.Student;
public class ClassObjectInstance {
public static void main(String[] args) {
Student st1 = new Student("홍길동", "컴퓨터공학부", 37, "bit@empas.com", 2023110, "010-1111-2222");
Student st2 = new Student("김길동", "컴퓨터공학부", 27, "bit@empas.com", 2023111, "010-2222-1111");
Student st3 = new Student("이길동", "컴퓨터공학부", 17, "bit@empas.com", 2023112, "010-2112-1221");
System.out.println(st1.toString());
System.out.println(st2.toString());
System.out.println(st3.toString());
}
}
상속
객체를 설계하다 보면 비슷한 클래스의 경우 중복 요소 발생 가능
객체를 수평적인 구조로 설계할 시 단점
수직적구조 = 계층화 = 상속 = 클래스와 클래스의 관계 설계
객체를 수직적인 구조로 설계할 시 장점
상속 : UML(Unified Modeling Language) - 다이어그램
super class(상위 클래스, 부모 클래스) - 일반화, 추상화, 개념화, 포괄적
↑ extends(상속, 확장) = 상속에서 사용하는 키워드
sub class(하위 클래스, 자식 클래스, 파생 클래스) - 구체화, 세분화
super() → 상위클래스의 생성자를 호출
package fc.java.part4;
public class Employee {
protected String name;
protected int age;
protected String phone;
protected String empDate;
protected String dept;
protected boolean marriage;
public Employee() {
super();
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", phone='" + phone + '\'' +
", empDate='" + empDate + '\'' +
", dept='" + dept + '\'' +
", marriage=" + marriage +
'}';
}
}
package fc.java.part4;
public class RempVO extends Employee{
public RempVO() {
super();
}
}
package fc.java.part4;
public class EmployeeTest {
public static void main(String[] args) {
// 사원 한명 객체 생성하고 데이터 저장 후 출력
RempVO vo = new RempVO();
vo.name = "홍길동";
vo.age = 50;
vo.phone = "010-4444-4445";
vo.empDate = "2002-QD10-10";
vo.dept = "홍보부";
vo.marriage = true;
System.out.println(vo.name + "\t" + vo.age + "\t" + vo.phone + "\t" + vo.empDate + "\t" + vo.dept + "\t" + vo.marriage);
System.out.println(vo.toString());
}
}
상속 관계에서 객체 초기화 (정보은닉 적용)
부모의 생성자에서 초기화 하는 것이 바람직 함.
package fc.java.part4;
public class EmployeeTest {
public static void main(String[] args) {
// 사원 한명 객체 생성하고 데이터 저장 후 출력
RempVO vo = new RempVO("홍길동", 500, "010-1111-1111","2024-01-21", "홍보부", false);
//System.out.println(vo.name + "\t" + vo.age + "\t" + vo.phone + "\t" + vo.empDate + "\t" + vo.dept + "\t" + vo.marriage);
System.out.println(vo.toString());
}
}
package fc.java.part4;
public class EmployeeInitTest {
public static void main(String[] args) {
RempVO vo = new RempVO("홍길동", 500, "010-1111-1111","2024-01-21", "홍보부", true);
System.out.println(vo.toString());
}
}
Upcasting(업 캐스팅, 자동 형 변환): 부모가 자식을 가리키는 객체 생성 방법 (상속 관계 일 때)
package fc.java.model;
public class Animal extends Object {
public Animal(){
super(); // new Object()
}
public void eat(){
System.out.println("동물처럼 먹다");
}
}
package fc.java.model;
public class Dog extends Animal {
public void eat() {
System.out.println("개처럼먹다.");
}
}
package fc.java.model;
public class Cat extends Animal {
public void night(){
System.out.println("밤에 눈에서 빛이 난다.");
}
}
package fc.java.part4;
import fc.java.model.Animal;
import fc.java.model.Cat;
import fc.java.model.Dog;
public class DogUpcastingTest {
public static void main(String[] args) {
Animal ani = new Dog();
ani.eat();
ani = new Cat();
ani.eat();
}
}
상속체이닝(자신보다 부모가 먼저)
super()
메서드 재정의(Override)
동적바인딩
package fc.java.model;
public class Dog extends Animal {
public Dog(){
super();
int a =10;
}
//재정의(Override)
public void eat(){
System.out.println("개처럼 먹다.");
}
}
package fc.java.model;
public class Cat extends Animal {
public Cat(){
super();
}
public void night(){
System.out.println("밤에 눈에서 빛이 난다.");
}
public void eat(){
System.out.println("고양이처럼 먹다.");
}
}
package fc.java.part4;
import fc.java.model.*;
public class DogCatTest {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
Cat c = new Cat();
c.eat();
c.night();
}
}
package fc.java.part4;
import fc.java.model.Animal;
import fc.java.model.Dog;
import fc.java.model.Cat;
public class OverrideTest {
public static void main(String[] args) {
//Upcasting
Animal ani = new Dog();
ani.eat(); // Animal ---(동적바인딩)---> Dog
ani = new Cat();
ani.eat();// Animal ---(동적바인딩)---> Cat
}
}
부모 자식 간 형 변환 가능
Downcasting(다운 캐스팅, 강제 형 변환)
package fc.java.part4;
import fc.java.model.*;
public class ObjectCasting {
public static void main(String[] args) {
Animal ani = new Dog();
ani.eat();
ani=new Cat(); //업캐스팅
ani.eat();
((Cat)ani).night(); //다운캐스팅
}
}
다형성
<다형성 전제조건>
다형성 인수 - 하나의 타입으로 여러가지 타입을 받을 수 있음. (부모이기 때문)
instanceof: 특정 타입이 어떤 타입으로 부터 생성이 되었는지 타입을 알아보는 연산자
상속관계에서 하위클래스들을 배열에 저장하기 위해서 생성해야하는 배열
→ 다형성 배열, 상위타입 배열
package fc.java.part4;
import fc.java.model.*;
public class PolyTest {
public static void main(String[] args) {
//업캐스팅으로 객체 생성
//상속관계, 재정의, 동적바인딩
//다형성
//상위클래스가 동일한 메세지로 하위클래스를 서로다르게 동작시키는 객체지향 원리
Animal ani = new Dog();
ani.eat(); // 실행시점에서 사용될(호출될)메서드가 결정되는 바인딩(동적 바인딩)
ani=new Cat();
ani.eat();
//다운캐스팅
((Cat)ani).night();
}
}
package fc.java.part4;
import fc.java.model.*;
public class PolyMethodTest {
public static void main(String[] args) {
Dog d= new Dog();
display(d);
Cat c = new Cat();
display(c);
}
/* private static void display(Cat c){
c.eat();
}
private static void display(Dog d){
d.eat();
} */
private static void display(Animal ani) {
ani.eat();
if(ani instanceof Cat){
((Cat)ani).night();
}
//Cat타입으로 받은 경우에만 실행
//((Cat)ani).night();
}
}
다형성 배열(상위타입배열)
package fc.java.part4;
import fc.java.model.*;
public class PolyArrayTest {
public static void main(String[] args) {
Dog d = new Dog();
Cat c = new Cat();
//Dog, Cat을 저장할 배열 생성
//Animal[] ani = {new Dog(), new Cat()};
//2. 다형성배열
Animal[] ani = new Animal[2];
ani[0] = d;
ani[1] = c;
display(ani);
}
public static void display(Animal[] ani){
for(int i =0;i<ani.length; i++){
ani[i].eat();
if(ani[i] instanceof Cat){
((Cat)ani[i]).night();
}
}
}
}
다형성 보장?
→ 부모가 명령을 내리면 자식이 반드시 동작(반응)
→ Override(재정의) 하지 않으면 다형성이 보장 안됨
다형성 보장
추상메서드(불안전한 메서드)
→ 메서드의 구현부가 없는 메서드
→ 반드시 자식이 완전하게 재정의 해야 함
추상클래스?
package fc.java.poly;
public abstract class Animal {
public abstract void eat();
public void move(){
System.out.println("무리를 지어서 이동한다.");
}
}
package fc.java.poly;
public class Cat extends Animal {
public void night (){
System.out.println("밤에 눈에서 빛이 난다.");
}
@Override
public void eat(){
System.out.println("고양이처럼 먹다.");
}
}
package fc.java.poly;
public class Dog extends Animal {
//재정의(Override)
public void eat(){
System.out.println("개처럼 먹다.");
}
}
package fc.java.part4;
import fc.java.poly.*;
public class IsNotOverride {
public static void main(String[] args) {
//재정의를 안했기 때문에 -> 부모가 명령(메세지 보내면)을 내리면 오동작
//다형성 보장x -> 다형성 보장하기 위해 재정의를 강제로 하도록 만듦
//추상클래스, 인터페이스 등장
//다형성이 보장 됨
Animal ani = new Dog();
ani.eat();
ani=new Cat();
ani.eat();
}
}
package fc.java.part4;
import fc.java.poly.*;
public class AbstractClassTest {
public static void main(String[] args) {
Animal ani = new Dog();
ani.eat();
ani.move();
ani=new Cat();
ani.eat();
ani.move();
((Cat)ani).night();
}
}
인터페이스
다형성 보장하기 위해 등장한 클래스 - 추상클래스, 인터페이스
추상클래스: 추상메서드+구현메서드
인터페이스: 추상메서드+final statix 변수
<공통점>
<차이점>
→ 추상 메서드와 구현 메서드 가질 수 있음
→ 추상 메서드와 final static변수(상수)를 가질 수 있음
package fc.java.poly;
public interface RemoCon {
public void chUp();
public void chDown();
public void volup();
public void volDown();
public void internet();
}
package fc.java.poly;
public class Radio implements RemoCon {
@Override
public void chUp() {
System.out.println("Radio의 채널이 올라간다.");
}
@Override
public void chDown() {
System.out.println("Radio의 채널이 내려간다.");
}
@Override
public void volup() {
System.out.println("Radio의 채널이 올라간다.");
}
@Override
public void volDown() {
System.out.println("Radio의 채널이 내려간다.");
}
@Override
public void internet() {
System.out.println("Radio에서는 인터넷이 지원이 안됩니다.");
}
//chUp(), chDown(), volUp(), VolDown()
}
package fc.java.poly;
public class TV implements RemoCon {
@Override
public void chUp() {
System.out.println("TV채널이 올라간다.");
}
@Override
public void chDown() {
System.out.println("TV채널이 내려간다.");
}
@Override
public void volup() {
System.out.println("TV채널이 올라간다.");
}
@Override
public void volDown() {
System.out.println("TV채널이 내려간다.");
}
@Override
public void internet() {
System.out.println("TV에서 인터넷 실행된다.");
}
//chUp(), chDown(), volUp(), VolDown()
}
package fc.java.part4;
import fc.java.poly.Radio;
import fc.java.poly.RemoCon;
import fc.java.poly.TV;
public class InterfaceTest {
public static void main(String[] args) {
//다형성 100%보장
//부모가 인터페이스면 자식의 내부 동작 방식 몰라도 동작 시킬 수 있음
RemoCon remo = new Radio();
remo.chUp();
remo.chDown();
remo.volup();
remo.volDown();
remo.internet();
remo=new TV();
remo.chUp();
remo.chDown();
remo.volup();
remo.volDown();
remo.internet();
}
}
Object클래스 이용해 객체 생성, 다형성 적용, toString메서드 활용 연습
package fc.java.poly;
import java.lang.*;
public class A extends Object {
public A(){
super();
}
public void display(){
System.out.println("나는 A입니다.");
}
public void printGo(){
System.out.println("나는 A입니다.");
}
}
package fc.java.part4;
public class B {
public void printGo(){
System.out.println("나는 B입니다.");
}
}
package fc.java.part4;
import fc.java.poly.*;
public class ObjectPolyArg {
public static void main(String[] args) {
A a=new A();
display(a);
B b=new B();
display(b);
}
public static void display(Object obj){
if(obj instanceof A){
((A)obj).printGo();
}else{
((B)obj).printGo();
}
}
}
package fc.java.part4;
import fc.java.poly.*;
public class ObjectPolyArray {
public static void main(String[] args) {
Object[] obj=new Object[2];
obj[0] = new A();
obj[1] = new B();
display(obj);
/* for(int i=0; i<obj.length;i++){
if(obj[i] instanceof A){
((A) obj[i]).printGo();
}else{
((B) obj[i]).printGo();
}
} */
}
private static void display(Object[] obj){
}
}
package fc.java.poly;
public class Board extends Object{
private String title;
public String getTitle(){
return title;
}
public void setTitle(String title){
this.title=title;
}
@Override
public String toString() {
System.out.println(super.toString());
return "Board{" +
"title='" + title + '\'' +
'}';
}
}
package fc.java.part4;
import fc.java.poly.Board;
public class ObjectToString {
public static void main(String[] args) {
Board b = new Board();
b.setTitle("게시글 입니다.");
System.out.println(b.toString());
System.out.println(b);
}
}