# Interfaces

\*\*\*\* **NOTE: BLOG MOVED TO** [**https://cmrodriguez.me/**](https://cmrodriguez.me/) **\*\*\*\***

An interface is a reference type in Java. It is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface.

Along with abstract methods, an interface may also contain constants, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods.

An interface is different from a class in several ways:

* You cannot instantiate an interface.
* An interface does not contain any constructors.
* All of the methods in an interface are abstract.
* An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final.
* An interface is not extended by a class; it is implemented by a class.

To test this functionality I've created in the application an interface called MyInterface, and a class that implements the interface called MyInterfaceClass.

In order to get the interface representation in Frida we use the same code as we would use for a class:

```javascript
MyInterface = Java.use("com.blog.testfrida.interfaces.MyInterface");
```

We can't intercept or modify the abstract methods exposed by the interface. As an example I tried to implement the getMessage method from the interface in the following way:

```javascript
MyInterface.getMessage.implementation = function () {
    console.log("it gets into the getMessage");
    return String.$new("it works");
}
```

When we call the getMessage from the implementation of the getMessage method in the MyInterfaceClass, the console.log is not triggered. If we want to change the implementation, we have to do it in each class the abstract method is implemented. In this case we did it on the only class implementing MyInterface:

```javascript
var MyInterfaceClass = Java.use("com.blog.testfrida.interfaces.MyInterfaceClass");
MyInterfaceClass.getMessage.implementation = function () {
    console.log("it gets into the getMessage");
    return String.$new("it works");
}
```

Note that we can't instantiate an interface, it will throw the following error:

```
Error: no supported overloads 
  at makeConstructor (frida/node_modules/frida-java-bridge/lib/class-factory.js:478) ... 
  at /examples.js:434
```

When we get an instance of a class that implements an interface, we can call the interfaces' methods, but Frida will end up calling the classes implementations as in the following examples:

```javascript
//we get an instance of Interface and call the getMessage
var interfaceInstance = MyInterfaceClass.getNewInstance();

//internally it calls the getMessage from the MyInterfaceClass
console.log(interfaceInstance.getMessage());

//this does not call the default interface, it calls the class one (even when it is
//casted as a MyInterface interface)
console.log(interfaceInstance.getInt());
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://neo-geo2.gitbook.io/adventures-on-security/frida-scripting-guide/interfaces.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
