Compartir tecnología

[Introducción a JAVA] Día 15 - Interfaz

2024-07-12

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

[Introducción a JAVA] Día 15 - Interfaz



¿Por qué hay una interfaz?
Como todos sabemos, la herencia consiste en extraer las abstracciones comunes de la subclase a la clase principal y obtenerpuntos comunes de todo el sistemaSin embargo, para guardar código, también existe una situación: la mayoría de las subclases tienen ciertos puntos en común, pero solo unas pocas subclases no tienen esta característica, entonces, si estos puntos en común se escriben en la clase principal, se heredarán, lo cual no es razonable para estas pocas subcategorías.
Por ejemplo: los gatos y los perros pueden nadar, pero los conejos no. En este momento, si el método de "natación" está definido en la clase principal, no es razonable que el conejo lo herede, pero si los gatos y los perros escriben sus propios métodos de natación. respectivamente, puede suceder que el formato de escritura y el nombre de los dos métodos sean inconsistentes. Por lo tanto, necesitamos definir un nuevo concepto para restringir las especificaciones de escritura de los métodos de "natación" en estas dos subclases.En este punto, podemos definir una "natación".interfaz, defina el método abstracto swim () en la interfaz y luego permita que los gatos y perros se conecten a esta interfaz para garantizarUnificación de código
En resumen, la interfaz es unaregla, cuando necesitamos definir reglas para múltiples clases al mismo tiempo, necesitamos usarinterfaz

1. La interfaz es una abstracción de "comportamiento"

La interfaz no representa un tipo de cosa, la interfaz representauna regla, por lo que las interfaces se pueden pasar como parámetros a los métodos.
"Ya sea un camión, un vehículo de tres ruedas o mano de obra, siempre que pueda moverse, será útil".

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

2. Definición y uso de interfaces

  • Las interfaces se definen con la palabra clave interfaz.
public interface 接口名 {}
  • 1
  • No se pueden crear instancias de las interfaces, lo que significa que no se pueden utilizar para crear objetos.
  • La diferencia entre interfaz y clase eslograrLas relaciones están representadas por la palabra clave implements.
public class 类名 implements 接口名 {}
  • 1
  • Una subclase de una interfaz (clase de implementación) anula todos los métodos abstractos de la interfaz o es en sí misma una clase abstracta.
  • La relación de implementación entre interfaces y clases puede serImplementación única, puede tambiénMúltiples implementaciones
public class 类名 implements 接口名1 , 接口名2 {}
  • 1
  • Una clase de implementación puede implementar múltiples interfaces mientras hereda una clase.
public class 类名 extends 父类 implements 接口名1 , 接口名2 {}
  • 1

práctica:Escribir clases Javabean estándar con interfaces y clases abstractas.

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

Primero escriba la clase principal. Debido a que las tres subclases comen cosas diferentes, puede definir eat() como un método abstracto:

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

Interfaz de escritura Nadar:

package oopInterface;

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

Al escribir una clase de rana, preste atención a heredar la clase principal y reescribir el método abstracto de la clase principal, y preste atención a implementar la interfaz de natación:

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

Al escribir una clase de perro, preste atención a heredar la clase principal y anular el método abstracto de la clase principal para implementar la interfaz de natación:

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

Al escribir una clase de conejo, tenga en cuenta que solo necesita heredar la clase principal y anular el método abstracto, y no necesita implementar la interfaz de natación (no puede nadar):

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

Escribe clases de prueba.

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. Características de los miembros en la interfaz.

  • Variables miembro: las variables miembro en una interfaz solo pueden serconstante, el final estático público se usa de forma predeterminada (incluso si no lo escribe, se considerará automáticamente de esta manera).
  • Constructor: interfazNoMétodo de construcción.
  • Métodos miembros: antes de JDK7, solo podían ser métodos abstractos.por defectoEl modificador es abstracto público; después de JDK8, los métodos con cuerpos de método se pueden definir en interfaces; después de JDK9, los métodos privados se pueden definir en interfaces.

4. La relación entre interfaces y clases.

  • La relación entre clases: Relación de herencia: solo es posible la herencia única, no la herencia múltiple, pero la herencia de varios niveles.
  • La relación entre clases e interfaces: relación de implementación: se puede implementar sola o en múltiples implementaciones, y también se pueden implementar múltiples interfaces mientras se hereda una clase.
  • La relación entre interfaces: relación de herencia: puede ser herencia única o herencia múltiple.

Aviso:
1. Cuando una clase implementa una interfaz, debe implementar todos los métodos abstractos en la interfaz o la clase en sí también es una clase abstracta.
2. Una clase puede implementar múltiples interfaces. Si implementa múltiples interfaces, debe serlo.todoSe implementan todos los métodos abstractos que se implementarán en la interfaz.
3. Las interfaces se pueden heredar de múltiples interfaces. Si una subinterfaz hereda múltiples interfaces y luego es implementada por una clase de implementación, entonces la clase de implementación debe combinar la subinterfaz y todas sus interfaces principales.todoSe implementan todos los métodos abstractos.

práctica:Escribir clases Javabean estándar con interfaces y clases abstractas.

