How to access Java Interface in kotlin fun? - java

I want to access java interface in kotlin class.
How can i do that?
public interface InterfaceCallback {
void onComplete(Boolean isComplete);
}
public class Utils {
//constructor
public Utils() {}
public void getCallbackEvent(Context context, String videoLink, InterfaceCallback interfaceCallback) {
//...
interfaceCallback.onComplete(true);
}
}
I try to access this method in kotlin class as below but it's generate an error.
Utils().getCallbackEvent(this, videoLink) {it->
Log.e(TAG, "getCallbackEvent: $it")
}
java.lang.IllegalAccessError: Interface com.example.demo.InterfaceCallback implemented by class com.example.demo.activitys.DownloadScreen$$ExternalSyntheticLambda1 is inaccessible (declaration of 'com.example.demo.activitys.DownloadScreen$$ExternalSyntheticLambda1' appears in /data/data/com.example.demo/code_cache/.overlay/base.apk/classes9.dex)
Thanks!

You'll have to implement that interface somewhere.
For Kotlin:
class InterfaceCallbackImpl : InterfaceCallback {
override fun onComplete() {
// Implementation of the method
}
}
Then you should be able to use InterfaceCallbackImpl

Related

How to call methods of different classes passed as parameter type?

How would I do something like this? Ignore the syntax errors.
//some class
class A {
//some func
func(){
}
}
class B {
func2(){
}
}
//Generic Class that can take type A or B
class generic<T> {
func3(T){
//How to do this?
T.func();
T.func2();
}
}
I really don't understand Generics. Sorry if it sounds ridiculous.
You use generic to abstract the "shape" of class you can work on without caring about the actual implementation classes.
You should create a common interface
interface Common {
void doWork();
}
//some class
class A implements Common {
void doWork() {
func();
}
//some func
func(){
}
}
class B implements Common {
void doWork() {
func2();
}
func2(){
}
}
//Generic Class that can take type A or B
class generic<T extends Common> {
func3(T task){
task.doWork();
}
}
So pretty much you want to have a class that takes another Util class(or whatever it does) And calls some standard(generic) method on it. What i would do is Create an interface with the method;
public interface ExampleInterface {
void methodToCall();
}
Then you have your class that takes a implementation of that Interface;
public class OtherExampleClass<T extends ExampleInterface> {
public void call(T caller){
caller.methodToCall();
}
}
For the record, So far this really doesnt need to be genericized at all, I would really only do this if your Class 'A' and 'B' have some specific return type based on which one you provide when instantiated your 'Generic' class.

Cannot reference this before supertype constructer has been called + Consumer

I'm attempting to define a generic abstract class that handles the processing/retrying logic of the implementing class. I want all implementing classes to pass a "process" and "fail" function that is executed by the abstract class. The abstract class also holds retry attempt logic and some other generic boilerplate code that I would like to reuse.
Specifically, I have the following abstract class:
public abstract class EnvelopeDispatcher<T> {
protected Consumer<T> processFn;
protected Consumer<T> failFn;
private MetricsRegistry metricsRegistry;
public EnvelopeDispatcher(MetricsRegistry metricsRegistry, Consumer<T> processFn, Consumer<T> failFn) {
this.metricsRegistry = metricsRegistry;
this.processFn = processFn;
this.failFn = failFn;
}
protected void process(T envelope) {
//abstract processing logic calling processFn and failFn
}
}
And the following implementing class:
public class ActionEnvelopeDispatcher extends EnvelopeDispatcher<ActionEnvelope> implements Consumer<ActionEnvelope> {
public ActionEnvelopeDispatcher(MetricsRegistry metricsRegistry ) {
super(metricsRegistry, this::processEnvelope, this::failEnvelope)
}
#Override
public void accept(#NonNull ActionEnvelope envelopeToProcess) {
super.process(envelopeToProcess);
}
private void processEnvelope( ... ) {
//processing logic
}
private void failEnvelope( ... ) {
//failure case logic
}
}
When I attempt to call super while referencing this::processEnvelope and this::failEnvelope I get "Cannot reference this before supertype constructer has been called".
I understand why this is happening, but I'm not sure of the alternatives. Does anyone know how to get around this or a better implementation pattern?
What you could do is don't make the dispatcher abstract and create it using factory methods.
Something like this:
class EnvelopeDispatchers {
// factory method
public static EnvelopeDispatcher<ActionEnvelope> actionEnvelopeDispatcher(MetricsRegistry metricsRegistry) {
return new EnvelopeDispatcher(metricsRegistry,
EnvelopeDispatchers::processEnvelope,
EnvelopeDispatchers::failEnvelope);
}
private static void processEnvelope(ActionEnvelope env) {
//processing logic
}
private static void failEnvelope(ActionEnvelope env) {
//failure case logic
}
}

How to override java public class method in Kotlin?

