哪些Java类型可以实现接口?
Java中没有多重继承的概念,但是借助接口我们可以实现多重继承。接口是一个命名的定义集合。 (不执行)
Java的接口是一种特殊的类。和类一样,接口包含方法和成员;与类不同,接口中的所有成员都是最终的,所有方法都是抽象的。
//interface definition
//we use interface keyword to declare interface
interface
variable declaration; //
method declaration; //does not implement them, are always public and abstract.
}
//class which implements interface
public class
//the methods declared my interface class should be implemented by the class which implement it.
}
- 我们无法在Java中实例化接口,这意味着我们无法创建接口类的对象。
- 实现接口的类必须为其所有方法提供实现,除非它是抽象类。
- 默认情况下,接口的任何属性都是 public、static 和 final。因此,不需要为属性提供访问修饰符,但如果它符合,也不会抱怨它。
- 默认情况下,方法是隐式抽象和公共的,这是完全有意义的,因为方法没有主体,因此子类可以提供方法实现。
- 静态方法不能在接口中声明——这些方法永远不是抽象的,也不表达对象的行为
Java类型实现接口
主要有 5 种Java类型可以实现下面列出的接口,我们将在稍后深入探讨如下:
- Java类
- Java抽象类
- Java嵌套类
- Java枚举
- 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}