Condivisione della tecnologia

[Introduzione a JAVA] Giorno 15 - Interfaccia

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

[Introduzione a JAVA] Giorno 15 - Interfaccia



Perché c'è un'interfaccia?
Come tutti sappiamo, l'ereditarietà consiste nell'estrarre le astrazioni comuni della sottoclasse nella classe genitore e ottenerlecomunanza dell’intero sistemaPer salvare il codice, tuttavia, c'è anche una situazione: la maggior parte delle sottoclassi ha una certa comunanza, ma solo poche sottoclassi non hanno questa caratteristica, quindi se questa comunanza viene scritta nella classe genitore, verrà ereditata, il che è irragionevole per queste poche sottocategorie.
Ad esempio: cani e gatti possono nuotare, ma i conigli no. In questo momento, se il metodo "nuoto" è definito nella classe genitore, è irragionevole che il coniglio lo erediti. Tuttavia, se cani e gatti scrivono i propri metodi di nuoto rispettivamente, potrebbe accadere che il formato di scrittura e la denominazione dei due metodi non siano coerenti. Pertanto, dobbiamo definire un nuovo concetto per vincolare le specifiche di scrittura dei metodi di "nuoto" in queste due sottoclassi.A questo punto possiamo definire un “nuoto”interfaccia, definisci il metodo astratto swim() nell'interfaccia, quindi lascia che cani e gatti si connettano a questa interfaccia per garantireUnificazione del codice
Per riassumere, l'interfaccia è aregola, quando dobbiamo definire regole per più classi contemporaneamente, dobbiamo utilizzareinterfaccia

1. L’interfaccia è un’astrazione del “comportamento”

L'interfaccia non rappresenta un tipo di cosa, l'interfaccia rappresentauna regola, quindi le interfacce possono essere passate come parametri ai metodi.
"Che si tratti di un camion, di un tre ruote o di manodopera, purché possa muoversi, sarà utile."

搬家(车的对象);
  • 1
搬家(搬家公司);
  • 1
public interface 运输 {
	...
}
  • 1
  • 2
  • 3
public void 搬家(运输的接口 c) {
	...
}
  • 1
  • 2
  • 3

2. Definizione e utilizzo delle interfacce

  • Le interfacce sono definite con la parola chiave interfaccia.
public interface 接口名 {}
  • 1
  • Non è possibile istanziare le interfacce, il che significa che le interfacce non possono essere utilizzate per creare oggetti.
  • La differenza tra interfaccia e classe ècompiereLe relazioni sono rappresentate dalla parola chiave implements.
public class 类名 implements 接口名 {}
  • 1
  • Una sottoclasse di un'interfaccia (classe di implementazione) sovrascrive tutti i metodi astratti nell'interfaccia o è essa stessa una classe astratta.
  • La relazione di implementazione tra interfacce e classi può essereImplementazione unica, possono ancheMolteplici implementazioni
public class 类名 implements 接口名1 , 接口名2 {}
  • 1
  • Una classe di implementazione può implementare più interfacce ereditando una classe.
public class 类名 extends 父类 implements 接口名1 , 接口名2 {}
  • 1

pratica:Scrivi classi Javabean standard con interfacce e classi astratte.

 青蛙		属性:名字,年龄		行为:吃虫子,蛙泳
 狗			属性:名字,年龄		行为:吃骨头,狗刨
 兔子		属性:名字,年龄		行为:吃胡萝卜
  • 1
  • 2
  • 3

Scrivi prima la classe genitore Poiché le tre sottoclassi mangiano cose diverse, puoi definire eat() come un metodo astratto:

