추상클래스
메모리의 낭비 없이 클래스를 미리 설계
메소드를 재정의(override)해서 사용한다.
메소드명을 가져다 사용하면 됨. 강제성을 띄지만 메소드명 만드는데 노력x
메소드명이 동일하여 통일성.
abstract class ShapeClass{ //추상클래스도 부모클래스의 역할을 함
abstract void draw(); //틀을 만들어 놨으니 가져다가 재정의하여 사용해라. interface와 똑같음
//무조건 return값은 void고 메소드명은 draw
}
class Circle extends ShapeClass{
@Override
public void draw() {
System.out.println("원을 그린다..");
}
}
class Rect extends ShapeClass{ //추상클래스의 메소드중 unimplement method 존재시 오류
@Override
public void draw() {
System.out.println("사각형을 그린다..");
}
}
class Tri extends ShapeClass{
@Override
public void draw() {
System.out.println("삼각형을 그린다..");
}
}
public class Test1 {
public static void main(String[] args){
Circle ob1 = new Circle();
Rect ob2 = new Rect();
Tri ob3 = new Tri();
ob1.draw();
ob2.draw();
ob3.draw();
}
}
추상클래스 안에는 무조건 추상메소드가 1개 이상 존재해야 함.
일반 메소드만 있다면 에러는 안나지만 추상클래스로 만들 필요가 없음
abstract class SortInt{ //정수를 정렬하는 클래스
private int[] value; //배열을 담을 수 있는 공간만 생성
protected abstract void sorting(); //추상 메소드
public void sort(int[] value){//매개변수로 배열.
this.value = value;
sorting();//sort 메소드안에서 추상메소드 sorting 호출 가능
//자식은 부모클래스의 것을 사용가능하지만 부모는 자식클래스의 것을 사용할 수 없다.
//abstract를 쓰면 예외적으로 자식클래스의 것을 사용한다.
//매소드만은 예외가 없음.
}
public int length(){
if(value==null){ //객체생성시 new로 생성. 초기값은 null로 되어있음. 배열 안의 int값은 0. [0,0,0]
return 0;
}
return value.length; //배열안에 해쉬코드가 들어있다면 배열의길이를 반환
}
protected final int compare(int i, int j) { //final메소드 : 자식클래스가 오버라이드 할수없음
//compare가 1이면 오름차순정렬 -1이면 내림차순정렬
if(value[i]==value[j])
return 0;
else if(value[i]>value[j]) //경우의 수 3가지 존재. 필요한 건 31,32줄 코드
return 1;
else
return -1;
}
protected final void swap(int i , int j) {
int temp;
temp = value[i];
value[i] = value[j];
value[j] = temp;
}
public void print() {
if(value == null){
return;
}
for(int n: value){
System.out.printf("%4d", n);
}
System.out.println();
}
}
class SortTest extends SortInt{
@Override
protected void sorting() { //Override가 붙으면 자신의 메소드 호출
//Selection sort
for(int i=0; i<length()-1; i++){
for(int j=i+1; j<length();j++){
if(compare(i, j)>0){ //0보다 큰 경우는 return값이 1 일때 밖에 없음. 이때 swap메소드 실행해라
swap(i, j);
}
}
}
}
}
public class Test2 {
public static void main(String[] args) {
int value[] = {50,20,6,58,99};
SortTest ob = new SortTest();
ob.sort(value);
ob.sorting();
ob.print();
}
}
상속관계가 아닌 클래스의 경우 upcast, downcast가 불가능하다.
class TestA{
public void print(){
System.out.println("A클래스....");
}
}
class TestB{
public void print(){
System.out.println("A클래스....");
}
}
public class Test3 {
public static void main(String[] args) {
TestA a = new TestA();
TestA b;
TestB bb;
b = a;
//bb =a; 데이터 타입이 다름. 아예 다른 클래스. 불가
//bb = (TestB)a; 형변환해서 넣을 수 있는가? 불가. 상속관계의 경우만 upcast, downcast 사용가능
}
}
부모클래스와 자식클래스의 메소드 호출 비교
자식클래스를 upcast 시켜도 오버라이드된 메소드를 호출 시 자신의 메소드를 호출한다.
class SuperTest{
public int a= 10, b= 20;
public void write(){
System.out.println("슈퍼클래스 write() 메소드....");
}
public int hap() {
return a+b;
}
}
class SubTest extends SuperTest{
public int b=100, c=200;
public void print() {
System.out.println("서브클래스 print() 메소드....");
}
@Override
public int hap() {
return a+b+c;
}
}
public class Test4 {
public static void main(String[] args) {
SubTest ob1 = new SubTest();
System.out.println("b: "+ ob1.b); //100
//SuperTest ob2 = (SuperTest)ob1; 명시적형변환
SuperTest ob2 = ob1; //암시적형변환. upcast
System.out.println("b: "+ ob2.b); //20
System.out.println("합: "+ ob2.hap()); //310. 메소드는 무조건 자신거를 호출
ob2.write();
//ob2.print(); ob2는 부모클래스이므로 사용불가. 내꺼는 내꺼다.(부모가 자식꺼를 사용할 수 없다.)
}
}
Interface
1.추상클래스의 일종(선언만 있고 내용이 없음)
2.final 상수변수만 정의 가능
3.인터페이스를 구현하기 위해서는 implements를 사용한다
4.하나이상의 인터페이스를 implements한 클래스는 인터페이스의 모든 메소드를 재정의 해야한다.
5.인터페이스가 다른 인터페이스를 상속 받을수있으며 이때는 extends를 사용한다.
6.클래스와는 다르게 인터페이스는 다중 구현이 가능하다
인터페이스를 사용하는 목적 : 강제성이 있음(인터페이스에 나온대로 무조건 만들어야함).
그로인해 통일성을 얻을 수 있다. 자바에서 인터페이스는 저장소.
session : 클라이언트가 서버에 접속하면 생기는 것. 연결의 개념도 있음. 그 사람을 위한 메모리공간
세션에 얼마나 메모리를 할당해야 할지 모르기 때문에 자료형은 가장 큰 OBJECT
upcast가 언제 되었는지 알아야 다시 데이터를 받을 때 downcast 를 할 수 있음
세션 <---- a.jsp
a.jsp라는 웹페이지가 있을 때 여기있는 데이터를 세션으로 받고
세션 ----> b.jsp로 옮길 때
그대로 object 자료형을 쓰면 용량 낭비가 큼. 그렇기 때문에 downcast 와 upcast 중요
interface Fruit{ //인터페이스와 추상클래스와 다른 점 : 일반메소드, 일반인스턴스변수 사용할 수 없음.
//final상수만 만들 수 있다. 초기화 꼭 해줘야 함
//기본이 static변수.
String Won = "원"; //public static final이 생략
int getPrice(); //public abstract 생략
public String getName(); //abstract 생략
}
class FruitImpl implements Fruit{ //FruitImpl : Fruit이라는 인터페이스를 구현한 클래스.
인터페이스 다중 상속이되면 Fruit, 인터페이스명+',' 옆으로 쓰면 됨
@Override
public int getPrice() {
return 1000;
}
@Override
public String getName() {
return "사과";
}
public String getItems(){
return "과일";
}
}
public class Test5 {
public static void main(String[] args) {
FruitImpl ob1 = new FruitImpl();
System.out.println(ob1.getItems() + ":" + ob1.getName() + ":" + ob1.getPrice() + Fruit.Won );
Fruit ob2 = ob1; //upcast. 형변환해서 Fruit클래스에 넣음
System.out.println(ob2.getName());
//System.out.println(ob2.getItem()); getItem() 사용안됨. 부모는 자식의 것을 가져다 쓸 수없음
}
}
인터페이스를 구현한 클래스 : TestImpl
Object 의 equals 메소드를 오버라이드 함 : hak 과 name이 동일하다면 동일인물
Override된 메소드가 없다면 Object의 equals 사용 - 주소비교 : hak 과 name이 동일해도 객체의 주소가 다르기 때문에 다른 인물.
interface Test{
public int total();
public void write();
}
class TestImpl implements Test{
private String hak;
private String name;
private int kor;
private int eng;
public TestImpl(){}
public TestImpl(String hak, String name, int kor, int eng){
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
/*
public void set(String hak, String name, int kor, int eng){
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
*/
@Override
public boolean equals(Object ob){//매개변수가 Object로 upcast됨. ob2는 TestImpl 클래스지만 오브젝트로 들어감
boolean flag = false;
if(ob instanceof TestImpl){//object가 껍데기를 빼면 무슨타입이냐
TestImpl t = (TestImpl)ob;//downcast. TestImpl로 형변환시켜서 t에 저장
if(this.hak.equals(t.hak) && this.name.equals(t.name)){ //여기에서의 equals는 String의 메소드.
hak과 name이 String 타입이니까. this-ob1, t-ob2
flag = true;
}
}
return flag;
}
@Override
public int total() {
return kor+eng;
}
@Override
public void write() {
System.out.println(hak + "," + name + "," + total());
}
}
public class Test6 {
public static void main(String[] args) {
Test ob1 = new TestImpl("111","배수지",80,90); //자식클래스로 객체 생성 & 초기화
//인터페이스 인터페이스를구현한클래스
Test ob2 = new TestImpl("111", "배수지", 100, 100);
//자식의 메소드 사용안됨
TestImpl ob3 = new TestImpl();
//자식의 메소드 가능
if(ob1.equals(ob2)){ //Override된 메소드가 없다면 Object의 equals 사용 - 주소비교
System.out.println("ob1과 ob2는 동일 인물");
}else{
System.out.println("ob1과 ob2는 다른 인물");
}
ob1.write();
ob2.write();
ob3.write();
}
}
인터페이스 다중 상속. 인터페이스가 인터페이스를 상속 받을 수 있다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
interface FruitA{
String Won = "원"; //앞에 public static final 생략
public int getPrice();
public String getName();
}
interface ItemFruit extends FruitA{ //인터페이스가 인터페이스를 상속받을 수 있다.
public String getItems();
}
class Orange implements ItemFruit{ //오버라이드 3개 해야 함. ItemFruit, FruitA 인터페이스의 메소드들.
@Override
public int getPrice() {
return 1500;
}
@Override
public String getName() {
return "오렌지";
}
@Override
public String getItems() {
return "과일";
}
}
class Apple implements ItemFruit{
@Override
public int getPrice() {
return 2000;
}
@Override
public String getName() {
return "사과";
}
@Override
public String getItems() {
return "과일";
}
}
public class Test7 {
public void packing(ItemFruit ob){
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice() + FruitA.Won);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Test7 t = new Test7();
System.out.print("1.오렌지 2.사과 : "); // 1 or 2 입력
int ch = sc.nextInt();
if(ch==1){
t.packing(new Orange()); //오렌지클래스 객체를 생성해서 매개변수로 사용
}else if(ch==2){
t.packing(new Apple());
}
//new 가 매개변수로 들어가는 건 이미 많이 봤음
//BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
/*
* 인터페이스 예시
ItemFruit ob;
ob = new Orange();
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice() + FruitA.Won);
ob = new Apple();
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice() + FruitA.Won);
* 자료형 예시
int a;
a = 10;
System.out.println(a);
int a;
a = 20;
System.out.println(b);
*/
}
}
'Dev > Java' 카테고리의 다른 글
[java] ArrayList, List, Map, Generic, Exception (0) | 2019.01.27 |
---|---|
[java] 내부클래스, 익명의클래스(Annonymous), Vector (0) | 2019.01.27 |
[java] Calendar 클래스, Wrapper 클래스, Singleton, final (0) | 2019.01.24 |
[java] 상속, Object 클래스, String클래스, StringBuffer와 StringBuilder (0) | 2019.01.24 |
[java] 생성자, instance블럭, static블럭, 재귀함수, Call By Reference (0) | 2019.01.24 |