간단 차이점 정리
Implement, extends 차이- extends :
부모로부터 상속/ 클래스를 확장하기 위한 것( 클래스는 선언과 내용이 들어가 있는 것 )
- implements
:조언자로부터 상속 / 다중 상속을 통해 해결 가능함 / 그러나 interface로 정의되어 있어야함
intertace , abstract , extends 차이- intertace : 한자식이 두 부모로 부터
상속받을 수 있음 (그자체로 객체를 만들 수 없음 ) implements로 상속해서 객체를 만들 수 있음 ,, 인터페이스의 함수를
필수적으로 장착해야함
- abstract 는 자식이 부모의 것을 쓸때
공통적인것들을 사용하기 위해 추상적으로 틀+기능을 구현해 놓은것 >> 자식이 해당 클래스를 상속받아 자유롭게
extends 하여 override해서 쓸 수 있음
- extends 부모로부터 물려받는것
- 상속은 물려받는것 , 인터페이스는 장착하는것
- extends : 부모로부터 상속/ 클래스를 확장하기 위한 것( 클래스는 선언과 내용이 들어가 있는 것 )
- implements :조언자로부터 상속 / 다중 상속을 통해 해결 가능함 / 그러나 interface로 정의되어 있어야함
- intertace : 한자식이 두 부모로 부터 상속받을 수 있음 (그자체로 객체를 만들 수 없음 ) implements로 상속해서 객체를 만들 수 있음 ,, 인터페이스의 함수를 필수적으로 장착해야함
- abstract 는 자식이 부모의 것을 쓸때 공통적인것들을 사용하기 위해 추상적으로 틀+기능을 구현해 놓은것 >> 자식이 해당 클래스를 상속받아 자유롭게 extends 하여 override해서 쓸 수 있음
- extends 부모로부터 물려받는것
- 상속은 물려받는것 , 인터페이스는 장착하는것
07. 상속과 인터페이스
리팩토링
겹치는 함수를 별도의 클래스에 만들고 각각 클래스에 가져다 쓴다.
"o is a ㅁ" 관계이면 중복코드 제거를 할 수 있다.
단일상속
자바는 단일 상속이다.
상속이란?
Employee, Professor , Student 클래스에서 Person클래스의 내용을 가져다 사용하는것을 '상속한다' 라고 표현한다.
접근제한자 class 클래스명 extends 부모 클래스명{
}
상속 전
Employee.java
package com.ruby.java.ch07;
public class Employee {
private String name; // 외부에서 쓸 수 있게 끔 getter setter 만들어줌
private int age;
private String dept;
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 String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String toString() {
return "Employee [name=" + name + ", age=" + age + ", dept=" + dept + "]";
}
}
Porfessor.java
package com.ruby.java.ch07;
public class Professor {
private String name; // 외부에서 쓸 수 있게 끔 getter setter 만들어줌
private int age;
private String subject;
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 String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String toString() {
return "Professor [name=" + name + ", age=" + age + ", subject=" + subject + "]";
}
}
Student.java
package com.ruby.java.ch07;
public class Professor {
private String name; // 외부에서 쓸 수 있게 끔 getter setter 만들어줌
private int age;
private String subject;
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 String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String toString() {
return "Professor [name=" + name + ", age=" + age + ", subject=" + subject + "]";
}
}
MainTest.java
package com.ruby.java.ch07;
public class MainTest {
public static void main(String[] args) {
Student s = new Student();
Employee e = new Employee();
Professor p = new Professor();
s.setName("홍길동");
s.setAge(47);
s.setMajor("컴퓨터 과학");
e.setName("이기자");
e.setAge(35);
e.setDept("입학처");
p.setName("이순신");
p.setAge(47);
p.setSubject("빅데이터");
System.out.println(s.toString());
System.out.println(e.toString());
System.out.println(p.toString());
}
}
상속 후-
Person.java
package com.ruby.java.ch07.inheritance;
public class Person {
private String name;
private int 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 String toString() {
return name + ":"+ age;
}
}
Employee.java
package com.ruby.java.ch07.inheritance;
public class Employee extends Person{
private String dept;
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}
Professor.java
package com.ruby.java.ch07.inheritance;
public class Professor extends Person {
private String subject;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
}
Student.java
package com.ruby.java.ch07.inheritance;
public class Student extends Person{
private String major;
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;java
}
}
MainTest.java
package com.ruby.java.ch07.inheritance;
public class MainTest {
public static void main(String[] args) {
// TODO Auto-generated constructor stub
Student s = new Student();
Employee e = new Employee();
Professor p = new Professor();
s.setName("홍길동");
s.setAge(47);
s.setMajor("컴퓨터 과학");
e.setName("이기자");
e.setAge(35);
e.setDept("입학처");
p.setName("이순신");
p.setAge(47);
p.setSubject("빅데이터");
System.out.println(s.toString());
System.out.println(e.toString());
System.out.println(p.toString());
}
}
new Employee() --->Employee---->Person를 가서 Person에 있는 name age 의 변수 와 함수등을 가져와서 다시 Person ----> Employee ----> new Employee()로 간다.
p281
부모것이 먼저 만들어 지고 그 다음 자식이 만들어 진다.
Person 에서 상속받은것 , Employee 자기자신에서 만든것 순이다.
Person (name | age | getName() ...) + Employee (dept | getDept() | setDept() )
p282
상속활용
메서드 오버라이딩
부모한테 상속받은 메서드의 내용을 재정의 하는 것
부모클래스에서 정의된 메서드(바디)를 자식클래스에서 재정의함
위에 코드 Student Employee Professor 에서 출력값에서는 자식 클래스가 선언한 값(서로 다 결과를 반환하는 값들)이 안나온다.
why? Person.java에 안써져있기 때문!
-> 그래서 각각 Student Employee Professor파일에 재정의해야한다!
각각 자식클래스에
public String toString() {
return "...";
}
추가
ex>
//Employee.java
public String toString() {
//return name + ":" + age + ":"+ dept;
//에러난다. 상속받은 것이기 때문! (x)
return this.getName() + ":" + this.getAge() + ":"+ this.getDept();
//이렇게 해주어야함
}
super
상속해도 너무 길고 중복되는것 많아! -> 그래서 super를 쓴다.
extends 다음에 있는애를 지칭한다.
super.메서드명(인자)
위에 코드에서 각각 자식 클래스 toString()함수에
return super.toString() +":"+dept; // Emloyee.java
return super.toString() +":"+subject; // Professor.java
return super.toString() +":"+ major; // Student.java
로 바꿔준다.
부모 생성자 호출
각각 클래스에 기본 생성자를 만든다.
public Person() {
super();
System.out.println("Person() 호출");
}// Person.java
public Employee(){
super();
System.out.println("Employee() 호출");
}// Emloyee.java
public Professor() {
super();
System.out.println("Professor() 호출");
}// Professor.java
public Student() {
super();
System.out.println("Student() 호출");
}// Student.java
결과값(출력)
Person() 호출
Student() 호출
Person() 호출
Employee() 호출
Person() 호출
Professor() 호출
Student Employee Professor 이 생성될때마다 부모클래스의 생성자도 같이 호출된다.
전)
Student Employee Professor 각각에 저 생성자를 다 만들어 줘야 했다.
public Student(String name, int age, String major){
setName(name);
setAge(age);
this.major=major;
}
후)
중복을 줄이기 위해서 부모클래스 Person.java에서 생성자 하나를 만들어 준 후
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
super(name,age); 로 만들어주면 중복을 줄일 수 있다.
public Student(String name, int age, String major){
super(name,age);
this.major=major;
}
final 제어자
final : 값을 못바꾸게 하는것
메서드 앞에 final 주면 오버라이딩 불가하다
추상개념
Employee
|
Salesman -- Manager -- Consultant
|
Director
메서드 정의할 때 앞에다
제어자 리턴타입 메서드이름(매개변수){ 바디 } 가있음
바디가 필요없어서 안만들으면 오류!
그럴때 일부러 바디 안만들었어! 라고 abstract 키워드를 주면 오류가 나지 않는다.
absrtact class Employee{
String name;
int salary;
public absrtact void calcSalary();
}
추상 메서드를 가지고 있으면 class에서도 추상메서드 가지고 있다고 말해야한다.
추상메서드는 왜쓰나요?
내가 가지고 있는 내용중에 반드시 오버라이딩 시키고 싶다(오버라이딩는 선택사항) 할때 쓰는 것이 abstract
반드시 오버라이딩 시키고 싶다 ! 바디 일부러 안만들고! 드러나게 하고 싶다! 할 경우 abtract
public abstract class Employee {
String name;
int salary;
public abstract void calcSalary();
}
Employee 상속받으면 에러뜸
public class Salesman extends Employee {
} // error!
---> 오버라이딩 시켜줘야한다!!
public class Salesman extends Employee {
public void calcSalary() {
} //오류 사라짐!
}
무조건 오버라이딩 시켜줘야하는데 해주기 싫다면?
자신 클래스도 추상화 시켜주면 된다.
public abstract class Salesman extends Employee {
//오버라이딩 안시켜줘도됨
int salary;
String name;
}
인터페이스
어떤 프로그램을 개발할 떄 아이폰/갤럭시용 프로그램을 만들어야한다. 그랬을 때 아이폰용은 별도의 사용방법으로 사용할 수 있게하고 , 갤럭시도 갤럭시대로 방법이 있다. 사용자는 한가지 방법으로만 사용할 수 있게끔 만들고 싶다. 어느 플랫폼이나 공통적으로 기능을 구현 할 때 강제 규약(표준화)을 만들면 편해진다.
제어자 interface 인터페이스명{
public static final 변수선언;
public abstract 메서드선언();
public default 메서드선언() {}; //최신버젼 필요 ㄴㄴ
public static 메서드선언() {}; //최신버젼 필요 ㄴㄴ
public private 메서드선언() {}; //최신버젼 필요 ㄴㄴ
}
interface Test{//추상메서드를 가지고 있는 객체가 interface
public static final int MIN_SIZE = 1;
void a(); // 추상메서드
void b(); // 추상메서드
}
Class A{
a(){};
b(){};
}
Class B{
a(){};
b(){};
A.c = new A();
c.a();
c.b();
}
인터페이스 안에서 변수선언을 한다면? 인스턴스 변수는 선언할 수 없다
public static final int MIN_SIZE = 1;
으로 앞에 붙여줘야 한다.
메서드를 선언할 때에도
public abstract String getMessage();
로 abstract 를 추가해야 한다.
p319
클래스 다이어그램
<<interface>>
클래스가 클래스를 상속하면 : 실선
클래스가 인터페이스 상속 : 점선
제어자 class 클래스명 extends 부모 클래스명 implements 인터페이스명,인터페이스명..{
}
다중상속이 가능하다
인터페이스 안에서만 만들목적으로 쓴 것이 private 이다.
인터페이스는 body를 만들지 않고 메서드만 만들어 놓기 때문에 단순히 정의만 해두고 구체적인 내용이 없다
그에 반해서 class 는 완전한 body 를 가지고 있기 때문에 extend로 상속 받아서 사용해야한다.
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
09. 기본 API활용하기 (0) | 2019.02.11 |
---|---|
08. 다형성과 내부클래스 (0) | 2019.02.11 |
06. 객체지향 구현 (0) | 2019.02.08 |
05.객체지향 (0) | 2019.02.07 |
04. 배열 (0) | 2019.02.07 |