3

我正在查看 Java 网站上提供的接口章节
Using Interface as a type
所以我的理解是,接口的全部意义在于它就像一个类,但不可能从中形成对象,但是这个页面说明了如何使用接口作为数据类型。该行Relatable obj1 = (Relatable)object1;似乎创建了一个类型的对象,Relatable它是一个接口。虽然我必须说new这里没有使用关键字,因此并没有真正创建对 type 对象的引用Relatable。这真的是这条线没有创建类型对象的原因Relatable吗?

再次,它进一步说

如果您强调在各种类中实现 Relatable,那么从这些类中的任何一个实例化的对象都可以与 findLargest() 方法进行比较——前提是这两个对象属于同一个类。

这是什么意思?这是否意味着实现Relatable可以调用的任何东西findLargest()?如果是这样,为什么它说provided that both objects are of the same class

----- 编辑 -----
从本教程的前几章:相关的
定义:

public interface Relatable {

    // this (object calling isLargerThan)
    // and other must be instances of 
    // the same class returns 1, 0, -1 
    // if this is greater // than, equal 
    // to, or less than other
    public int isLargerThan(Relatable other);
}  

使用相关作为类型:

public Object findLargest(Object object1, Object object2) {
   Relatable obj1 = (Relatable)object1;
   Relatable obj2 = (Relatable)object2;
   if ((obj1).isLargerThan(obj2) > 0)
      return object1;
   else 
      return object2;
}

----- 编辑 2 -----
在匿名类的章节中,它这样做:

public class HelloWorldAnonymousClasses {

    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }
.
.
.
 HelloWorld englishGreeting = new EnglishGreeting();

        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

那么这是如何工作的呢?

4

5 回答 5

4

Relatable obj1 = (Relatable)object1; 似乎创建了一个 Relatable 类型的对象

不,这一行创建了一个类型的引用(obj1)Relatable并将其分配给object1. 为了使它起作用,object1必须强制转换为 (interface) type Relatable
这里没有创建新对象。

这是否意味着任何实现 Relatable 的东西都可以调用 findLargest()?

是的。

如果是这样,为什么它说假设两个对象属于同一类?

它与isLargerThan(). 由于任何实现该Relatable接口的类都不知道其他实现它的类的任何信息,因此它们无法与其他类进行有意义的比较。因此,为了使其工作,两个对象需要属于同一类。

对编辑 2 的回应

那么这是如何工作的呢?

不是首先定义一个类,然后创建它的实例,就像在 的情况下一样EnglishGreetingfrenchGreeting而是动态创建的。幕后发生的事情HelloWorld是创建了一个新的类实现,就像在英语的情况下一样,只是这次它是匿名的(你永远不能给它一个名字)。当您需要一次性实现接口时,它只是一种方便的快捷方式。

于 2013-07-22T09:27:56.860 回答
3

接口类型属于java中引用类型的范畴。你永远不能实例化一个接口,但它可以被分配对任何实现它的类的对象的引用:

声明类型为接口类型的变量可以将其值作为对实现指定接口的类的任何实例的引用。

接口就像行为。如果一个类碰巧实现了一个接口,比方说Serializable,这会为该类添加一个行为,即该类可以被序列化。

这有助于您在代码中引入抽象。例如,假设您需要一个实用程序类中的方法,该方法将负责序列化的实际工作。如果没有接口,您最终将编写大量方法,每个方法用于您想要序列化的每种对象类型。现在想象一下,如果您要求每个对象自己处理它们的序列化(通过实现serialize在它们实现的接口中声明的方法)。使用这样的实现,您只需要编写一种用于序列化的实用方法。这个方法可以接受一个Serializable类型的参数,并且任何实现这个接口的类的实例都可以传递给这个方法。现在在方法中你只需要调用serialize接口变量上的方法。在运行时,这将导致serialize调用实际对象的方法。

希望我能够保持简单。

于 2013-07-22T09:35:32.257 回答
2

接口只是一个定义对象行为的类,而不是它的底层实现。通过使Relatable obj1 = (Relatable)object1;您只是将 object1 转换为 Relatable 类型,因此您可以调用 Relatable 接口中定义的任何方法

于 2013-07-22T09:29:20.587 回答
2

Java中的接口是实现接口的类的相互结构,因此类以自己的方式从该接口的方法/其他成员中受益,这称为多态性,

interface A
{
  // method header only declared here, so implementation can vary between classes
  public int foo(); 
}

class B implements A
{
   public override String foo()
   {
     return "Class B";
   }
}

class C implements A
{
   public override String foo()
   {
     return "Class C";
   }
}

因此您可以同时调用foo()两者class BC但它们会做出不同的反应,因为它们以自己的方式实现该方法

于 2013-07-22T09:31:18.657 回答
1

关于你的第一个问题Relatable obj1 = (Relatable)object1;

simpleRelatable obj1;不会创建 Relatable 的实例,但指定分配给它的任何对象都必须是实现 Relatable 接口的类型。

因此,要转换的任何对象都必须是实现 Relatable 接口的类型。

于 2013-07-22T09:29:12.913 回答