I need to redefine/override method from java public class in Kotlin class:
// Java
public class BaseOne {
public static void m1() {}
}
// Kotlin
class BaseTwo : BaseOne() {
override fun m1() {}
}
but get an error: m1 overrides nothing.
If I remove override annotation I get Accidental override: The following declarations have the same JVM signature.
In java this works fine, but not in Kotlin :(
UPD: working java code
public class BaseTree extends BaseOne {
public static void m1() {}
}
UPD2 "Curiouser and curiouser!" (с)
I have next code:
// Java class
public class BaseOne {
public static void m1() {
System.out.println("BaseOne");
}
}
// Kotlin class
class BaseTwo : BaseOne() {
companion object {
fun m1() {
println("BaseTwo")
}
}
}
// Java class
public class BaseThree extends BaseOne {
public static void m1() {
System.out.println("BaseThree");
}
}
When I run this code from Java,
public class Main {
public static void main(String[] args) {
BaseOne.m1();
BaseThree.m1();
BaseTwo.m1();
}
}
I receive:
BaseOne
BaseThree
BaseOne
As you see - override/redefine/"hide" doesn't work
But if I run it from Kotlin's main
fun main(args: Array<String>) {
BaseOne.m1()
BaseThree.m1()
BaseTwo.m1()
}
all works as intended:
BaseOne
BaseThree
BaseTwo
My additional question is - How to write code with equal behaviour? Is there a docs about it?
You are override a static method and overriding depends on having an instance of a class.
public class BaseOne {
public void m1() {}
}

Overrite method from external or private class

I have some method that use method from external library (mvn). So I cannot adit it. When Im trying override that method im getting:
void is not public in *class; cannot be accessed error from outside
package
dont have access to that external library
The question in how to override method from external class (library) that extends abstract class or class with private methods.
logout = new Class(arg1, arg2) {
#Override
public boolean ovMethod(){
someMethod(true);
}
Method ovMethod() from (external class, downloaded by maven) Class:
Class extends AbstractClass {
public abstract class AbstractClass {
void someMethod(boolean arg) {
}
}
}
Generally speaking, you shouldn't override methods that are not meant to be overridden. But as a last resort, if the method is package-private (a.k.a. default visibility) you can create your own class in the same package so it has permission to override the method:
package same.package_as.superclass;
public class MyClass extends Class {
#Override
void someMethod(boolean arg) {
// custom implementation
}
}

C# equivalent to implement interface inside super keyword in Java [duplicate]

I am not sure how am I suppose to go about my question. It is about Android can Instantiate Interface. I am trying to do in C#. Now I am pretty sure that the rules for both Java and C# is you can't create an Instance of abstract and Interface as being said.
But I would really like to know how Android does this practice.
In Android you can do this.
public interface Checkme{
void Test();
void Test2();
}
public void myFunc(Checkme my){
//do something
}
// Now this is the actual usage.
public void Start(){
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
}
Actually once you press Enter on new Checkme() You will automatically get the Override methods of the Interface. Like auto Implement method of an Interface in C#.
I hope my question make sense.
C# doesn't support anonymously auto-implemented interfaces because it has delegates:
public void Foo(Func<string> func, Action action) {}
// call it somewhere:
instance.Foo(() => "hello world", () => Console.WriteLine("hello world"));
With delegates you can fill the gap and it can be even more powerful than implementing interfaces with anonymous classes.
Learn more about delegates.
This is an Anonymous Class:
public void Start(){
myFunc(new Checkme() {
#Override
public void Test() {
}
#Override
public void Test2() {
}
});
}
An anonymous class is an unnamed class implemented inline.
You could also have done it using a Local Class, but those are rarely seen in the wild.
public void Start(){
class LocalCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
myFunc(new LocalCheckme());
}
These both have the advantage that they can use method parameters and variables directly, as long as they are (effectively) final.
As a third option, you could do it with an Inner Class.
private class InnerCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
public void Start(){
myFunc(new InnerCheckme());
}
An inner class cannot access method variables (obviously because it's outside the method), but can be used by multiple methods.
Any local values from the method can however be passed into the constructor and stored as fields of the inner class, to get the same behavior. Just requires a bit more code.
If the inner class doesn't need access to fields of the outer class, it can be declared static, making it a Static Nested Class.
So, all 3 ways above a very similar. The first two are just Java shorthands for the third, i.e. syntactic sugar implemented by the compiler.
C# can do the third one, so just do it that way for C#.
Of course, if the interface only has one method, using a Java lambda or C# delegate is much easier than Anonymous / Local / Inner classes.
If I understand correcly, you're defining a class that implements an interface, and when you specify that the class implements an interface, you want it to automatically add the interface's methods and properties.
If you've declared this:
public interface ISomeInterface
{
void DoSomething();
}
And then you add a class:
public class MyClass : ISomeInterface // <-- right-click
{
}
Right-click on the interface and Visual Studio will give you an option to implement the interface, and it will add all the interface's members to the class.
you mean something like this?
pulic interface Foo{
void DoSomething();
}
public class Bar : Foo {
public void DoSomething () {
//logic here
}
}
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
You're passing into myFunc() something that is called an anonymous class. When it says "new Checkme() { .... }", it is defining an anonymous implementation of the Checkme interface. So, it's not an instance of the interface itself, just an instance of a type that implements it.
In C# anonymously implemented classes for Interface are not auto generated just like in java, you need to follow the below procedure to workout.
public class MyClass {
public void someMethod (string id, IMyInterface _iMyInterface) {
string someResponse = "RESPONSE FOR " + id;
_iMyInterface.InterfaceResponse (someResponse);
}
}
public interface IMyInterface {
void InterfaceResponse (object data);
void InterfaceResponse2 (object data, string x);
}
public class MyInterfaceImplementor : IMyInterface {
private readonly Action<object> actionname;
private readonly Action<object, string> actionInterfaceResponse2;
public MyInterfaceImplementor (Action<object> InterfaceResponse) {
this.actionname = InterfaceResponse;
}
public MyInterfaceImplementor(Action<object> interfaceResponseMethod, Action<object, string> interfaceResponseMethod1) {
this.actionname = interfaceResponseMethod ?? throw new ArgumentNullException(nameof(interfaceResponseMethod));
this.actionInterfaceResponse2 = interfaceResponseMethod1 ?? throw new ArgumentNullException(nameof(interfaceResponseMethod1));
}
public void InterfaceResponse (object data) {
this.actionname (data);
}
public void InterfaceResponse2(object data, string x) {
this.actionInterfaceResponse2(data, x);
}
}
Gist Source : https://gist.github.com/pishangujeniya/4398db8b9374b081b0670ce746f34cbc
Reference :

Categories