Java의 추상화 및 계약
L'추출 클래스가 있는 "계약"을 정의할 수 있습니다. 그들은 "무엇"과 "어떻게"를 분리하여 존중해야 합니다. Java에서는 이것이 달성됩니다 와 추상 수업 e 인터페이스.
무엇을 배울 것인가
- 상속 및 확장 키워드
- 다형성 및 메서드 재정의
- 추상 클래스와 추상 메서드
- 다중 인터페이스 및 구현
- 인터페이스의 기본 메소드
- 추상 클래스와 인터페이스를 사용하는 경우
유전
L'유전 클래스가 속성을 획득할 수 있도록 허용 그리고 다른 클래스의 메소드. 상속받은 클래스는 다음과 같습니다. 아강, 그것이 상속받는 것은 슈퍼클래스.
// Superclasse (classe padre)
public class Persona {
protected String nome;
protected String cognome;
protected int eta;
public Persona(String nome, String cognome, int eta) {
this.nome = nome;
this.cognome = cognome;
this.eta = eta;
}
public String getNomeCompleto() {
return nome + " " + cognome;
}
public void presentati() {
System.out.println("Mi chiamo " + getNomeCompleto());
}
}
// Sottoclasse (classe figlia) - eredita da Persona
public class Studente extends Persona {
private int matricola;
private double mediaVoti;
public Studente(String nome, String cognome, int eta, int matricola) {
super(nome, cognome, eta); // chiama costruttore della superclasse
this.matricola = matricola;
this.mediaVoti = 0;
}
// Metodo aggiuntivo specifico di Studente
public void studia(String materia) {
System.out.println(nome + " sta studiando " + materia);
}
// Getter
public int getMatricola() {
return matricola;
}
}
다형성 및 재정의
Il 다형성 다양한 클래스의 객체를 처리할 수 있습니다. 일반적인 유형을 통해. 그만큼'보수 재정의할 수 있게 해준다 상속된 메서드.
public class Studente extends Persona {
private int matricola;
public Studente(String nome, String cognome, int eta, int matricola) {
super(nome, cognome, eta);
this.matricola = matricola;
}
// Override: ridefinisce il metodo della superclasse
@Override
public void presentati() {
System.out.println("Ciao! Sono " + getNomeCompleto());
System.out.println("Matricola: " + matricola);
}
}
public class Docente extends Persona {
private String materia;
public Docente(String nome, String cognome, int eta, String materia) {
super(nome, cognome, eta);
this.materia = materia;
}
@Override
public void presentati() {
System.out.println("Buongiorno, sono il Prof. " + cognome);
System.out.println("Insegno " + materia);
}
}
// Polimorfismo in azione
Persona[] persone = new Persona[3];
persone[0] = new Studente("Mario", "Rossi", 20, 123456);
persone[1] = new Docente("Luigi", "Verdi", 45, "Programmazione");
persone[2] = new Persona("Anna", "Bianchi", 30);
for (Persona p : persone) {
p.presentati(); // chiama il metodo corretto per ogni tipo
System.out.println("---");
}
규칙 재정의
- 주석
@Override선택사항이지만 권장됩니다 - 메소드에는 동일한 서명(이름 및 매개변수)이 있어야 합니다.
- 반환 유형은 동일하거나 하위 유형이어야 합니다.
- 가시성을 줄일 수 없습니다(공개에서 비공개로).
- 메서드를 재정의할 수 없습니다.
finalostatic
추상 클래스
에이 추상 수업 직접 인스턴스화할 수 없습니다. 서브클래스를 생성하는 추상(구현이 필요 없는) 메서드를 포함할 수 있습니다. 그들은 구현해야 합니다.
// Classe astratta: non può essere istanziata
public abstract class FormaGeometrica {
protected String nome;
protected String colore;
public FormaGeometrica(String nome, String colore) {
this.nome = nome;
this.colore = colore;
}
// Metodo concreto: ha implementazione
public void descrivi() {
System.out.println("Sono un/una " + nome + " di colore " + colore);
}
// Metodi astratti: senza implementazione, le sottoclassi DEVONO implementarli
public abstract double calcolaArea();
public abstract double calcolaPerimetro();
}
// Sottoclasse concreta: DEVE implementare tutti i metodi astratti
public class Cerchio extends FormaGeometrica {
private double raggio;
public Cerchio(String colore, double raggio) {
super("cerchio", colore);
this.raggio = raggio;
}
@Override
public double calcolaArea() {
return Math.PI * raggio * raggio;
}
@Override
public double calcolaPerimetro() {
return 2 * Math.PI * raggio;
}
}
public class Rettangolo extends FormaGeometrica {
private double base;
private double altezza;
public Rettangolo(String colore, double base, double altezza) {
super("rettangolo", colore);
this.base = base;
this.altezza = altezza;
}
@Override
public double calcolaArea() {
return base * altezza;
}
@Override
public double calcolaPerimetro() {
return 2 * (base + altezza);
}
}
// Utilizzo
FormaGeometrica[] forme = {
new Cerchio("rosso", 5),
new Rettangolo("blu", 4, 3)
};
for (FormaGeometrica forma : forme) {
forma.descrivi();
System.out.printf("Area: %.2f, Perimetro: %.2f%n",
forma.calcolaArea(), forma.calcolaPerimetro());
}
인터페이스
에이'인터페이스 계약을 정의합니다: 메소드 세트 구현 클래스가 제공해야 하는 것입니다. 추상클래스와는 다르게 클래스는 구현할 수 있습니다 다중 인터페이스.
// Interfaccia: definisce un contratto
public interface Valutabile {
// Tutti i metodi sono implicitamente public abstract
double getVoto();
String getGiudizio();
}
public interface Stampabile {
void stampa();
}
public interface Esportabile {
String esportaJSON();
String esportaCSV();
}
// Una classe può implementare MULTIPLE interfacce
public class Esame implements Valutabile, Stampabile, Esportabile {
private String nomeCorso;
private int voto;
private boolean lode;
public Esame(String nomeCorso, int voto, boolean lode) {
this.nomeCorso = nomeCorso;
this.voto = voto;
this.lode = lode && voto == 30;
}
// Implementazione Valutabile
@Override
public double getVoto() {
return voto;
}
@Override
public String getGiudizio() {
if (voto >= 28) return "Ottimo";
if (voto >= 24) return "Buono";
if (voto >= 18) return "Sufficiente";
return "Insufficiente";
}
// Implementazione Stampabile
@Override
public void stampa() {
String votoStr = lode ? "30 e Lode" : String.valueOf(voto);
System.out.println(nomeCorso + ": " + votoStr + " (" + getGiudizio() + ")");
}
// Implementazione Esportabile
@Override
public String esportaJSON() {
return String.format("{\"corso\":\"%s\",\"voto\":%d,\"lode\":%b}",
nomeCorso, voto, lode);
}
@Override
public String esportaCSV() {
return String.format("%s,%d,%b", nomeCorso, voto, lode);
}
}
기본 메소드(Java 8+)
public interface Calcolabile {
double calcola();
// Default method: ha un'implementazione di default
default String formattaRisultato() {
return String.format("%.2f", calcola());
}
// Static method nell'interfaccia
static double arrotonda(double valore, int decimali) {
double fattore = Math.pow(10, decimali);
return Math.round(valore * fattore) / fattore;
}
}
public class MediaVoti implements Calcolabile {
private int[] voti;
public MediaVoti(int... voti) {
this.voti = voti;
}
@Override
public double calcola() {
int somma = 0;
for (int v : voti) somma += v;
return (double) somma / voti.length;
}
// Può override il default method se vuole
@Override
public String formattaRisultato() {
return "Media: " + String.format("%.2f", calcola()) + "/30";
}
}
추상 클래스와 인터페이스
비교
| 나는 기다린다 | 추상 클래스 | 인터페이스 |
|---|---|---|
| 유전 | 싱글(확장) | 다중(구현) |
| 건축업자 | Si | No |
| 상태(속성) | 예(아무거나) | 상수만(정적 최종) |
| 구체적인 방법 | Si | 기본/정적 전용 |
| 일반적인 사용 | 상태와 공통 기반 | 행동 계약 |
언제 무엇을 사용할 것인가
- 추상 클래스: 공유할 공통 코드, 상태 또는 관계 "및"의 유형이 있는 경우
- 인터페이스: 다양한 클래스에서 구현할 수 있는 동작을 정의하려는 경우
- 둘 다: 인터페이스를 구현하는 추상 클래스를 사용할 수 있습니다.
전체 예: 대학 시스템
public interface Valutabile {
double getMedia();
String getGiudizio();
}
public interface Identificabile {
String getCodice();
String getTipo();
}
public abstract class MembroUniversita implements Identificabile {
protected String nome;
protected String cognome;
protected String codice;
public MembroUniversita(String nome, String cognome, String codice) {
this.nome = nome;
this.cognome = cognome;
this.codice = codice;
}
public String getNomeCompleto() {
return nome + " " + cognome;
}
@Override
public String getCodice() {
return codice;
}
// Metodo astratto: ogni sottoclasse definisce il suo comportamento
public abstract void svolgiFunzione();
}
public class StudenteUniversitario extends MembroUniversita implements Valutabile {
private int[] voti = new int[20];
private int numEsami = 0;
public StudenteUniversitario(String nome, String cognome, int matricola) {
super(nome, cognome, "S" + matricola);
}
public void registraEsame(int voto) {
if (numEsami < voti.length && voto >= 18 && voto <= 30) {
voti[numEsami++] = voto;
}
}
@Override
public String getTipo() {
return "Studente";
}
@Override
public void svolgiFunzione() {
System.out.println(getNomeCompleto() + " studia per gli esami");
}
@Override
public double getMedia() {
if (numEsami == 0) return 0;
int somma = 0;
for (int i = 0; i < numEsami; i++) somma += voti[i];
return (double) somma / numEsami;
}
@Override
public String getGiudizio() {
double media = getMedia();
if (media >= 28) return "Eccellente";
if (media >= 24) return "Buono";
if (media >= 18) return "Sufficiente";
return "In corso";
}
}
public class Professore extends MembroUniversita {
private String materia;
private int oreSettimanali;
public Professore(String nome, String cognome, String codice, String materia) {
super(nome, cognome, "P" + codice);
this.materia = materia;
this.oreSettimanali = 20;
}
@Override
public String getTipo() {
return "Professore";
}
@Override
public void svolgiFunzione() {
System.out.println("Prof. " + cognome + " insegna " + materia);
}
public void assegnaVoto(StudenteUniversitario studente, int voto) {
studente.registraEsame(voto);
System.out.printf("Il Prof. %s ha assegnato %d a %s%n",
cognome, voto, studente.getNomeCompleto());
}
}
public class TestUniversita {
public static void main(String[] args) {
// Creazione membri
StudenteUniversitario mario = new StudenteUniversitario("Mario", "Rossi", 123456);
StudenteUniversitario anna = new StudenteUniversitario("Anna", "Bianchi", 789012);
Professore profVerdi = new Professore("Luigi", "Verdi", "001", "Programmazione");
// Assegnazione voti
profVerdi.assegnaVoto(mario, 28);
profVerdi.assegnaVoto(mario, 30);
profVerdi.assegnaVoto(anna, 24);
profVerdi.assegnaVoto(anna, 26);
// Polimorfismo: array di tipo base
MembroUniversita[] membri = {mario, anna, profVerdi};
System.out.println("\n=== Membri Universita ===");
for (MembroUniversita m : membri) {
System.out.println(m.getTipo() + ": " + m.getNomeCompleto());
System.out.println("Codice: " + m.getCodice());
m.svolgiFunzione();
// Verifica se implementa Valutabile
if (m instanceof Valutabile) {
Valutabile v = (Valutabile) m;
System.out.printf("Media: %.2f - %s%n", v.getMedia(), v.getGiudizio());
}
System.out.println("---");
}
}
}
결론
이 기사에서는 상속, 다형성, 추상 클래스를 살펴보았습니다. 인터페이스 - 코드를 생성할 수 있는 OOP의 고급 요소 유연하고 재사용이 가능합니다.
에서 다음 기사 우리는 볼 것이다 자바 코어 API: 문자열, StringBuilder, 래퍼 클래스 및 날짜/시간 API.
기억해야 할 핵심 사항
- 확장: 클래스의 단일 상속
- 구현: 인터페이스 구현(다중)
- @보수: 슈퍼클래스의 메서드를 재정의합니다.
- 추상적인: 구현이 없는 메소드, 인스턴스화할 수 없는 클래스
- 인터페이스: 무상태 행동 계약
- 기본: 인터페이스에 구현된 메서드







