'Take a class as a parameter which has a particular method in it

I know that we can pass a class in a param which has a particular class as its super. For example, see this:

public void sampleMethod(Class<? super MyParentClass> class){
   // my random code 😒
}

and in kotlin:

fun sampleMethod(class:Class<? super MyParentClass>){
   // my random code 😒
}

But, can I have something like this?:

public void sampleMethod(Class <? hasMethod myMethod> class){
   // my random code 😒
}

or in Kotlin:

fun sampleMethod(class:Class<? hasMethod MyParentClass>){
   // my random code 😒
}

Basically I only want to accept a class in that param which has a method mentioned in it. Is it possible?

If yes, I want the code in java and Kotlin

If no, then any alternative will be ok

Edit


Most of the answers here are not what I want. So, I am explaining it a bit more here:

public class MyClass1{
   public static void main(String[] args){
      doRandomTask(new ClassWhichHasMethod()); // works fine
      doRandomTask(new ClassWhichDoesNotHaveMethod()); // gives error as it does not have that method
   }

   static class ClassWhichHasMethod{
      public void theMethodIWant(){} // the method I want to check
   }

   static class ClassWhichDoesNotHaveMethod{ // no method here}

   public static void doRandomTask(Class<? hasMethod theMethodIWant> class){
      // my random code 
   }

}


Solution 1:[1]

You need to use an interface to do that. When an object implements an interface, that guarantees that it has the methods, properties etc that the interface defines. You don't need to know what class the object is, just that it can be treated as the interface's type:

interface MethodHaver {
    fun myCoolMethod(something: String)
}

class Whatever : MethodHaver {
    // need to implement/override the method in the interface to satisfy the contract
    override fun myCoolMethod(something: String) {
        // do a thing
    }
}

class SomethingElse {
    // uses anything that implements MethodHaver
    fun doTheThing(myObject: MethodHaver) {
        // the object definitely has this method, because the MethodHaver type requires it
        myObject.myCoolMethod("wow")
    }
}

You can do it with anonymous objects too, doesn't have to be classes

SomethingElse().doTheThing(object : MethodHaver {
    override fun myCoolMethod(something: String) {
        // do something
    }
})

Or, in Kotlin, since the interface only has one method, you can make it a functional interface, and then you can pass a lambda instead that matches the single method's signature:

// note the 'fun' keyword before 'interface'
fun interface MethodHaver {
    fun myCoolMethod(something: String)
}

// pass a lambda that matches the method signature, i.e. takes a String and returns Unit (doesn't return anything)
SomethingElse().doTheThing { something -> // do something }

And finally, in Kotlin you can skip the interfaces and use function types instead

class SomethingElse {
    // accepts any function that takes a String and returns Unit
    fun doTheThing(f: (String) -> Unit) {
        // call the passed function like any other
        f("wow")
    }
}

// has the method you're interested in, but it isn't implementing an interface
class ClassWithMethod {
    fun someMethod(string: String) {
        println(string)
    }
}

fun main() {
    // call it passing a lambda
    SomethingElse().doTheThing { println(it) }

    // or pass a function reference, like a method on a specific object
    val myClass = ClassWithMethod()
    SomethingElse().doTheThing(myClass::someMethod)
}

With the function reference example there, instead of having to pass an object that has a particular method, you can just pass a reference to the method itself. So instead of having to involve interfaces (so the type system can confirm you're passing a valid object with the appropriate method), you can cut out the middleman and pass the method itself directly. So long as its signature matches (parameters and return type), it's valid

So yeah, lots of options depending on exactly what you need to do!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cactustictacs