package oopInterface;

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(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 abstract void eat();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Scrivi l'interfaccia Nuota:

package oopInterface;

public interface Swim {
    public abstract void swim();
}
  • 1
  • 2
  • 3
  • 4
  • 5

Quando scrivi una classe di rana, presta attenzione a ereditare la classe genitore e a riscrivere il metodo astratto della classe genitore, e presta attenzione all'implementazione dell'interfaccia di nuoto:

package oopInterface;

public class Frog extends Animal implements Swim {
    public Frog() {
        super();
    }

    public Frog(String name, int age) {
        super(name, age);
    }

    @Override
    public void swim() {
        System.out.println("青蛙在蛙泳。");
    }

    @Override
    public void eat() {
        System.out.println("青蛙在吃虫子。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Quando scrivi una classe per cani, presta attenzione a ereditare la classe genitore e sovrascrivere il metodo astratto della classe genitore per implementare l'interfaccia di nuoto:

package oopInterface;

public class Dog extends Animal implements Swim {

    public Dog(){
        super();
    }

    public Dog(String name, int age) {
        super(name,age);
    }
    @Override
    public void swim() {
        System.out.println("狗在狗刨。");
    }

    @Override
    public void eat() {
        System.out.println("狗在吃骨头。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Quando scrivi una classe coniglio, tieni presente che devi solo ereditare la classe genitore e sovrascrivere il metodo astratto e non è necessario implementare l'interfaccia di nuoto (non puoi nuotare):

package oopInterface;

public class Rabbit extends Animal {

    public Rabbit() {
    }

    public Rabbit(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("兔子在吃胡萝卜。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Scrivi lezioni di prova.

package oopInterface;

public class Test {
    public static void main(String[] args) {
        Frog f = new Frog("小绿",23);
        f.eat();
        f.swim();
        System.out.println(f.getName() + ", " + f.getAge());
        Dog d = new Dog("大D", 24);
        d.eat();
        d.swim();
        System.out.println(d.getName() + ", " + d.getAge());
        Rabbit r = new Rabbit("兔子", 30);
        r.eat();
        System.out.println(r.getName() + ", " + r.getAge());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3. Caratteristiche dei membri nell'interfaccia

  • Variabili membro: le variabili membro in un'interfaccia possono essere solocostante, public static final viene utilizzato per impostazione predefinita (anche se non lo scrivi, verrà automaticamente considerato in questo modo).
  • Costruttore: interfacciaNOMetodo di costruzione.
  • Metodi membri: prima di JDK7, potevano essere solo metodi astratti.predefinitoIl modificatore è public abstract; dopo JDK8, i metodi con corpi di metodo possono essere definiti nelle interfacce dopo JDK9, i metodi privati ​​possono essere definiti nelle interfacce;

4. La relazione tra interfacce e classi

  • La relazione tra le classi: relazione di ereditarietà: è possibile solo l'ereditarietà singola, non l'ereditarietà multipla, ma l'ereditarietà a più livelli.
  • La relazione tra classi e interfacce: relazione di implementazione: può essere implementata da sola o in più implementazioni ed è anche possibile implementare più interfacce ereditando una classe.
  • La relazione tra le interfacce: relazione di ereditarietà: può essere ereditarietà singola o multipla.

Avviso:
1. Quando una classe implementa un'interfaccia, deve implementare tutti i metodi astratti nell'interfaccia oppure anche la classe stessa è una classe astratta.
2. Una classe può implementare più interfacce Se implementa più interfacce, deve esserloTuttoVengono implementati tutti i metodi astratti da implementare nell'interfaccia.
3. Le interfacce possono essere ereditate da più interfacce. Se una sottointerfaccia eredita più interfacce e viene quindi implementata da una classe di implementazione, allora la classe di implementazione deve combinare la sottointerfaccia e tutte le sue interfacce principali.TuttoTutti i metodi astratti sono implementati.

pratica:Scrivi classi Javabean standard con interfacce e classi astratte.

乒乓球运动员:姓名,年龄,学打乒乓球,说英语
篮球运动员:姓名,年龄,学打篮球
乒乓球教练:姓名,年龄,教打乒乓球,说英语
篮球教练:姓名,年龄,教打篮球
  • 1
  • 2
  • 3
  • 4
//Person类
package oopInterExp;

//因为直接创建顶层父类人的对象是没有意义的
//所以将其写为抽象类
public abstract class Person {
    private String name;
    private int age;

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

    public Person() {
    }

    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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
//Sporter类继承Person
package oopInterExp;

public abstract class Sporter extends Person {

    public Sporter(String name, int age) {
        super(name, age);
    }

    public Sporter() {
    }

    public abstract void learn();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
//Coach类继承Person
package oopInterExp;

public abstract class Coach extends Person {

    public Coach() {
    }

    public Coach(String name, int age) {
        super(name, age);
    }

    public abstract void teach();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
//SpeakEnglish接口
package oopInterExp;

public interface SpeakEnglishInter {
    public abstract void speakEnglish();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//PingPongSporter继承Sporter,实现SpeakEnglish
package oopInterExp;

public class PingPongSporter extends Sporter implements SpeakEnglishInter {

    public PingPongSporter(String name, int age) {
        super(name, age);
    }

    public PingPongSporter() {
    }

    @Override
    public void learn() {
        System.out.println("学习乒乓球。");
    }

    @Override
    public void speakEnglish() {
        System.out.println("乒乓球运动员在说英语。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
//PingPongCoach继承Coach,实现SpeakEnglish
package oopInterExp;

public class PingPongCoach extends Coach implements SpeakEnglishInter {
    public PingPongCoach() {
    }

    public PingPongCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("教乒乓球。");
    }

    @Override
    public void speakEnglish() {
        System.out.println("乒乓球教练在说英语。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
//BasketballSporter继承Sporter
package oopInterExp;

public class BasketballSporter extends Sporter {

    public BasketballSporter(String name, int age) {
        super(name, age);
    }

    public BasketballSporter() {
    }

    public void learn() {
        System.out.println("学篮球。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
//BasketballCoach继承Coach
package oopInterExp;

public class BasketballCoach extends Coach {

    public BasketballCoach() {
    }

    public BasketballCoach(String name, int age) {
        super(name, age);
    }

    public void teach() {
        System.out.println("教篮球。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5. Nuovi metodi nell'interfaccia

5.1 Nuovi metodi nell'interfaccia di avvio JDK8

Prima del JDK7, nelle interfacce potevano essere definiti solo metodi astratti.
La nuova funzionalità di JDK8 è: i metodi con corpi di metodo possono essere definiti nell'interfaccia (can definepredefinitometodo ostaticometodo).
La nuova caratteristica di JDK9 è: può essere definito nell'interfacciaprivatometodo.

5.1.1 Metodi predefiniti nelle interfacce

I metodi con corpi del metodo sono definiti nell'interfaccia, principalmente perAggiornamento dell'interfacciaConsiderando che l'interfaccia non può essere immutabile, è necessario aggiungervi nuovi metodi per l'aggiornamento. Se questi metodi sono metodi astratti, in questo momento, questi metodi devono essere implementati contemporaneamente nella classe di implementazione, il che è molto problematico e. non è facile da sincronizzare; se l'aggiornamento utilizza un metodo con un corpo del metodo, quindi non è necessario modificare ulteriormente la classe di implementazione. Se sono necessarie modifiche, è possibile modificarle anche riscrivendole.

  • Per definire i metodi predefiniti nell'interfaccia, è necessario utilizzare le parole chiave predefinito Toelettatura.
  • Formato: nome del metodo del tipo di valore restituito predefinito pubblico (elenco dei parametri) { }
  • Esempio: public default void show() { }
  • I metodi predefiniti non sono metodi astratti e non devono essere sovrascritti. Ma se viene riscritto, la parola chiave predefinita deve essere rimossa durante la riscrittura.
  • public può essere omesso, ma default non può essere omesso.
  • Se sono implementate più interfacce e sono presenti metodi predefiniti con lo stesso nome in più interfacce, la sottoclasse deve sovrascrivere il metodo (non sovrascrivere causerà conflitti).

Interfaccia Inter1:

package oopInterface5;

public interface Inter1 {
    public abstract void method();
    public default void default_method() {
        System.out.println("Inter1接口中的默认方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Interfaccia Inter2:

package oopInterface5;

public interface Inter2 {
    public default void default_method() {
        System.out.println("Inter2接口中的默认方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

I due metodi predefiniti hanno lo stesso nome Se la classe di implementazione implementa queste due interfacce contemporaneamente, questo metodo predefinito deve essere riscritto!

package oopInterface5;

public class InterImpl implements Inter1, Inter2 {

    @Override
    public void method() {
        System.out.println("抽象方法的实现");
    }

    @Override
    public void default_method() {
        System.out.println("重写接口中的默认方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Classe di prova:

package oopInterface5;

public class Test {
    public static void main(String[] args) {
            InterImpl ii = new InterImpl();
            ii.method();				//抽象方法的实现
            ii.default_method();		//重写接口中的默认方法
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
5.1.2 Metodi statici nelle interfacce

JDK8 e versioni successive consentiranno di definire metodi statici nelle interfacce, che dovranno essere modificate con static.
nell'interfacciametodo staticoIl formato della definizione è:

  • tipo di valore restituito statico pubblico nome del metodo (elenco parametri) { }
  • Esempio: public static void show() { }

Cose da notare sui metodi statici nelle interfacce:

  • I metodi statici possono solo passareNome dell'interfacciaChiamato, non può essere chiamato tramite il nome della classe di implementazione o il nome dell'oggetto.
  • public può essere omesso, static non può essere omesso.

Scrivi un'interfaccia:

package oopInterface6;

public interface Inter {
    public abstract void method();

    public static void static_method() {
        System.out.println("接口中的静态方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Scrivi una classe di implementazione Nella classe è presente anche un metodo statico con lo stesso nome del metodo nell'interfaccia, ma questo non ha priorità perché i metodi statici non possono essere sovrascritti:

package oopInterface6;

public class InteImpl implements Inter {
    @Override
    public void method() {
        System.out.println("重写接口中的抽象方法");
    }

    //这不叫重写
    public static void static_method() {
        System.out.println("我不是重写的Inter接口中的静态方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Ma in realtà i due sono metodi diversi.

package oopInterface6;

public class Test {
    public static void main(String[] args) {
        InteImpl ii = new InteImpl();
        ii.method();						  //重写接口中的抽象方法
        Inter.static_method();               //调用接口中的静态方法
        InteImpl.static_method();           //调用实现类中的一个同名的静态方法
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.2 Nuovi metodi nell'interfaccia di avvio JDK9

5.2.1 Definire metodi privati ​​nell'interfaccia
  • Formato 1: nome del metodo del tipo di valore restituito privato (elenco dei parametri) { }
  • Esempio 1: private void show() { }
  • Utilizzo: servire il metodo predefinito.
package oopInterface7;

public interface InterA {
    public default void show1() {
        System.out.println("show1开始执行");
        show3();
    }

    public default void show2() {
        System.out.println("show2开始执行");
        show3();
    }

    //普通的私有方法,给默认方法服务的
    private void show3() {
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • Formato 2: nome del metodo del tipo di valore restituito statico privato (elenco dei parametri) { }
  • Esempio 2: metodo void statico privato() { }
  • Utilizzo: servire metodi statici.
package oopInterface7;

public interface InterB {
    public static void show1() {
        System.out.println("show1开始执行");
        show3();
    }

    public static void show2() {
        System.out.println("show2开始执行");
        show3();
    }

    //普通的私有方法,给静态方法服务的
    private static void show3() {
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码。");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

6. Applicazione dell'interfaccia

1. L'interfaccia rappresenta le regole ed è un'astrazione del comportamento. Se vuoi che una classe abbia un comportamento, lascia semplicemente che la classe implementi l'interfaccia corrispondente.
2. Quando il parametro di un metodo è un'interfaccia, è possibile passare l'interfacciaTutti gli oggetti della classe di implementazione, questo approccio è chiamato polimorfismo dell'interfaccia.

7. Modello di progettazione dell'adattatore

  • Design Pattern è un insieme di esperienze di progettazione di codice classificate e catalogate che vengono utilizzate ripetutamente, note alla maggior parte delle persone. Lo scopo dell'utilizzo dei modelli di progettazione è riutilizzare il codice, renderlo più facilmente comprensibile da altri, garantire l'affidabilità del codice e la riusabilità del programma.

Gli adattatori possono essere utilizzati per semplificare il codice ed evitare gli inconvenienti causati quando ci sono troppi metodi astratti nell'interfaccia e dobbiamo usarne solo una parte.
Le fasi di scrittura sono generalmente:
1. Scrivi la classe intermedia XXXAdapter per implementare l'interfaccia corrispondente.
2. Implementare implementazioni vuote di metodi astratti nell'interfaccia.
3. Lasciare che la classe di implementazione reale erediti la classe intermedia e riscrivere i metodi richiesti.
4. Per impedire ad altre classi di creare oggetti della classe dell'adattatore, la classe dell'adattatore intermedio è decorata con abstract.

interfaccia:

package AdapterDesignPattern;

public interface Inter {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
    public abstract void method4();
    public abstract void method5();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Classe dell'adattatore:

package AdapterDesignPattern;

public abstract class InterAdapter implements Inter {
    @Override
    public void method1() {

    }

    @Override
    public void method2() {

    }

    @Override
    public void method3() {

    }

    @Override
    public void method4() {

    }

    @Override
    public void method5() {

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Classe di implementazione:

package AdapterDesignPattern;

public class InterImpl extends InterAdapter {
    //我需要用到哪个方法,就重写哪个方法就可以了
    @Override
    public void method5() {
        System.out.println("只要用第五个方法");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10