JAVA

8.Java 오버라이딩/super/다형성/toString/추상클래스

네스이 2022. 7. 13. 16:37

2022.07.13.수


1)오버라이딩(overriding)

 -개념 : 부모 클래스의 메서드를 자식 클래스가 재정의 가능한 방법으로서 자식에서 수정된 메서드를 의미

 -규칙 : 부모클래스 메서드의 리턴타입, 메서드명, 파라미터 동일해야함, 접근지정자는 같거나 확대가능

public class Pet 
{
	//공통적인 속성
	public String name;
	public int age;
	
	//공통적인 동작
	public void eat()
	{
		System.out.println("eat");
	}
	public void sleep()
	{
		System.out.println("sleep");
	}
	
	public Pet() {}
	public Pet(String name, int age) 
	{
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
	
}
public class Cat extends Pet 
{
	//의존적인 속성
	String gender;
	
	//의존적인 동작
	public void cry()
	{
		System.out.println("Cat.cryCat");
	}
	
	//재정의
	@Override //어노테이션
	public void eat()
	{
		System.out.println("냠냠");
	}
	@Override
	public void sleep()
	{
		System.out.println("쿨쿨");
	}

	public Cat() {}
	public Cat(String name, int age, String gender) 
	{
		super(name, age);
		this.gender = gender;
	}
	
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	
	
}
public class Dog extends Pet 
{
	//의존적인 속성
	String color;

	//의존적인 동작
	public void swim()
	{
		System.out.println("Dog.swimDog");
	}
	
	//재정의
	@Override //어노테이션
	public void eat() 
	{
		System.out.println("쩝쩝");
	}
	@Override
	public void sleep()
	{
		System.out.println("드르렁");
	}

	public Dog() {}
	public Dog(String name, int age, String color) 
	{
		super(name, age);
		this.color = color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
	
	
	
}
public class TestPet {

	public static void main(String[] args) 
	{
		Cat c = new Cat("야옹이1", 2, "암컷");
		Cat c2 = new Cat("야옹이2", 2, "수컷");
		
		//기능호출
		c.eat();
		c.sleep();
		c.cry();
		
		Dog d = new Dog("멍멍이1", 3, "화이트");
		Dog d2 = new Dog("멍멍이2", 3, "블랙");
		
		//기능호출
		d.eat();
		d.sleep();
		d.swim();
	}

}

2)super 키워드

public class Pet 
{
	String name;
	int age;
	
	public Pet() {}
	public Pet(String name, int age) 
	{
		this.name = name;
		this.age = age;
	}

	//name, age 한꺼번에 반환해주는 메서드
	public String getInfo()
	{
		return name + "\t" + age;
	}
	//오버로딩
	public String getInfo(int n)
	{
		return null;
	}
}
public class Cat extends Pet 
{
	//추가적인 속성
	String gender;

	public Cat() {}
	public Cat(String name, int age, String gender) 
	{
		super(name, age);
		this.gender = gender;
	}
	@Override
	public String getInfo() 
	{
		//=return name + "\t" + age + "\t" + gender;
		return super.getInfo() + "\t" + gender;
	}
	
	
}

3)다형성(polymorphism)

 -개념 : 상속이 전제되어 있을 때 큰 타입의 참조 변수가 같거나 작은타입을 참조할 수 있는 능력

 -문법 : 부모타입 변수 = new 작은타입();

 -장점 : 재사용성

 -참고사항 : 가)하위 클래스에서 추가된 멤버는 접근 불가 -> 형변환으로 해결

                   나)특정 타입 instanceof 연산자로 추론가능

 -활용 : 가)배열

            나)메서드 파라미터 변수

public class Cat extends Pet 
{
	//추가적인 속성
	String gender;

	public Cat() {}
	public Cat(String name, int age, String gender) 
	{
		super(name, age);
		this.gender = gender;
	}
	@Override
	public String getInfo() 
	{
		//=return name + "\t" + age + "\t" + gender;
		return super.getInfo() + "\t" + gender;
	}
	
	
}
public class TestPet2 {

	public static void main(String[] args) 
	{
		//1.일반적인 객체 생성 방법 ==> 변수갯수 많아짐
		Pet p = new Pet("앵무새", 2);
		Cat c = new Cat("야옹이1", 2, "암컷");
		Dog d = new Dog("멍멍이1", 3, "화이트");
		
		//2.다형성 ==> 변수 하나로 다양한 객체 관리 가능 -> 재사용성 증가
		Pet p2 = new Pet("앵무새", 2);
		System.out.printf("이름:%s, 나이:%d \n", p2.getName(), p2.getAge());
		p2 = new Cat("야옹이1", 2, "암컷");
		//자식에서 추가된 멤버(변수, 메서드)를 참조하기 위해서는 자식타입으로 형변환 해야함
		//Cat c2 = (Cat)p2;
		//System.out.printf("이름:%s, 나이:%d, 성별:%s", c2.getName(), c2.getAge(), c2.getGender());
		System.out.printf("이름:%s, 나이:%d, 성별:%s \n", p2.getName(), p2.getAge(), ((Cat)p2).getGender());
		p2 = new Dog("멍멍이1", 3, "화이트");
		System.out.printf("이름:%s, 나이:%d, 성별:%s \n", p2.getName(), p2.getAge(), ((Dog)p2).getColor());
	}

}
public class TestPet3_배열활용 {

