📜  哪些Java类型可以实现接口?

📅  最后修改于: 2022-05-13 01:54:49.647000             🧑  作者: Mango

哪些Java类型可以实现接口?

Java中没有多重继承的概念,但是借助接口我们可以实现多重继承。接口是一个命名的定义集合。 (不执行)

Java的接口是一种特殊的类。和类一样,接口包含方法和成员;与类不同,接口中的所有成员都是最终的,所有方法都是抽象的。

  • 我们无法在Java中实例化接口,这意味着我们无法创建接口类的对象。
  • 实现接口的类必须为其所有方法提供实现,除非它是抽象类。
  • 默认情况下,接口的任何属性都是 public、static 和 final。因此,不需要为属性提供访问修饰符,但如果它符合,也不会抱怨它。
  • 默认情况下,方法是隐式抽象和公共的,这是完全有意义的,因为方法没有主体,因此子类可以提供方法实现。
  • 静态方法不能在接口中声明——这些方法永远不是抽象的,也不表达对象的行为

Java类型实现接口



主要有 5 种Java类型可以实现下面列出的接口,我们将在稍后深入探讨如下:

  1. Java类
  2. Java抽象类
  3. Java嵌套类
  4. Java枚举
  5. Java动态代理

类型 1: Java类

当一个类实现一个接口时,它本质上是在签署一个契约。要么类必须实现接口及其超接口中声明的所有方法,要么类必须声明为抽象的。

要声明一个实现接口的类,请在类声明中包含一个 implements 关键字。您的类可以实现多个接口,因此implements 关键字后跟以逗号分隔的类实现的接口列表。

例子

Java
// Java Program illustrating Java Class implementing
// Interfaces
  
// Importing I/O classes
import java.io.*;
  
interface Animal {
  
    // final public static int x = 4;
    // public, static and final
    int x = 4;
  
    // Public and abstract
    void sound();
}
  
// Class implementing interface
class Chicks implements Animal {
  
    // Implementing the abstract method
    public void sound() { System.out.println("cheep"); }
  
    // Main driver method
    public static void main(String[] args)
    {
        Chicks c = new Chicks();
        c.sound();
        System.out.println("The value of x = " + x);
    }
}


Java
// Java Program illustrating Java Abstract Class
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
  
interface Animal {
    public void sound();
    public void breed();
}
  
abstract class Cat implements Animal {
  
    // Note: It is is not necessary to implement
    // all methods of interface class
  
    public void sound() { System.out.println("meow"); }
}
  
public class Cat1 extends Cat {
    public void breed() { System.out.println("Ragdoll"); }
}
  
class Main {
    public static void main(String[] args)
    {
        Cat1 c = new Cat1();
        c.breed();
        c.sound();
    }
}


Java
// Java Program illustrating Java Nested Classes
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
  
interface Animal {
  
    // Nested class
    public class Type {
  
        public static void animal()
        {
            System.out.println("The animal is cat");
        }
    }
  
    public void breed();
    public void sound();
}
  
public class Cat implements Animal {
  
    // Method 1
    public void breed() { System.out.println("Munchkin"); }
  
    // Method 2
    public void sound() { System.out.println("Meow"); }
}
  
// Main class 
class MainClass {
    public static void main(String args[])
    {
        Cat c = new Cat();
  
        // Calling the nested class
        Animal.Type.animal();
        c.breed();
        c.sound();
    }
}


Java
// Java Program illustrating Java Enum class
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
// interface class
interface Cat {
    public void breed();
}
  
// Class 1
// Enum class
enum Breed implements Cat {
  
    Siamese,
    Persian,
    Bengal,
    Burmese;
  
    public void breed()
    {
        System.out.print("The breed is " + this);
    }
}
  
// Class 2
// Main class
public class MainClass {
  
    // main driver method
    public static void main(String args[])
    {
        Breed.Persian.breed();
    }
}


Java
// Java Program illustrating Java Dynamic Proxy Class
// implementing Interfaces
  
package javaInterface;
// Importing I/O classes
import java.io.*;
// Interface
interface Animal {
    public void breed();
    public void sound();
}
// Class 1
// Class implementing interface
class Cat implements Animal {
    public void breed() { System.out.println("Ragdoll"); }
    public void sound() { System.out.println("meow"); }
}
// Class 2
// InvocationHandler that simply passes every method call
// through to an instance:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
class LoggingHandler implements InvocationHandler {
    private final Object target;
    private Map calls = new HashMap<>();
    public LoggingHandler(Object target)
    {
        this.target = target;
    }
    public Object invoke(Object proxy, Method method,
                         Object[] args) throws Throwable
    {
        String name = method.getName();
        if (name.contains("toString")) {
            return calls.toString();
        }
        calls.merge(name, 1, Integer::sum);
        return method.invoke(target, args);
    }
}
// Class 3
// create a proxy using this invocation handler, we use the
// newProxyInstance
// static utility method on the java.reflection.Proxy class:
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
  
class MainClass {
    @SuppressWarnings("unchecked")
    public static  T withLogging(T target, Class itf)
    {
        return (T)Proxy.newProxyInstance(
            itf.getClassLoader(), new Class[] { itf },
            new LoggingHandler(target));
    }
    public static void main(String args[])
    {
        Cat c = new Cat();
        Animal logged = withLogging(c, Animal.class);
        logged.breed();
        logged.sound();
        System.out.println(logged);
    }
}


