[英]Why do we use interfaces when we are going to override the method anyway?
Here we're importing Comparator because the class SizeComparator implements Comparator... - Why not leave out the implements part of comparator if all we want is the compare method, which we are overriding anyway?在这里我们导入 Comparator 因为 class SizeComparator 实现了 Comparator... - 如果我们想要的只是比较方法,为什么不省略比较器的实现部分,无论如何我们都将覆盖它? Since we're overriding it why even type in the code that we want to implement the interface?
既然我们要重写它,为什么还要输入我们想要实现接口的代码呢?
I think what you're implying is the effective difference between nominal typing and structural typing.我认为你的意思是名义打字和结构打字之间的有效区别。
Structural typing is like this:结构类型是这样的:
x
is an object whose definition so happens to have a method named compare
, please invoke it.x
是一个 object ,其定义恰好有一个名为compare
的方法,请调用它。 Otherwise throw something or fail to compile. Nominal typing is like this:标称类型是这样的:
x
has a type.x
有一个类型。 If that type has a method named compare
, invoke it.compare
的方法,则调用它。 If x
is not that type, or x is but that type does not have a method named compare
, throw something, or fail to compile.x
不是那个类型,或者 x 是,但是那个类型没有一个名为compare
的方法,抛出一些东西,或者编译失败。 Java is nominally typed: You can't just go: "I want to call the compare
method on this object". Java 名义上是键入:你不能只是 go:“我想在这个对象上调用
compare
方法”。 No, the object needs to be of a known type that has a compare method.不,object 需要是具有比较方法的已知类型。 It's a 2step process: First java checks what the type of some expression is, and then you get to write method calls to methods that this type is declared to have.
这是一个两步过程:首先 java 检查某个表达式的类型是什么,然后您可以编写对声明该类型的方法的方法调用。 What the actual object's actual type is, is immaterial.
实际对象的实际类型是什么,无关紧要。 Trivial example:
简单的例子:
Object o = new ArrayList<String>();
o.add("Hello");
does not compile - because the compiler notices o.
不编译 - 因为编译器注意到
o.
, checks the type of the o
expression, finds that it is java.lang.Object
, checks what jlObject
's API exposes, notices that there is no add(String)
method in there, and fails to compile. , checks the type of the
o
expression, finds that it is java.lang.Object
, checks what jlObject
's API exposes, notices that there is no add(String)
method in there, and fails to compile. Even though at runtime it would have worked .即使在运行时它会起作用。 Because o-the-variable is pointing at an object whose real type is something that does have an
add
method.因为 o-the-variable 指向一个 object ,其实际类型是具有
add
方法的东西。
The reason that nominal typing is good goes deep, and certainly not all programming languages work that way.名义类型很好的原因很深,当然不是所有的编程语言都这样工作。 It has advantages and disadvantages.
它有优点和缺点。 For just one simple reason why structural typing can be a bit dangerous, imagine these two classes:
仅出于结构类型可能有点危险的一个简单原因,想象一下这两个类:
class Camera {
void shoot(Person p) {}
}
class Gun {
void shoot(Person p) {}
}
Hopefully that helps you see how structural typing could get problematic.希望这可以帮助您了解结构类型是如何出现问题的。 Names are useful.
名字很有用。 Namespaced names are far more useful - they avoid 'name squatting', where somebody who wrote a camera class thought they could claim the name 'shoot' as did someone writing a gun class.
命名空间名称更有用 - 它们避免了“名称抢注”,其中编写相机 class 的人认为他们可以像编写枪 class 的人一样声称他们可以使用名称“射击”。 This problem goes away if the language is fundamentally designed that all methods have a complete name, and that name is
com.martinhavens.Gun.shoot
.如果该语言从根本上设计为所有方法都有一个完整的名称,并且该名称是
com.martinhavens.Gun.shoot
,那么这个问题就会消失。 Now there is no way to accidentally blow your face off if all you wanted to do, was make a selfie.如果你想做的只是自拍,现在没有办法不小心把你的脸吹掉。
In your specific example it is perhaps possible for the system to work without it, given that SizeComparator itself also defines it, but programming is an exercise in abstraction.在您的具体示例中,系统可能在没有它的情况下工作,因为 SizeComparator 本身也定义了它,但编程是一种抽象练习。 For example, java's built in
java.util.TreeSet
class builds a tree set: It can store objects, automatically promises you that it only ever contains 1 of a given value (never duplicates), and it automatically sorts itself.例如,java 内置的
java.util.TreeSet
class 构建了一个树集:它可以存储对象,自动向您保证它只包含给定值的 1(从不重复),并且它会自动对自身进行排序。 It does this by making a tree structure.它通过创建树结构来做到这一点。 To make such a class, you need to provide - A comparator .
要制作这样的 class,您需要提供-A 比较器。 Obviously, the authors of java-the-core-library cannot know that you have written your own class named
SizeComparator
.显然,java-the-core-library 的作者不知道您已经编写了自己的 class,名为
SizeComparator
。 Hence, only 3 options:因此,只有 3 个选项:
TreeSet
, as long as it is something that has a compare(T a, T b)
method.TreeSet
的构造函数的内容并不重要,只要它具有compare(T a, T b)
方法即可。 Possible, but java is not like that, and there are advantages to this - see above.TreeSet
also publish a type that describes what "code capable of comparing things in the way TreeSet needs to do its job", and then any code anybody else writes with the intention of feeding it to TreeSet's constructor must indicate they are an implementation of this. TreeSet
的作者还发布了一种类型,该类型描述了“能够以 TreeSet 完成其工作的方式比较事物的代码”,然后任何其他人编写的意图将其提供给 TreeSet 的构造函数的任何代码都必须表明它们是一个实现这个的。 Which is exactly how java works.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.