乒乓球运动员:姓名,年龄,学打乒乓球,说英语
篮球运动员:姓名,年龄,学打篮球
乒乓球教练:姓名,年龄,教打乒乓球,说英语
篮球教练:姓名,年龄,教打篮球
  • 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. Nuevos métodos en la interfaz.

5.1 Nuevos métodos en la interfaz de inicio de JDK8

Antes de JDK7, sólo se podían definir métodos abstractos en las interfaces.
La nueva característica de JDK8 es: los métodos con cuerpos de método se pueden definir en la interfaz (se pueden definirpor defectométodo oestáticométodo).
La nueva característica de JDK9 es: se puede definir en la interfazprivadométodo.

5.1.1 Métodos predeterminados en interfaces

Los métodos con cuerpos de método se definen en la interfaz, principalmente paraActualización de interfazTeniendo en cuenta que la interfaz no puede ser inmutable, es necesario agregarle nuevos métodos para actualizar. Si estos métodos son métodos abstractos, en este momento, estos métodos deben implementarse en la clase de implementación al mismo tiempo, lo cual es muy problemático. no es fácil de sincronizar; si La actualización utiliza un método con un cuerpo de método, por lo que no es necesario modificar la clase de implementación adicionalmente. Si se necesitan modificaciones, también se pueden modificar reescribiendo.

  • Para definir métodos predeterminados en la interfaz, debe usar palabras clave por defecto Aseo.
  • Formato: nombre del método de tipo de valor de retorno predeterminado público (lista de parámetros) { }
  • Ejemplo: show nulo público predeterminado() { }
  • Los métodos predeterminados no son métodos abstractos y no es necesario anularlos. Pero si se reescribe, la palabra clave predeterminada debe eliminarse al reescribir.
  • Se puede omitir público, pero no se puede omitir el valor predeterminado.
  • Si se implementan varias interfaces y hay métodos predeterminados con el mismo nombre en varias interfaces, entonces la subclase debe anular el método (no anular provocará conflictos).

Interfaz 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

Interfaz Inter2:

package oopInterface5;

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

Los dos métodos predeterminados tienen el mismo nombre. Si la clase de implementación implementa estas dos interfaces al mismo tiempo, ¡este método predeterminado debe reescribirse!

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

Clase de prueba:

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 Métodos estáticos en interfaces

JDK8 y versiones posteriores permitirán definir métodos estáticos en interfaces, que deberán modificarse con estático.
en interfazmétodo estáticoEl formato de definición es:

  • nombre del método del tipo de valor de retorno estático público (lista de parámetros) { }
  • Ejemplo: show público estático vacío() { }

Cosas a tener en cuenta sobre los métodos estáticos en las interfaces:

  • Los métodos estáticos sólo pueden pasarNombre de la interfazLlamado, no se puede llamar mediante el nombre de la clase de implementación o el nombre del objeto.
  • Se puede omitir el público, no se puede omitir el estático.

Escribe una interfaz:

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

Escriba una clase de implementación. También hay un método estático en la clase con el mismo nombre que el método en la interfaz, pero esto no se anula porque los métodos estáticos no se pueden anular:

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

Pero, de hecho, los dos son métodos diferentes.

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 Nuevos métodos en la interfaz de inicio de JDK9

5.2.1 Definir métodos privados en la interfaz.
  • Formato 1: nombre del método de tipo de valor de retorno privado (lista de parámetros) { }
  • Ejemplo 1: show privado vacío() { }
  • Uso: Sirve el método predeterminado.
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: nombre del método de tipo de valor de retorno estático privado (lista de parámetros) {}
  • Ejemplo 2: método privado estático void() { }
  • Uso: Sirve métodos estáticos.
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. Aplicación de interfaz

1. La interfaz representa reglas y es una abstracción del comportamiento. Si desea que una clase tenga un comportamiento, simplemente deje que la clase implemente la interfaz correspondiente.
2. Cuando el parámetro de un método es una interfaz, se puede pasar la interfazTodos los objetos de la clase de implementación., este enfoque se llama polimorfismo de interfaz.

7. Patrón de diseño del adaptador

  • Design Pattern es un conjunto de experiencias de diseño de código clasificado y catalogado que se utilizan repetidamente y son conocidos por la mayoría de las personas. El propósito de utilizar patrones de diseño es reutilizar el código, hacer que otros lo entiendan más fácilmente, garantizar la confiabilidad del código y la reutilización del programa.

Los adaptadores se pueden utilizar para simplificar el código y evitar los inconvenientes causados ​​cuando hay demasiados métodos abstractos en la interfaz y solo necesitamos usar parte de ellos.
Los pasos de escritura generalmente son:
1. Escriba la clase intermedia XXXAdapter para implementar la interfaz correspondiente.
2. Implementar implementaciones vacías de métodos abstractos en la interfaz.
3. Deje que la clase de implementación real herede la clase intermedia y reescriba los métodos requeridos.
4. Para evitar que otras clases creen objetos de la clase adaptadora, la clase adaptadora intermedia está decorada con abstracto.

interfaz:

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

Clase de adaptador:

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

Clase de implementación:

package AdapterDesignPattern;

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

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