	public static void main(String[] args) 
	{
		/*
			1.다형성 활용 ==> 배열 이용
			고양이 10마리, 강아지 20마리
			1)개별적으로 객체 생성 저장 ==> 변수30개 필요
			2)개별타입으로 배열 생성     ==> 변수2개 필요
			3)다형성 			  ==> 변수1개 필요
		 */
		
		Pet[] pets = { new Cat("야옹이1", 2, "암컷"),
				       new Dog("멍멍이1", 3, "화이트"),
				       new Cat("야옹이2", 3, "수컷"),
				       new Dog("멍멍이2", 2, "블랙"),
				       new Cat("야옹이3", 1, "암컷") };
		
		for(Pet i : pets)
		{
			//고양이? 강아지? ==> instanceof 연산자 이용해서 원래 타입을 식별 할 수 있음
			//문법 : 변수명 instanceof클래스
			if(i instanceof Cat)
			{
				System.out.printf("이름:%s, 나이:%d, 성별:%s \n", i.getName(), i.getAge(), ((Cat)i).getGender());
			}
			else
			{
				System.out.printf("이름:%s, 나이:%d, 색상:%s \n", i.getName(), i.getAge(), ((Dog)i).getColor());
			}
		}
		
	}

}
public class TestPet4_메서드활용 {

	//정보출력하는 메서드
	public static void info_print(Pet pet)
	{
		System.out.printf("이름:%s, 나이:%d", pet.getName(), pet.getAge());
		
		if(pet instanceof Cat)
		{
			System.out.printf(", 성별:%s", ((Cat)pet).getGender());
		}
		else if(pet instanceof Dog)
		{
			System.out.printf(", 색상:%s", ((Dog)pet).getColor());
		}
		else if(pet instanceof Pet) //istanceof 사용시 상속구조에서 부모타입을 가장 마지막에 비교해야함
		{
			
		}
		System.out.println();
	}
	
	public static void main(String[] args) 
	{
		//2.다형성 활용 ==> 메서드 파라미터 변수
		
		Pet p = new Pet("앵무새", 2);
		Cat c = new Cat("야옹이1", 2, "암컷");
		Dog d = new Dog("멍멍이1", 3, "화이트");
		
		info_print(p);
		info_print(c);
		info_print(d);
		
		System.out.println(p.toString());
	}

}

3)Object 클래스 toString() 메서드

 -반환값 : 클래스명@16진수

 -Object 클래스의 toString() 메서드를 하위 클래스에서 재정의해서 사용해야함

 -toString : 참조변수를 출력할 때 자동 호출됨

   ==>sysout(참조형 변수) = sysout(참조형 변수.toString())

/*
	재사용 클래스 작성 패턴
	1.인스턴스 변수
	2.생성자
	3.getter/setter
	4.toString() 재정의
 */

public class Student //extends Object가 자동 지정됨
{
	String name;
	int age;
	
	public Student() {}
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() 
	{
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
	
}
public class TestStudent {

	public static void main(String[] args) 
	{
		Student s = new Student("홍길동", 20);
		
		//기존방식
		System.out.println(s.getName() + "\t" + s.getAge());
		
		//참조 변수 출력
		System.out.println(s);
		System.out.println(s.toString());
	}

}

4)추상클래스

 -public abstract class 클래스명 {}

 -구성요소 : 변수, 메서드, 생성자, 추상메서드

 -추상메서드를 가지면 반드시 추상클래스로 만들어야 함(※추상 클래스가 반드시 추상 메서드를 가질 필요는 없음)

 -객체 생성 불가(불완전한 클래스)

 -추상메서드(불완전한 메서드) : public abstract void a(); (기능이 구현 되지 않음)

 -다른 클래스(concrete class)의 도움을 받아(상속) 추상클래스를 사용할 수 있음

 -자식 클래스(추상화 클래스 상속)에서 추상메서드를 재정의(overriding)해서 사용할 수 있음

 -목적 : 반드시 추상 클래스의 추상 메서드로 구현하도록 강제

 

  가) 추상화 하지 않은 클래스

package com.unabstract;

public class Pet 
{
	//변수
	//생성자
	
	
	//메서드
	//공통적인 기능
	public void eat() 
	{
		System.out.println("eat");
	}
}
package com.unabstract;

public class Cat extends Pet 
{
	//변수
	//생성자
	
	//메서드
	//재정의 안하고 자기 멋대로 메서드 추가
	public void eatCat()
	{
		System.out.println("냠냠");
	}
}
package com.unabstract;

public class Dog extends Pet 
{
	//변수
	//생성자
	
	//메서드
	//재정의 안하고 자기 멋대로 메서드 추가
	public void eatDog()
	{
		System.out.println("쩝쩝");
	}
}
package com.unabstract;

public class TestPet {

	public static void main(String[] args) 
	{
		Cat c = new Cat();
		c.eatCat();
		
		Dog d = new Dog();
		d.eatDog();

	}

}

  나)추상클래스

package com.abstract2;

public abstract class Pet 
{
	//변수
	String name;
	//생성자
	Pet() {}
	//메서드
	public String getName() { return name; }
	
	//추상메서드
	//추상메서드 반드시 재정의 해야함
	public abstract void eat();
}
package com.abstract2;

public class Cat extends Pet 
{

	
	@Override
	public void eat() 
	{
		System.out.println("냠냠");
	}

}
package com.abstract2;

public class Dog extends Pet {

	@Override
	public void eat()
	{
		System.out.println("쩝쩝");
	}

}
package com.abstract2;

public class TestPet {

	public static void main(String[] args) 
	{
//		Pet p = new Pet(); //추상클래스 new 불가
		//다형성 가능
		Pet p = new Cat();
        Pet p = new Dog();
        
		Cat c = new Cat();
		c.eat();
		Dog d = new Dog();
		d.eat();
		//eat으로 메서드 일치
	}

}