输出
cheep
The value of x = 4

类型 2: Java抽象类

接口和抽象类在很多方面相似,但抽象类允许单继承,而接口允许多继承。如果一个类包含一个接口但没有完全实现该接口所需的方法,则该类必须声明为抽象类。

当我们为抽象类实现接口时,意味着抽象类继承了接口的所有方法。没有必要在一个抽象类中实现所有的方法,但是,它涉及到抽象类(也通过继承),所以抽象类可以将接口中的一些方法保留在这里不实现。但是,当这个抽象类被某个类继承时,他们必须在抽象类中实现所有那些未实现的方法。

例子



Java

// Java Program illustrating Java Abstract Class
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
  
interface Animal {
    public void sound();
    public void breed();
}
  
abstract class Cat implements Animal {
  
    // Note: It is is not necessary to implement
    // all methods of interface class
  
    public void sound() { System.out.println("meow"); }
}
  
public class Cat1 extends Cat {
    public void breed() { System.out.println("Ragdoll"); }
}
  
class Main {
    public static void main(String[] args)
    {
        Cat1 c = new Cat1();
        c.breed();
        c.sound();
    }
}
输出
Ragdoll
meow

类型 3: Java嵌套类

Java能够在接口中嵌套一个类。嵌套类是隐式公共和静态的。在接口内嵌套类可能很有用,尤其是当封闭接口和封闭类之间存在关系时。在接口内部嵌套类可以提高源代码的可读性。同名的类和接口,嵌套也可以帮助你避免两者之间的名称冲突。

例子

Java

// Java Program illustrating Java Nested Classes
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
  
interface Animal {
  
    // Nested class
    public class Type {
  
        public static void animal()
        {
            System.out.println("The animal is cat");
        }
    }
  
    public void breed();
    public void sound();
}
  
public class Cat implements Animal {
  
    // Method 1
    public void breed() { System.out.println("Munchkin"); }
  
    // Method 2
    public void sound() { System.out.println("Meow"); }
}
  
// Main class 
class MainClass {
    public static void main(String args[])
    {
        Cat c = new Cat();
  
        // Calling the nested class
        Animal.Type.animal();
        c.breed();
        c.sound();
    }
}
输出
The animal is cat
Munchkin
Meow

类型 4: Java枚举

Enum 可以在Java实现任何接口。由于 enum 是一种类型,类似于任何其他类和接口,它可以在Java实现任何接口。这在某些情况下为使用 Enum 实现其他一些行为提供了很大的灵活性。

例子

Java

// Java Program illustrating Java Enum class
// implementing Interfaces
  
// Importing I/O classes
import java.io.*;
// interface class
interface Cat {
    public void breed();
}
  
// Class 1
// Enum class
enum Breed implements Cat {
  
    Siamese,
    Persian,
    Bengal,
    Burmese;
  
    public void breed()
    {
        System.out.print("The breed is " + this);
    }
}
  
// Class 2
// Main class
public class MainClass {
  
    // main driver method
    public static void main(String args[])
    {
        Breed.Persian.breed();
    }
}
输出
The breed is Persian

类型 5: Java动态代理

代理通过代理对象间接调用对象方法。 Java.lang.reflect API 提供了一个类作为 Proxy 和一个接口作为 InvocationHandler。这两个 API 一起创建了一个动态代理类。代理类根据给定的参数创建动态代理类。 InvocationHandler 调用动态代理类的方法。

例子

Java

// Java Program illustrating Java Dynamic Proxy Class
// implementing Interfaces
  
package javaInterface;
// Importing I/O classes
import java.io.*;
// Interface
interface Animal {
    public void breed();
    public void sound();
}
// Class 1
// Class implementing interface
class Cat implements Animal {
    public void breed() { System.out.println("Ragdoll"); }
    public void sound() { System.out.println("meow"); }
}
// Class 2
// InvocationHandler that simply passes every method call
// through to an instance:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
class LoggingHandler implements InvocationHandler {
    private final Object target;
    private Map calls = new HashMap<>();
    public LoggingHandler(Object target)
    {
        this.target = target;
    }
    public Object invoke(Object proxy, Method method,
                         Object[] args) throws Throwable
    {
        String name = method.getName();
        if (name.contains("toString")) {
            return calls.toString();
        }
        calls.merge(name, 1, Integer::sum);
        return method.invoke(target, args);
    }
}
// Class 3
// create a proxy using this invocation handler, we use the
// newProxyInstance
// static utility method on the java.reflection.Proxy class:
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
  
class MainClass {
    @SuppressWarnings("unchecked")
    public static  T withLogging(T target, Class itf)
    {
        return (T)Proxy.newProxyInstance(
            itf.getClassLoader(), new Class[] { itf },
            new LoggingHandler(target));
    }
    public static void main(String args[])
    {
        Cat c = new Cat();
        Animal logged = withLogging(c, Animal.class);
        logged.breed();
        logged.sound();
        System.out.println(logged);
    }
}

输出:

Ragdoll
meow
{sound=1, breed=1}