[英]Java - Adding methods to interface implementation
I'll use an easy example for the sake of the question.为了这个问题,我将使用一个简单的例子。
If I have an Interface
say Animal
which is like如果我有一个
Interface
说Animal
就像
public interface Animal {
void jump();
}
And I'm creating an object of the interface on the go, like我正在旅途中创建界面的对象,例如
public class Main {
public static void main(String[] args) {
Animal cat = new Animal() {
@Override
public void jump() {
System.out.println("The cat jumped");
}
public void sleep() {
System.out.println("The cat slept");
}
};
cat.jump();
cat.sleep(); // cannot do that.
}
}
Now, I added the sleep()
method to the interface implementation and want that method to be callable from the place where I'm calling cat.jump()
.现在,我将
sleep()
方法添加到接口实现中,并希望可以从我调用cat.jump()
的位置调用该方法。 That is what I want.这就是我想要的。 I see that throws an error and I do understand because the object is of type
Animal
and Animal
does not have the sleep()
method.我看到这会引发错误,我确实理解,因为该对象属于
Animal
类型,而Animal
没有sleep()
方法。
If I do not want to add a new method to the interface
, in that case, what other options do I have to be able to call a method that I created in interface implementation?如果我不想向
interface
添加新方法,在这种情况下,还有哪些其他选项可以调用我在接口实现中创建的方法?
The problem is that you didn't understand what it is to program for the interface.问题是你不明白为接口编程是什么。 I believe you are thinking that it is a rule that you have created and must follow.
我相信你在想这是你创造的规则,必须遵守。 It is not.
它不是。 It is something to understand why it exists and to do it when necessary.
了解它为什么存在并在必要时这样做是一件很重要的事情。
You must declare a variable as the interface if you only need what is in the interface.如果您只需要接口中的内容,则必须将变量声明为接口。 If you need what is in the concrete class then you must declare the concrete class.
如果您需要具体类中的内容,则必须声明具体类。
Casting or something else is adopting a mistake to fix the first mistake.铸造或其他东西正在采用错误来修复第一个错误。
Interfaces should be used to segregate responsibilities.应该使用接口来分离职责。 You program to interface so that what will receive the object can only access what is in that type.
您对接口进行编程,以便接收对象的内容只能访问该类型的内容。 It is purposeful that it does not allow other members of the concrete object to access.
它是有目的的,不允许具体对象的其他成员访问。 If you used the interface, that code does not know what is not in the interface.
如果你使用了接口,那代码不知道接口中没有什么。
Do you still want to call didSomething ()
and be through an interface?你还想通过一个接口调用
didSomething ()
吗? You have two possibilities:你有两种可能:
In fact, although it is useful to see how it works, programming for interface in something as simple as that is of no practical use.事实上,虽然了解它是如何工作的很有用,但是用这么简单的方式为接口编程并没有实际用处。 It is useful to use this technique when you have complex systems, which will need maintenance and flexibility to change the implementation without having to change the contract.
当您拥有复杂的系统时使用此技术很有用,这些系统需要维护和灵活性来更改实现而无需更改合同。
interface Something {
void doSomething();
}
interface Otherthing {
void doOtherthing();
}
class Whatever implements Something, Otherthing {
public void doSomething() {
System.out.println("Do something !");
}
public void doOtherthing() {
System.out.println("Do otherthing !");
}
}
class Test {
public static void main(String[] arguments) {
Something s = new Whatever();
s.doSomething();
Otherthing w = new Whatever();
w.doOtherthing();
}
}
If you want to call a method that's not in the interface, then you can't use the interface to make the call, you have to use the class.如果要调用一个不在接口中的方法,那么就不能使用接口进行调用,必须使用类。
Since the class is anonymous, you can't use the class.由于该类是匿名的,因此您不能使用该类。
Make a real named class, instead of using anonymous classes, eg create a class Cat
.创建一个真正的命名类,而不是使用匿名类,例如创建一个
class Cat
。
class Cat implements Animal {
// methods from anonymous class here
}
Cat cat = new Cat();
cat.jump();
cat.sleep(); // you can do this now
When you use the following syntax:当您使用以下语法时:
SuperClass anonymousInstance = new SuperClass() {
/*Code here*/
}
you are not creating an instance of the Superclass (in this case, Animal
).您不是在创建超类的实例(在本例中为
Animal
)。 Rather, you are creating an instance of some unspecified Subclass of the Superclass.相反,您正在创建超类的某个未指定子类的实例。 The only reason why you are able to store it in a reference variable of the Superclass is because of polymorphism .
您能够将它存储在超类的引用变量中的唯一原因是多态性。
You should only be using anonymous inner classes, as opposed to creating and instantiating an actual class, when you want to override a single method in the Superclass and only intend to use the new class once.当您想覆盖超类中的单个方法并且只打算使用新类一次时,您应该只使用匿名内部类,而不是创建和实例化实际类。 If you are creating a new method, as you did here with the
sleep
method, it is better practice to create an actual class.如果您正在创建一个新方法,就像您在此处使用
sleep
方法所做的那样,最好创建一个实际的类。
With that being said, if you must use an anonymous inner class and you are using Java 10 or later, you do have the option of using local variable type inference .话虽如此,如果您必须使用匿名内部类并且您使用的是 Java 10 或更高版本,则您可以选择使用局部变量类型推断。 This is accomplished via the
var
keyword.这是通过
var
关键字完成的。
var anonymousInstance = new SuperClass() {
/*Code here*/
}
In you use the var
keyword instead, the Java compiler will infer the anonymous type of the Subclass, which will include all of the methods in the Subclass.如果您使用
var
关键字,Java 编译器将推断子类的匿名类型,它将包括子类中的所有方法。 This does have its limitations - you'll lose access to new methods if you pass the object as a parameter - but it will work otherwise.这确实有其局限性 - 如果您将对象作为参数传递,您将无法访问新方法 - 但否则它会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.