jnk1m
Foliage IT
jnk1m
전체 방문자
오늘
어제
  • 분류 전체보기 (209)
    • Today I Learned (34)
    • Java (47)
    • Database (15)
    • [NHN Academy] (27)
    • Spring (47)
    • HTML + CSS + JavaScript (11)
    • JSP (3)
    • Node.js (10)
    • React Native (2)
    • 기타 (8)
    • 스크랩 (5)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
jnk1m
Java

JAVA 자바 웹 개발 Day09 (Code)

Java

JAVA 자바 웹 개발 Day09 (Code)

2022. 2. 18. 00:52

110. 다형성

package day09;//다형성

class A{ int x;} //x
class B extends A{int y;} //x,y

public class Test110 {

	public static void main(String[] args) {
		
		// 기존에 객체 생성하던 방식
		A a = new A();
		B b = new B(); 
		
		//다형성: 부모 타입의 변수에 자식 객체를 넣는다. 
		A a1= new B();
		System.out.println(a1.x);
		
		//부모 객체가 자식 변수에 들어가는건 안된다. 
		//B b1 = new A();
		
	}

}

부모 타입의 변수에 자식의 객체를 넣어 생성하였다. 부모는 자식 클래스 안에 뭐가 들어있는지 모르기 때문에 자식 클래스에 있는 변수를 사용할 수는 없다. 

 

111.

package day09;

class AClass{ //x,func
	int x;
	void func() {
		System.out.println("AAA");
	}
}
class BClass extends AClass{ //x,y,func,sub
	int y ;
	@Override
	void func() {
	System.out.println("BBB");
	}
	void sub() {
		System.out.println("subsub");
	}
}
public class Test111 {

	public static void main(String[] args) {
		AClass a = new BClass();
//		AClass a = new AClass();
		BClass b = null;
		//참조변수가 가르키는 실제객체가 BClass의 객체가 맞는지 판단하고
		if(a instanceof BClass) {  //맞으면 true
			System.out.println("형변환 가능");
			b = (BClass)a; //실행해라
		}else {
			System.out.println("형변환 불가능");
		}
		
		AClass a1 = null;
		BClass b1 = new BClass();
		BClass b2 = null;
		
		a1= (AClass)b1; //자식 객체를 형 변환하여 부모 참조 변수에 넣었다. 
        //형 변환 생략해도 에러x 자식을 부모로 업캐스팅. 
		b2= (BClass)a1; // 위에서 a1에 BClass를 넣었음. 한번 형 변환해서 넣어주면 가능. 
		// 실체가 같은 타입이더라도 들고 있는 변수가 부모라면, 맞는 타입에 대입할 때도
		// 형 변환이 반드시 필요함. 부모를 자식으로 형 변환하는걸 다운캐스팅 

		
		AClass a2 = new AClass();
		BClass b3 = null;
		
		b3 =(BClass)a2; //AClass (부모)를 BClass (자식)으로 형변환 할 수 없다!
		//BClass b3 = new AClass(); 와 동일. 
		b3.func();
//////////////
		AClass a4 = null;
		BClass b4 = new BClass();
		a4 = (AClass)b4; //a는 AClass타입. 밑에 코드와 동일함. B로 객체를 만들어도 접근 못함. 
		a4.func();
///////////	
		AClass a5 = new AClass(); //x, func("AAA")
		AClass a6 = new BClass();  //x, @func("BBB"), (y, sub()접근못함) 
		
		System.out.println(a.x);
		a.func();

		System.out.println(a1.x);
		a1.func();
		
	}

}

Day5 노트 참고:

*참조 변수 (래퍼런스 변수): 객체를 가리키는, 객체의 주소 (래퍼런스)를 담고 있을 변수 -> 객체 생성 전, 참조 변수 먼저 선언만 하면 메모리에 아직 객체가 생성되어 올라간 것이 아니다. 그냥 주소 담을 수 있는 변수만 만들어 놓은 것.

 

112. 다형성

package day09; //다형성 

class Person{}
class Student extends Person{}
class Teacher extends Person{}
class Professor extends Teacher{}


public class Test112 {
	
	static void print(Person p) { //부모 변수의 자식 객체 받아줄 수 있다.
		// p = new Student(); = Teacher(); = Student(); = Professor();
		if(p instanceof Person) {System.out.println("Person!");}
		if(p instanceof Student) {System.out.println("Student!");}
		if(p instanceof Teacher) {System.out.println("Teacher!");}
		if(p instanceof Professor) {System.out.println("Professor!");}
	}
	
	public static void main(String[] args) {
//		print(new Person());
		print(new Student());
//		print(new Teacher());
//		print(new Professor());

	}

}

먼저 Person 클래스를 선언하고 세 개의 자식 클래스를 만들어 준다. 

Test112 클래스에 있는 프린트 메서드는 매개변수가 있는데 만약 모든 클래스를 경우에 따라 다르게 출력하고 싶다면 매개변수로 부모 타입을 지정해주면 된다. 부모 변수의 자식 객체를 받아줄 수 있다.

 

그런데! 만약에 프로페서로 객체를 생성해서 인자로 주면 Person, Teacher, Professor가 전부 출력된다. 프로페서는 티쳐를 상속하고, 티쳐는 퍼슨을 상속한다. 스튜던트를 상속받지 않았기에 instanceof에 false가 되어 출력되지 않고 나머지 세 개만 출력이 된다. 

 

package selfstudy;

class Person{}
class Student extends Person{}
class Teacher{}
class Professor extends Teacher{}

public class self1 {
	static void print(Person p) {
		if(p instanceof Person) {System.out.println("Person");}
		if(p instanceof Student) {System.out.println("Student");}
		
	}
	static void print(Teacher t) {
		if(t instanceof Teacher) {System.out.println("Teacher");}
		if(t instanceof Professor) {System.out.println("Professor");}
	}
	public static void main(String[] args) {
		print(new Professor());
	}

}

코드를 살짝 바꿔 보았다. 이렇게 하면 티쳐를 상속한 Professor는 메서드 오버로딩된 print(Teacher t)를 실행시켜 Teacher와 Professor를 출력한다. 

 

113.

package day09;

import java.util.Scanner;

class AA{
	int x;
}
class BB extends AA{
	int y;
}

public class Test113 {

	public static void main(String[] args) {
		AA a = new AA();
		AA a1 = new BB();
		Object o = new AA(); //o는 자식객체가 뭘 가지고 있는지 모른다.. 
		Object o2 = new BB();
		Object o3 = new Scanner(System.in);
		if(o instanceof AA) {
			AA abc = (AA)o;
		}
	}

}

Object는 완전 조상 클래스. 

그래서 부모 클래스인 o는 자식 클래스인 AA로 객체 생성이 가능하다. 

 

114. 매개변수의 다형성

package day09; //매개변수의 다형성

class Product{
	int price; //제품 가격 
	int bonusPoint; //제품 구매 시 제공하는 포인트 점수
	Product(int price){
		this.price = price;
		bonusPoint = (int)(price/10); //제품 가격의 10%
	}
}

class LGTv extends Product{
	LGTv(){
		super(100);
	}
	@Override //투스트링 오버라이딩
	public String toString() {
		return "엘지 티비";
	}
}
class SComputer extends Product{
	SComputer(){
		super(200);
	}
	@Override //투스트링 오버라이딩
	public String toString() {
		return "삼성 컴퓨터";
	}
}
class Buyer{	//고객
	int money = 1000; //지갑
	int bonusPoint = 0; //고객 포인트
	void buy(Product p) { //매개변수 다형성. 무슨 타입을 몇개 써야 잘 작동하는지 생각하기. 
		if(money < p.price) {
			System.out.println("돈이 모자라네요. 다음에 다시 오세요~");
			return;
		}
		money -= p.price;
		bonusPoint += p.bonusPoint;
		System.out.println(p+ "을/를 구입하셨습니다.");
	}
}
public class Test114 {

	public static void main(String[] args) {
		Buyer b= new Buyer();
		LGTv tv = new LGTv();
		SComputer com = new SComputer();
		
		b.buy(tv);
		b.buy(com);
		
		
		System.out.println("현재 남은 돈은 " + b.money + "원 입니다.");
		System.out.println("현재 포인트는 "+ b.bonusPoint + "점 입니다.");
	}

}

먼저 봐야할 것!

프로덕트 클래스엔 기본 생성자가 없는 점. 만약 프로덕트 클래스를 상속받으면, 프로덕트의 매개 변수를 가진 생성자에 값을 던져줄 필요가 있다. 이 경우엔 LGTv의 기본 생성자 안에 super(100)으로 하여 프로덕트 생성자에 매개변수 price로 값 100을 준다.

 

투 스트링! 원래는 주소 값을 주는 메서드. 여기서는 해당 클래스를 호출하면 리턴해주는 값으로 문구를 오버 라이딩해줬다. 21일에 자세히 배운다고 하니 참고하자. 

 

115.

package day09; //오버라이딩으로 다형성 실현

class Shape{
	public void draw() {
		System.out.println("Shape");
	}
}
class Line extends Shape{
	@Override
	public void draw() {
		System.out.println("Line");
	}
}
class Rect extends Shape{
	@Override
	public void draw() {
		System.out.println("Rect");
	}
}
class Circle extends Shape{
	@Override
	public void draw() {
		System.out.println("Circle");
	}
}

public class Test115 {
	static void paint(Shape s) { //매개변수의 다형성 
		s.draw(); //s에 들어있는거에 따라서 line, shape, rect, circle 전부 될 수 있음. 
	}
	public static void main(String[] args) {
		Line line = new Line();
		paint(line);
		paint(new Shape());
		paint(new Rect());
		paint(new Circle());
	}

}

 

116.

package day09; //매개변수 다형성 응용. 자료구조 linked list 이용. 

//링크드 리스트 구현
class ShapeClass{
	ShapeClass next;
	ShapeClass() {next =null;}
	void draw() {
		System.out.println("shape");
	}
}

class LineClass extends ShapeClass{
	@Override
	void draw() {
		System.out.println("Line");
	}
	
}
class RectClass extends ShapeClass{
	@Override
	public void draw() {
		System.out.println("Rect");
	}
}
class CircleClass extends ShapeClass{
	@Override
	public void draw() {
		System.out.println("Circle");
	}
}


public class Test116 {

	public static void main(String[] args) {
		ShapeClass start,last, tmp; //last는 마지막 링크가 뭐였는지 tmp는 객체 생성할때 잠깐 쓰임(임시변수)
		start = new LineClass();
		last = start;
		tmp = new RectClass();
		last.next= tmp;
		last=tmp;
		tmp= new LineClass();
		last.next=tmp;
		last = tmp;
		
		tmp=new CircleClass();
		last.next=tmp;
		last = tmp;
		
		//모든 도형 출력
		ShapeClass s = start;
		while(s != null) {
			s.draw();
			s = s.next;
		}
	}

}

 

117.

package day09; //추상 클래스

abstract class Super{
	abstract void func();
	abstract void func1();
	
	//일반 변수들과 메서드들도 작성 가능. 하지만 객체 생성 불가능하여 상속 받아 사용해야함. 
	int a = 10;
	void aaa() {
		
	}
}
class Sub extends Super{

	@Override
	void func() { // 부모 클래스에 있는 모든 추상 메서드를 상속 받아 작성해야함.
	}

	@Override
	void func1() { //이건 안쓸거면 그냥 비워두기
	}
	
}
public class Test117 {

	public static void main(String[] args) {
		//미완성 형태의 추상 클래스로는 객체 생성 불가!!
		//Super s = new Super();
		
		Sub sub = new Sub();
		sub.func();
	}

}

 

118.

package day09; //추상 클래스 사용

abstract class Calculator{
	abstract int add(int a, int b); //두 정수의 합을 구하여 리턴
	abstract int substract(int a, int b); //두 정수의 차를 구하여 리턴
	abstract double average(int []a); //배열에 저장된 정수의 평균값 리턴
}

class MyCalc extends Calculator{
	@Override
	int add(int a, int b) { //리턴 되는 값이 있을 때는 출력문 안에서!
		return a + b;
	}
	@Override
	int substract(int a, int b) {
		return a-b;
	}
	@Override
	double average(int[] a) {
		double sum =0;
		for(int i : a) { //하나씩 올라가는 i가 아님. 그냥 값을 가져오는 for-each문
			sum += i;//난 a[i]으로 했는데 안 돌아감. 
		}
		return sum / a.length;
	}
}
public class Test118 {

	public static void main(String[] args) {
		MyCalc c = new MyCalc();
		
		System.out.println(c.add(10,5));
		System.out.println(c.substract(10,5));
		System.out.println(c.average(new int[] {1,2,3,4,5}));
		//int [] arr = {1,2,3,4,5}; 위 배열은 이 배열의 간결한 버전. 

	}
}

 

119.

package day09;

interface Test{
	public static final int NUM =1; //상수
	public abstract void add(); //추상메서드
	
	int x =100;//상수
	int func();//추상메서드
}

interface Test2{
	void func22();//추상메서드
}

class AA1{
	int x =10;
}

class Inter extends AA1 implements Test , Test2{ 
	//이렇게 상속도 받고 인터페이스도 구현할 수 있음
	

	@Override
	public void add() {
		System.out.println("imple~");
		
	}

	@Override
	public int func() {
		return 0;
	}

	@Override
	public void func22() {
		System.out.println("func2");
		
	}
	
}
public class Test119 {

	public static void main(String[] args) {
		Inter i = new Inter();
		i.add();
		i.func22();
		
		//다형성 
		//인터페이스 타입의 변수에, 구현 클래스로 생성한 객체 담을 수 있다.(부모 역할)
		Test t = new Inter(); //테스트 타입을 구현시켜놓은 클래스. 
		Test2 tt =new Inter(); //테스트를 구현해서 만들어놓은 클래스는 모두 테스트의 자식. 
		
		
	}

}

만약에! 여기서 i.x 와 t.x를 호출하게 되면 t.x 는 제대로 출력 되지만 i.x는  The field is ambiguous 에러가 뜨게 된다. 왜냐, 테스트를 구현해놓은 클래스 t 안에는 x가 값으로 100을 가진 그 x 하나밖에 없지만 테스트 인터페이스와 AA1 클래스를 상속받은 i 안에는 변수 x가 두 개가 있기 때문에..  

    'Java' 카테고리의 다른 글
    • JAVA 웹 개발 Day10 (Note2): 익명 클래스, 예외 처리, 기본 정리
    • JAVA 웹 개발 Day10 (Note1): 싱글턴, 내부 클래스
    • JAVA 자바 웹 개발 Day09 (Note): 다형성, 추상 클래스, 인터페이스
    • JAVA 자바 웹 개발 Day7 (연습 문제 85~90)

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.